domenica, maggio 14, 2017

Set multiple parameters at once with Dynamo

It is common practice  using Dynamo to get and set objects parameters from Revit, I'd say this is one of the best features in Dynamo actually, something that empowers all the stakeholders in a workflow to communicate information and data seamlessly using the Revit model as an aggregator. What good is the BIM if we still have to populate the "I" manually, right?

It's also true that if you don't have Dynamo principles clear in mind, graphs tend to be messy, let's say not too elegant. There are even subtle mistakes that could actually prevent the graphs from executing correctly.

In the image above the example on the left is wrong, and as a matter of fact crashes Dynamo because there are two parallel branches in the graph that modify the same element on the same parameter. What should be the result in this case, value 1 or value 2? There is no good answer actually. On the right instead a sample of how it is supposed to happen from a graph flow point of view. It doesn't make much sense to change the same parameter but it's something that could potentially happen and it is better to avoid.

So in case of multiple parameters I very often see long chains of Set Parameter By Name nodes, one after the other, big space on the graph calling over and over the same function. It's working I know but the graph is not very concise.

Let's elements a collection of #n Revit elements, let's parameters a list of parameters names that these elements share, finally let's values a list of values with the following structure organized in a list of lists: each item of the main list is made of the values.

Now if you run this graph the result is not what one would expect.
Not all the elements are taken into consideration, the parameters are not set correctly because the replication calculations here are not helping. Changing lacing on the node won't affect the result in the way one would want in this case. There is need either for a new data structure that could cope with the difference in the rank on the input or for replication guides to force the execution of the Set Parameter Value By Name with a function.

Dynamo nodes

The Set By Parameter Name takes input of rank 0 (single values) but the elements and the parameters have rank 1 and the values rank 2. By default, the elements of the input that are occupying the same index position are combined together in the node function. In this example:

  • the first element
  • the first parameter name
  • the first LIST of values
The first element is combined with multiple values over and over for the same parameter and it ends with the last value of the list. Sounds familiar? it's the same thing happening in the green group of the first image, definitely not ideal and, more importantly, wrong.

It is possible to introduce a list with rank 2 for the parameters, List of  repeated items, the same amount as the elements, rearrange the values with a Transpose to have the same amount of sub lists (this won't change the rank but only how the data is structured). The following graph will now work as intended.

Replication guides

Remember that each node in Dynamo is a function that can be recalled in its literal form (e.g. try Node to Code).
In DesignScript it is possible to drive the replication calculations and force how the functions handle the input. The replication guides are defined with one or more "< n >" after the name of an argument in a Code Block. It's like writing a series of nested for loops in Python, the lowest numbers come first.

In this case it would be something similar to:

for p, v in parameters, values: # Level 1
    for e, vi in elements, v: # Level 2
        e.SetParameterByName(p, vi)

Which in replication guides terms translates as follows.
The final output from the two methods is different but they are only one Transpose away.
This is something I recommend to start to use in your graphs to keep them tidy and use DesignScript at its full capabilities.