[Hide Marker by Sheet]
One of the really cool things that Dynamo allows is the ability to search through all the elements in a project and manipulate them without even opening up a view manually. This is beneficial if you’ve every worked on a really large project with hundreds of views and not enough time to open up each one if you’re looking for a certain element. Module 8 takes advantage of this by searching sheets and views to hide a marker specified by the user.
I have created this module to solve a problem I often come across which is the hassle of not knowing where markers are appearing. Say for example you create a new section on an elevation, this elevation marker will obviously appear in other views if the section happens to appear there. If you didn’t want the section to appear in certain views, you’ll have to hunt them down and hide the marker. So, this script does just that for you. It allows the user to select a marker, or whatever you like really, find the views it appears on and specify which views to hide it on without even opening a view.
You might notice I’ve added in the functionality to select which sheets to search and views to search manually. The reason I’ve done this as it could take a huge amount of time to search sheets if you have too many. So, by specifying the sheets you could contain the search to a specific area of the project. However, if you do want to search all sheets, go for gold, the functionality is there. Let me know how you go anyway, if there are any problems, please don’t hesitate to email me. The script download file is at the bottom of the page.
The first part of the script will be focusing on finding the sheets and views we want to hide the marker on. To start this, a Boolean node is fed into a Python Script This will be used to find all sheets which is outlined in part 1.1 below.
We now have the list of sheets in the document which we can filter to search for the marker on the sheets we like. This can be done by sheet name or sheet number depending on your preference. So, to get this information, we use the SheetName to get sheet names and Sheet.SheetNumber to get sheet numbers. The result of this is then sorted using List.Sort as they can sometimes be out of sequential order depending on how the sheets were created.
To choose which sheets we want to filter, we can use the SelectItem.ByList node. If you can’t find this node, don’t worry, you may need to download the Juggernaught Package. To do this, simply open up the package manager from the Packages pull down menu and search for Juggernaught. What this node allows for is the ability to select the items we want to output, from the list input. Therefore, here we simply select the sheets we want to search for the marker. If you don’t have many sheets in your project, feel free to connect your list of numbers or names straight into the Python Script in part 4 to search all sheets.
After selecting all the sheets we want to search, we need to plug this into another Python Script node which will use the sheet name or number to get the views from the sheets. The details of this node are described below in part 4.1.
As we did in part 3, we can select which views we actually want to search for the marker we are to hide. This is done using a SelectItem.ByList node where we can check the views manually. If you want to search all the views coming out of the Python Script node in part 4, you can do so by feeding the python output directly into the Python Script in part 7. Again, I have only added this part in as you might be searching a huge project and this will help reduce unnecessary search time.
Before we hide the marker in views, we first need to actually choose which marker we want to hide. This is easily done using the Select Model Element node which we can use to select the marker directly in Revit.
With a list of views and a marker in hand, we can finally hide the selected marker in all the views in our list. This is done using a trusty Python Script node which is detailed in part 7.1.
As usual, I won’t be going through all the imports as this is explained in earlier modules and there aren’t any unique imports here. So, we start by assigning the only input (IN) to toggle variable which will be used to reset script if needed.
If toggle is true, a FilteredElementCollector is used to filter the document (doc) of the sheet category (OST_Sheets) and assigns the list to the collector variable which will be the ouput. If toggle is false, a simple string is output.
The input is assigned to sheets and empty list created (out) to start. A conditional is then set up to check if the list sheets does not equal (!=) None. In other words, if there are items in the list, continue.
A FilteredElementCollector is created in the same manner as part 1.2 to retrieve all sheets from project.
We need to assess each sheet for views so here we set up a for loop to iterate through each item in the collector list of sheets. For each item, we get the sheet number and name by using the get_Parameter method and built in parameter SHEET_NUMBER and SHEET_NAME respectively as the method parameter. The result is assigned as a string by calling AsString() method.
With the sheet number and name of all sheets we can cross reference this with the input list of sheets to select the ones we want. This is achieved by checking if the sheet number (sNum) as a string is in the input sheets If this is true, we can then use the GetAllPlacedViews method on the sheet(i) and assign the result to views.
For each view in the newly created views list, we need to get some details which will be output. First we retrieve the view as an element using GetElement method and view as parameter. This is done as GetAllPlacedViews gets the views element ID, not the element itself. With the element assigned to the variable v, we can append the sheet number (sNum), view name (Name) and element Id (view.ToString) all as a one line string and append it to the out list.
This part repeats what is happening in part 5 however, here we are checking if the input sheets list contains the sheet name. Part 5 and 6 basically check whether you have input the sheet names or the sheet numbers and gets the views appropriately.
If for some magical reason your sheet name in the sheets list isn’t in the document sheets, then nothing happens as we pass. The out list is output and if there is no input into the node, a simple “No input.” string is returned. I have done this as without it, an error will be returned if there is no input because the script will still try to check if the sNum or sNam is in an empty sheets list.
In this script you might notice we have loaded the “System” assembly here and from it, everything from the Collections.Generic namespace imported. This is so we can create an ICollection type which I will explain shortly.
We assign the list of views (IN) to the variable viewSt and selected marker to marker. This is unwrapped using UnwrapElement so we can use it with the Revit api.
Here we create a list (lst) and add the element Id of the marker to it. We can then use this list to create an ICollection type object which the Revit API will later require. This type can be created from the Collection.Generic namespace which is why we have imported it. We can use the List[Autodesk.Revit.DB.ElementId] method to create a new List object which inherits the ICollection type and contains Revit element Ids. We then cast the list we just made (lst) to this new collection type.
With our fancy new ICollection type list containing our selected marker, we can continue by cycling through each of the views we have input and checking if it contains the marker. To do this, we first check if the view list (viewSt) is not empty (None). If this conditional is true, we can start a for loop to check each view in the viewSt list.
As each item in viewSt contains a string containing sheet information,we need to extract only the part we need to use which will be the view element Id. As the element Id is the last digits of the string, we can isolate this part by using rsplit on the string and parameters ‘-‘ and 1. These parameters mean we will split the string at the – symbol and only once starting from the right side of the string.  is used to retrieve the second item in the return list which will be the elementId and we assign it to eInt as an int. We can then use this int to create an element id handle. With this, we can get the view element using GetElement and the element id (eleId) as the parameter, this is then assigned to the vEle variable.
Now that we have the view element, all we need to do is hide the marker element. To do so, we start a try statement so we can catch an error if it occurs. Within the try statement we start a transaction (EnsureInTransaction) in the Revit document (doc) and perform HideElements method on the view element (vEle) with the marker as the parameter (toHide). Once this is finished, we can commit the Revit transaction using TransactionTaskDone. If this is successful, we append a short string to the out list.
If there was an error within the try statement, we can catch it here with except. All that will happen is a short string will be appended to the out Once the loop is finished, the output will be out. If viewSt happens to be an empty list, the output will be “No input.”
The end result of this short but sweet script should be the selected marker hidden on all the views that you have selected. As I have stated earlier, you could shorten this script a fair bit by excluded the option to checkbox the items you want to filter however, be careful if you are using this to search large projects as searching the views can take a while to process… Therefore, this option of using the checkbox lists will shorten that load time a lot!
This could quite easily be adapted to suit other needs such as hiding a particular element in certain views quickly instead of manually. If you need a hand at all in trying this, please don’t hesitate to get in touch at Jeremy@learndynamo.com. Otherwise, have fun playing and learning from the script, you can download below for Dynamo 1.1. If you are interested in future modules, please subscribe below to get them first or follow me on twitter @LearnDynamo.