Change the elevation of a level without moving the associated MEP elements

It doesn’t happen all that often, but once in a while (for whatever reason) you need to change the elevation of a level. For a MEP engineer this can seriously mess up your model. All those tees and elbows moving along with your level can generate an enormous error list of elements that need to be deleted.

I ran into this problem a while back so I figured, what if I tried this:
– Move all the elements on the specific level to another level
– Change the elevation of the level
– Move all the elements back to their previous level

I created two new custom nodes in Dynamo for this.
The first is ‘All Elements at Level’. This node does the same as the out of the box node, but also returns system families like ducts, pipes, walls etc.
The second is ‘Elements change Level’. This node will change the levels of elements to the given level. This will only work for non-hosted (i.e. level-hosted) MEP families though.

Save the changed elements to a SelectionSet in Revit with SelectionSet.ByElements node (Clockwork).
Now you can change the elevation of the level in Revit. Once done, return to Dynamo and use the SelectionSet.Elements node (also by Clockwork) to get all the elements that were changed.
After that you can set the level of the elements back to their old value.

Voila! level moved and elements still in place.

NB both nodes can be found in the ‘MEPover’ package.


Space-Room coordination (part 2)

Picking up from our previous post: you’ve now got a nice model full of automatically created spaces and there’s just one thing left to do: set the height of the spaces. The problem we face now is the spaces that span multiple levels. For instance a lift shaft, a concert hall or a big gallery in a museum. The architect will have either placed a room per level and stacked these on top of each other or placed a single room and set the limit offset accordingly:

If the rooms have been stacked on top of each other then you would want the same to happen with the spaces in your own model. In all other cases you would want the spaces to extend up to the nearest floor/roof.
To achieve this you could first extend every space up to the nearest floor or roof. After that check the warnings dialog for any overlapping spaces and then adjust their limit offset to extend to the space above.

For the first part we can use Dynamo’s Raybounce node. The only downside to this node is that it can’t be used on linked files. That’s why we need a tweaked version of this node. Luckily Data-shapes has a custom node for this that also works on linked files. The Raybounce node expects a list of points (space locations), a direction (Z axis) and a 3D view. For the 3D view it is best to create a view especially for the purpose of using Raybounce. In this view only enable the categories that could limit the top of your space, which most likely are: Floors, Roofs and Ceilings. Here’s the graph:

  1. Get all spaces and their locations
  2. Get the 3D view used for the Raybounce
  3. Add 100 mm to the Z value of the space locations. If you don’t do this the Raybounce might bounce right off the first floor it encounters, which could be the floor below the space.
  4. The raybounce node takes in the space locations (+ 100 mm), the Z-axis vector to indicate we want to shoot the rays upward and the view to use. The Raybounce node will return the first point it encounters. If you subtract the Z-value of that space from the Z-Value of the space location you will get the value you can use for setting the Limit Offset.
  5. Finally set the Limit Offset of the space by using a SetParameter node.
  6. As an aside, the Raybounce node might return a null value for some spaces. This means it cannot find anything above the space. By searching for nulls and using a FilterByBoolMask you can find any offending space. That way you can check your model to see what’s wrong. In this case the space was actually situated on the roof, so the null was correct.

After running this graph you will end up with something like this:

As expected the spaces in the shaft have all extended up to the top of the shaft. Next, we look at the warnings dialog to find all overlapping spaces.

Export the warnings to an HTML file and then load that into Dynamo for parsing.

  1. The first big chunk of the graph is for processing the html file. The final output of these first nodes are the ID numbers of spaces.
  2. Using Archi-lab’s Select.ByElementId node we get the actual space elements.
  3. The python script is a simplified version of Clockwork’s Room.Boundaries node and will return all boundary curves of the spaces.
  4. Using Ampersand’s Polycurve.ByCurves the curves are turned into polycurves. For some spaces there might be more than 1 polycurve (e.g. columns in spaces), so we filter out only the longest polycurve.
  5. Like in the Raybounce graph we extract the space locations and set those locations 100 mm higher so as to not clash with their own floors.
  6. From the polycurves surfaces are created and then thickened resulting in a list of solids. The creation of the surfaces might fail at times because not all polycurves are closed for some reason. The list of solids is then joined to create a single solid.
  7. That single solid is used with the Solid.ProjectInputOnto node. This node basically does the same as the Raybounce node but uses Dynamo geometry. In this case all points (from the space locations) are projected upwards and if they encounter the solid it will return their clash points.
  8. Points that don’t clash with the solid are filtered out.
  9. Finally the spaces’ Limit Offset is set just like we did in the Raybounce graph.

If all goes well limit offsets of the spaces should be adjusted to extend to the spaces above. In practice you may find that there are still a few spaces overlapping each other.

You may ask: why not use the second graph for the entire model from the start, why bother with Raybounce?  The reason is that creating geometry in Dynamo takes a long time. For bigger models the graph will just lock up and crash. First using the faster Raybounce graph ensures most of the spaces to be set correctly without the need for creating Dynamo geometry in the second graph.

Dynamo files: Room space coordination workflow

Space-Room coordination (part 1)

It is a topic I’ve been struggling with for years: coordination between spaces in the MEP-model and rooms in the architectural model. Up until now it was a very time-consuming process: for each level you had to check whether the spaces still lined up with the rooms from the linked model. Fortunately we can now streamline this process thanks to Dynamo. The following workflow uses custom nodes from the packages: “SpringNodes”, “Archi-Lab”, “SteamNodes” and “MEPover”.
There are a few things to consider when managing your spaces

A: Make sure the levels between the host model and the linked model are aligned;
B: Make sure the levels share the same computation height;
C: Create and coordinate spaces and rooms;
D: Set the limit offset of the spaces.

A. Aligning levels
The first one is easy as this is usually done when setting up your model. I take it everyone knows how to use the copy/monitor function, so let’s skip this step.

B. Set computation heights
If you only have a few levels in your project it is no problem: just manually check the computation height of the linked levels and the host levels and set the same computation height. However, if there are a lot of levels, Dynamo can come in handy. Here’s a simple workflow for setting the level’s computation height:

  1. Find the levels from both the host model and the linked architectural model
  2. With a dictionary you can create a list of keys and a list of associated values. In the example above the keys are the elevation values of the levels from the host model and the values are the levels themselves (also from the host model). After that the ‘search keys’ will look up the values associated with those keys.
    The level elevation values from the linked model are used to return the levels from the host model. By using this workflow you will be able to match levels from the linked model to levels in the host model. If however there are levels which can’t find a matching height, then a null value will be returned.
  3. Retrieve the computation height values from the levels in the linked model and use those to set the computation height of the levels in the host model. In this case the SetParameter node gives a warning, because there is a level in the linked model that can’t find a matching level in the host model (like stated in step 2). This doesn’t have to be a problem, just make sure there aren’t any rooms hosted to that level.
    If there are rooms hosted to that level then the next steps will fail as the spaces we are going to generate always need to be associated to a level.

C. Space creation and coordination
This is the hardest part. There is no single right way to manage the coordination between your spaces and the rooms from the linked model. If you are not in the same office as the architect it’s almost impossible to keep track of the changes in the linked model. It would mean checking every space that no longer has a matching room number and looking for that room’s new location or it could also have been deleted altogether.
I therefore put some thought into creating a workflow that would work for any situation, regardless of the changes to the rooms. The only prerequisite for this to work well is that every room has a unique room number (sadly I still run into a lot of architectural models with duplicate room numbers, even though Revit gives explicit warnings stating that this is actually a bad idea…).
let’s assume that every space has the same number as the room it is associated with. Now whenever you load a new architetural model, the spaces will retain their space numbers (basically the state of the old architectural model). All you need to do is find the difference between the new rooms and the existing spaces. There’s basically three options to choose from:
1: A room number has been deleted
2: A room number still exists in the model (and might have moved)
3: A room number is new

To gather the information above we can use a really useful data structure known as a ‘Set’.
Sets are a collection of unique items upon which you can perform some functions you can’t do as efficiently with lists. Luckily Dynamo has included a few nodes for working with sets. There are 2 important methods that can be used with sets: ‘SetDifference’ and ‘SetIntersection’. Explaining these is best done through an example:

As you can see, this way it’s possible to find out exactly what we are looking for. Now let’s have a look at the next challenge: associating room/space numbers with actual rooms and spaces. We can achieve this by using a dictionary in which the keys are the space/room numbers and the values are the actual spaces/rooms. The output of the dictionaries will be the data to use for creating, managing or deleting the current spaces. Here is the result (with explanation):

  1. First gather the rooms, spaces and their respective numbers.
  2. Use the SetDifference node (room numbers in input 1, space numbers in input 2) in order to have the new room numbers from the linked model returned. Those room numbers are used as input for the dictionary which will return the room elements. Secondly, get those rooms’ locations and use them for the creation of new spaces.
  3. Use the SetDifference node but reverse the input order (space numbers in input 1 and room numbers in input 2). This way the space numbers for which there is no longer a room number available in the linked model are returned. With the dictionary the space elements are returned. All that’s left is to simply delete these spaces.
  4. Find out which rooms and spaces with the same numbers are still in both the models, using the SetIntersection node. With the dictionary we retrieve the space elements. Because this doesn’t tell us whether the rooms and spaces are still in the same location, we need to check their locations and then move the spaces if necessary. Sadly Dynamo doesn’t allow moving spaces to different levels with any of the normal nodes. For this reason I created the node: “Space coordination move to associated room”. This node will find the room in the linked document with the same room number as the space. It will check its location and if that location isn’t the same as the space it will attempt to move the spaces to rooms with the same numbers.

After this make sure that the new space numbers change to match the associated room numbers. After that you can repeat this entire workflow for every new linked model update you receive.
The custom node can be found in the MEPover package. In addition, I have added three other nodes that partly or completely cover the work from the above workflow. The only difference is that it’s packed into an easy to use python node.

Seeing as this post is getting a bit long, I’ll leave it at that for now. The last part: “D” will be discussed in part two of this post. I will then touch on the subject of setting the spaces’ limit offset to the correct height.

Room calculation points for everybody

Revit allows you to enable a room calculation point for families of certain categories (e.g. light fixtures and air terminals), but not for all categories. For instance Duct Accessories don’t have this option, but it’s exactly these kinds of families that will end up above a Space with no assocation to that Space.

Thankfully we have Dynamo with which we can basically add a virtual Room Calculation Point to any Category we want. In combination with the Element.Space node from the Rhythm package (for getting elements that actually are in a space) we can assign way more duct accessories to spaces than before.

Here’s how it works:

  1. Collect all Duct Accessories and get their Space and their location
  2. Create a point below the Duct Accessories and check that location for Spaces with the SpaceAtPoint node from the MEPover package.
  3. Replace the nulls from the first list with values from the second list.
  4. You can create points in any direction you want. In this case another point is created above the Duct Accessories as well to check for spaces above it.

And with that we can associate way more Spaces to Duct Accessories than we could before.



Linssen BIM-blog

Met trots presenteren wij onze eerste blog pagina: het Linssen BIM-blog. Op deze pagina zullen we regelmatig berichten over alles omtrent BIM gezien vanuit het oogpunt van de installatie-adviseur. In eerste instantie zal dit blog voornamelijk gevuld worden met berichten over Dynamo scripts en workflows.

Tot de eerste blogpost verschijnt graag de aandacht voor onze andere nieuwe BIM-pagina: Visualisaties. Op deze pagina worden video’s geplaatst die wij maken van onze projecten.

Left Menu Icon