October 15, 2018

Dynamo: Export Views and Sheets from Revit - Part 4

First post in this Series [Part 1]
Previous post in this series [Part 3]

This post describes the nodes that generate the file names for the exported drawing files. As you may recall from the previous posts in this series, a list of Views and Sheets was generated from a user-created ViewSheetSet in Revit® by a Python Script node. That list was then separated into two lists, one for Views and one for Sheets, to allow for separate naming conventions for the exported drawing files for each. (Specifically, so that the sheet number can be included in the file name for Sheets.) The nodes that do this are contained in three groups: Generate Names for Exported Views, Generate Names for Exported Sheets and Combine Names....
All three groups make use of out-of-the-box nodes. The first two groups are nearly identical, and can be described simultaneously. The first node in each of those groups is a Code Block node, renamed to Exported DWG File Name Format for Views for the exported Views and Exported DWG File Name Format for Sheets for the exported Sheets. Each of these nodes has one input, view which takes the respective list from the List.FilterByBoolMask node covered in Part 3. A combination of parameter values associated with each View/Sheet and text is used to create the file name for each View/Sheet:
  • For Views: dwgname = view.Name + "_Export" + ".dwg";
  • For Sheets: dwgname = view.SheetNumber + "_" + view.Name + "_Export" + ".dwg";
The drawing name for Views concatenates the view.Name parameter value with "_Export" and the ".dwg" file extension. The drawing name for Sheets is similar, but adds the view.SheetNumber parameter values at the beginning, separating the sheet number from the sheet name with an underscore ("_") character. This is what I set up as a default for use in my office; you can customize this to meet your needs by adding, removing or rearranging the parts.

The lists of Sheet and View names are then run through two String.Replace nodes. The first replaces any asterisks ("*") with underscores ("_") and the second replaces any forward slashes ("/") with hyphens ("-"), as neither of these characters are permitted in a drawing file name, even though they are allowed in a View or Sheet name in Revit. Each resulting list of file names is then passed through a Watch node, so that the contents can be inspected after the graph is run. These two lists are then sent to the Combine Name... group, where a List.Create node and a Flatten node combine them into a single list. An optional Watch node is included here, as well.

So now we have a combined list of View and Sheet objects (from Part 3) and a combined list of file names for the corresponding exported files. The next post will look at the remaining user input nodes.

September 25, 2018

Revit: 2018.3, Windows 10 and No Material Browser

I discovered today that I was not able to open the Revit® Material Browser (on the Manage ribbon tab, on the Settings panel, selecting the Materials tool). As luck would have it, I am quite a bit behind in reading the Autodesk Revit Architecture Forum, and I just happened to have read a thread about this issue earlier today. In the Materials Dialog Box Doesn't work thread, a post by richard.horner, building off the previous post by stewart.jex, provided the solution that worked for me. I know I will not be able to find that thread when I need it in the future, and since the solution is not at all intuitive (I still cannot figure out why it works), I decided to document it here.

  1. In the Revit session in which you discover that the Material Browser will not open, go to the Application Menu (File "tab"), and choose Options.
  2. In the Options dialog, choose Hardware on the left side.
  3. On the right side, in the Hardware setup area, clear the checkmark from the Use hardware acceleration (Direct3D®) toggle.
  4. Select OK to ratify the change and close the Options dialog, and then close Revit. (Changes to hardware acceleration do not take effect immediately.)
  5. Restart Revit, and open a project file.
  6. On the Manage ribbon tab, on the Settings panel, select the Materials tool. The dialog opens! (Great, but who wants to run Revit without hardware acceleration, right? The next part is the bit that I cannot figure out.)
  7. Close the Material Browser.
  8. Open the Options dialog again, select Hardware and select the Use hardware acceleration (Direct3D®) toggle to re-enable it. There should be a checkmark in the toggle.
  9. Select OK to ratify the change and close the Options dialog, and then close Revit.
  10. Restart Revit, open a project file and then try to open the Material Browser again. It works!

While the analytical part of my brain wants to know why the exact same settings that previously failed now work, the "hey, you found a solution, now lets get on with what you were trying to do originally" part of my brain is declaring victory and moving on. And I will be carefully looking both ways crossing streets on my way home this evening, as I have clearly used my luck for the day.

September 12, 2018

Dynamo: Sorting a List of Lists by a Value in the Sub-List in Python

I had a list that was composed of sub-lists, each sublist contained a Sheet Object and the values of three parameters associated with that Sheet, including the Sheet Number. I wanted to be able to sort the sub-lists in ascending order of the Sheet Number value in each sublist. I found the following Python code does the job:
sortedLists = sorted(listOfLists, key=lambda x: x[index])
where index is the index of the item in the sub-list on which you want to do the sorting.

For example, given a list with four sublists, similar to that in the image below,
where the index of the Sheet Number in each list is 1, the code below
will sort the sub-lists by the item in index 1 of each sub-list, with a result of

This page on the stackoverflow website helped me work this out. Two additional notes:
  • If you want to replace the original list with the sorted list, you can use this syntax:

    listOfLists.sort(key=lambda x: x[index]).

  • If you want to sort in descending order, add reverse=true as a parameter:

    sortedLists = sorted(listOfLists, key=lambda x: x[index], reverse = true)

    or

    listOfLists.sort(key=lambda x: x[index], reverse = true).

September 01, 2018

Dynamo: Export Views and Sheets from Revit - Part 3

First post in this series [Part 1]
Previous post in this series [Part 2]

This post describes the nodes used to separate the Views from the Sheets that were obtained from the ViewSheetSet that the user specified as the source of Views and/or Sheets to be exported. This Dyanmo graph generates file names for the exported Views/Sheets. In order to be able to use the Sheet Number in the file name of exported Sheets, Views and Sheets need to be processed separately when generating the file names as Views do not have a Sheet Number parameter, so that cannot be part of the name generation code for Views. Separating the Views from the Sheets in two separate lists and processing each list separately when generating the file name seemed like the easiest way to handle that.

As noted in Part 2, the Python Script 1 node generates a list of View and Sheet objects, based on those included in the ViewSheetSet specified by the user. In order to separate that list into two separate lists, the List.FilterByBoolMask node is used. That requires a Boolean Mask, which is a list of true and false values. Items in the original list whose index corresponds to a true in the Mask list end up in the "in" output list. Those that correspond to false become part of the "out" list. The nodes in the lower left corner of the image above generate the Boolean Mask:
  • The list of Views/Sheets in the Set are fed into the "element" input of a Element.GetParameterValueByName node.
  • A String node provides the input to the "parameterName" input, with a value of "Category".
  • This creates a list of category objects, representing the category of the items in the View/Sheet list.
  • That list of categories is converted to a list of strings, representing the name of each category by the Element.Name node.
  • This list of strings is then passed to the Equal x to y? operator node (==), as the "x" input.
  • The "y" input is provided by a String node, with the value "Views".
  • The output will be a list of true/false values, based on whether the category name is "Views". Any Views on the original list will have a true value, and any Sheets will have a false value on that list.
Feeding the original list of Views/Sheets into the "list" input of the List.FilterByBoolMask node and the Bool Mask we just created above into the "mask" node will send the Views to the "in" output and the Sheets to the "out" output. These are sent to the respective file name generation nodes, to be covered in the next post in this series.

But before closing, there are two additional nodes in the blue node group in the image above. Eventually, we need to export the Views and/or Sheets, so we need to recombine the separated lists. I chose to put the Views first and the Sheets second, and used a List.Create node to combine the two. The List Create node will generate a list with two sublists, one of the Views and one of the Sheets. I just want a single combined list, which the Flatten node creates.

Note also that it is perfectly acceptable for the ViewSheetSet to have only Views or only Sheets. The nodes above will still generate two separate lists; one will just be empty.

Next post in this series [Part 4]

August 13, 2018

Revit: Design Options in Linked Revit Files Not Respected as Room Boundaries

I was trying to assist on a project in the office today (using Revit® 2018.3), when I ran into this issue, documented by Dave Baldacchino nearly six years ago. I set up a simplified set of files for experimental purposes; the images below demonstrate the problem remains an issue at least through 2018.3.

I created a "link" model, that has one Design Option Set (Exterior Walls) which in turn has two Design Options, Option 1 (primary) and Option 2. Each Design Option has one Wall object, running in the Project North-South direction (up and down on the screen). These are identical, with the exception that the Wall in Option 2 is offset 10 feet in the direction of Project West (left on the screen).

The link model is linked into a "host" model (origin to origin; both files were started with the same template file). In a floor plan view, four additional Walls were drawn, and two Rooms with Room Tags added. In the image below, the link model is showing Option 1 (primary). The link model is selected, and its type properties displayed to show that the link model is set to be room bounding. Interior Fill is turned on for the Rooms, to illustrate their extents.

No surprises there. But change the Visibility Graphics Overrides for the linked model to display Option 2, and the Wall moves 10'-0" to the left, as expected, but the Rooms stubbornly maintain their extents at the face of the Option 1 (primary) Wall location.

The workaround, to make the linked file not be room bounding, and to draw Room Separation lines in the host file, is not going to make anyone on that project team very happy.

August 10, 2018

Dynamo: Export Views and Sheets from Revit - Part 2

First post in this series [Part 1]

This post will cover the part of the graph that gets the list of Views and/or Sheets from a user-selected ViewSheetSet that are to be exported.
As noted in Part 1, the user has to create a View/Sheet Set in Revit® and add all of Views and/or Sheets to be exported to that set. The user enters the name of that set into a string node, labeled ViewSheetSet Name - String in the green-colored group labeled 2. Enter Name of Set to Export. Just above that, the Element Types node is set to the ViewSheetSet type, which is then fed to the All Elements of Type node to get a list of all of the ViewSheetSet objects in the active project. This list of ViewSheetSet objects is passed to the Element.Name node, which generates a list of the names (as strings) of those ViewSheetSets. This list is passed to the IndexOf node, along with the name that the user entered, to determine the index of that name on the list. Finally, the list of ViewSheetSets and the index of the desired ViewSheetSet are passed to the List.GetItemAtIndex node, to get that ViewSheetSet object.

During my initial testing, I passed the ViewSheetSet object to an Element.Parameters node, to see what information could be obtained from the object. The list of Views/Sheets included in that ViewSheetSet was not found there, so this node need not be included in the final graph. It turns out that there is not a node that ships with Dynamo that will generate a list of Views/Sheets that are included in a ViewSheet Set, and I was not able to find one in any of the third-party packages I have installed. I was able to find this thread in the DynamoBim.com Forum, in which Kulkul posted the Python code needed to extract a list of the Sheets/Views. My adaption of that, shown in the image below, is the code behind the Python Script 1 node, which takes the desired ViewSheetSet object as input and generates a list of the included Views and Sheets as output.

That list of Views and Sheets is then sent to several locations. During development, I added an Element.Name node and two Watch nodes to view the list. These do not need to be part of the final graph, but I left them in as a way to visually check that the correct ViewSheetSet was obtained.

In the next installment, I will cover the nodes that separate the list of Views/Sheets into separate lists of Views and Sheets. I wanted to do this so that I could include the Sheet Number value as part of the name of exported Sheets. Since Views do not have a Sheet Number property, they needed have the name of the exported drawing generated separately.

Next post in this series [Part 3]

July 27, 2018

Revit: Sheet Ribbon Tool Inactive

This issue came up today, and I wanted to document the solution for future reference. A user was working on a model, in Revit 2018, and was trying to create a new Sheet. On the View ribbon tab, on the Sheet Composition panel, the Sheet tool was inactive.

She was working on a project that had Design Options, and one of the Design Options was set active. The solution was to use the Active Design Option selector on the Status Bar and set it to Main Model. You can only create new Sheets in the Main Model.

July 18, 2018

Revit: Multi-Line Viewport Titles on Sheets

I was asked about this today, and decided to record the solution in a blog post, for future reference. Viewport Titles in Revit® will wrap onto a second line when the length exceeds what will fit, based on the length of the label in the Title Family, but often the user wants control over where the wrapping occurs. If your office protocols allow for using the Title on Sheet property of a Viewport for the title that is shown on the Sheet (rather than using the View Name), then you can set a line break at the cursor location in the Title on Sheet property edit box in the Project Browser by pressing CTRL+ENTER.
And, no, there is no significance to the contents of the Drafting View that I used as my test case, shown in the image above. They are just some semi-random Detail Lines drawn so that there would be something to see when the Drafting View was placed on a Sheet.

July 10, 2018

Dynamo: Export Views and Sheets from Revit - Part 1

I had a request the other day to streamline the process of updating CAD Exports for an Autodesk Revit® project. Unfortunately, some team members are not working in Revit, so certain Views have to be exported to CAD on a regular basis for use as backgrounds for the non-Revit-using team members. After a bit of trial (and a little tribulation) along with an enormous amount of help from the generous souls who have posted sample code to the Community Forums at dynamobim.org, I came up with the following Dynamo graph. All of the nodes used are "out-of-the-box" nodes available in the 1.3.2 version of Dynamo, but there are two Python Script nodes, the code for which is based on example code posted in the Community Forums. (As always, click on a image to see a full-size version of the image.)

The end user has to do three things prior to using the graph:
  • Create a View/Sheet Set into which all of the Views and/or Sheets to be exported are placed.
  • Get the name of the DWG Export Setup to be used for the export. (Create a new one if required by the project.)
  • Identify the folder (with full path) where the exports are to be sent.
With that information in hand, the user can make a project-specific copy of the Dynamo file, enter those three items in the appropriate nodes, save the file, and then run it whenever updated exports are needed. Dynamo will overwrite any files of the same name in the target folder, so previous versions need to be archived elsewhere if a record of all exports is required. In the next few posts, I will go through the various sections of the graph, and, to the best of my ability, explain how each works, including the two Python Script nodes that do the heavy lifting. Before doing so, I would like to thank the following Community Forum contributors whose helpful responses to others' questions also helped me to complete this project.
  • Konrad K Sobon, for the code in the Python Script 2 node that does the exporting, as well as for the advice given to Andrea_Ghensi in the same thread regarding code to have a specific DWG Export Setup used for the export. See the full thread here.
  • Andrea_Ghensi, for the code in the Python Script 2 node that allows the user to specify an existing DWG Export Setup for the export (as amended by Konran K Sobon). See the same thread as the previous link.
  • 4bimfercesp, for the line in the code in the Python Script 2 node that allows the user to specify whether Views on a Sheet should be merged into the exported sheet or exported as a separate file that is externally referenced into the exported Sheet file. See the full thread here.
  • Kukul, for the code in the Python Script 1 node that extracts a list of the Views/Sheets in a View/Sheet Set. See the full thread here.
The nodes at the left side of the graph that are in green-colored groups are the nodes that require user input. I will conclude this first post with one of the simpler parts of the graph, the Folder for Exported DWGs - Directory Path node.
This is an instance of the out-of-the-box Directory Path node, with a modified node title. The Browse button allows the user to navigate to the folder where the exported drawings are to be placed. The output of this node is fed to the IN[0] input of the Python Script 2 node. One thing to note about this node, and the other user input nodes, is that if you right click on the node, you will see that the Is Input item on the context menu is checked. That means that this node will be available for user input in Dyanmo Player.

I am not certain how many clicks using this graph will save over manually doing the same export (probably a few on subsequent exports if Dynamo Player is used, without making any changes to the inputs), but it certainly will help make the process more consistent.

Next post in this series [Part 2]

May 21, 2018

Autodesk Product Update Site Maintenance

If you were planning to do some software updates this coming weekend (Memorial Day weekend in the United States), get your download early, as the product update section of the Autodesk Account site will be down from 8:00 pm on Friday, May 25, 2018 through 2:59 am on Monday, May 28, 2018. (Those times are US Eastern Daylight Savings time, to the best of my knowledge.) Check out the banner notification at the top of the Autodesk Account Management page for the times in your zone.