April 11, 2019

Dynamo: Python Node to Test For Presence of a Parameter on an Object

We have a Dynamo graph that allows the user to search for a user-specified string in the names of Views and, if found, replace it with a second user-specified string. This comes in handy when someone decides that all of the instances of "LEVEL" in the view names should be changed to "FLOOR". The graph worked, but would result in an error condition, because there are, apparently, Views that do not have a "View Name" parameter attached to them. Attempting to retrieve the View Name parameter value from all elements of the Views category using an Element.GetParameterValueByName node resulted in this error:

While this did not appear to interrupt the processing of all Views, I would prefer to not have an error reporting (in both Dynamo and Dynamo Player), so that I do not have to explain to others who might use the graph that having that error is "Ok". I thought it would be simple to construct a BoolMask to filter out the Views without a View Name parameter, and proceeded to try to do so. Perhaps there is an easy way to create that BoolMask with core nodes or with something from a package, but my initial attempts were unsuccessful. The best I could do was get a list with true for the Views with the parameter but null for the Views without it, while throwing additional errors; that result also did not work as a mask in the List.FilterByBoolMask node. I quickly ran out of patience and decided to generate the mask list using a Python node, which turned out to be fairly easy.

Each Element in the Revit Model has a ParametersMap attribute, which is a map that contains all of the parameters the Element contains, accessible via the parameter Name, using the Contains(key) method for the ParameterMap object, where the key is the name of the parameter of interest. The potential for an error condition for Views without a View Name parameter can be handled by using try: and except: statements to build the mask list, as shown in the image below.

The Python node has two inputs, the first, IN[0], a list of Elements to be tested for the presence of a particular parameter, and the second, IN[1], a string representing the name of the parameter. The Contains method will return True if the Element's ParametersMap contains a parameter whose name matches the string passed to the Python node in IN[1]. If there is not a matching parameter name, it should return False; in testing, some of the Views were throwing an error, in which case the except: statement adds False to the output list.

The output from this Python node worked to remove the Views without a View Name parameter from the list of all elements of the Views category, allowing the rest of the graph to do the renaming of the Views without any error messages.

No comments: