I have the pleasure today of hosting a guest blog post, from a longtime Twitter friend that I was fortunate enough to meet up with in person this year, Tom Kunsman! As if working in this industry isn't cool enough, we also bond over our love of Legos and Space Science!
Before we get to Tom's article on saving time with Dynamo, here are some links to past articles from guest authors:
Saving time: Optimizing a Dull Structural Task with Dynamo
Dynamo is often used to not just create parametric
geometry, but to optimize workflows and maximize project efficiency.
Recently, I was working on a
structural project and was slogging through one of those very repetitive tasks.
This was, of course, the manual editing of a dimension on a beam system, in
order to place the label below them which specifies the number of structural members
and spacing required between them.
As I trudged through this task,
I realized that Dynamo could be leveraged to perform this task, in less time
than it would take to do manually. The data for all the members and spacing was
available in the system family parameters already, so all we had to do was find
a way to tap into it and put it where we want it.
1. Beam Framing Systems
and Their Parameters
First, let’s look at a framing
bay, to understand what information we are trying to gather (notice the values below
the dimension segments).
Initially, when I began working
through this problem, I was going to have users select the beam system, then
the dimension, but relating the two pieces of data proved difficult.
One of the more frustrating
aspects of Revit is the inability to access all of the parameters with in a
project, when you want to use them in tags or with other parameters. Take a
look at the parameters of the beam system. Note that “Centerline Spacing” is
grayed out, which means that the user cannot modify this value.
Thankfully, with Dynamo, we can access this information, along with
the “Number of Lines” value, to apply to the dimension spacing.
NOTE: This access has
the added benefit of eliminating the opportunity for user error.
1. Building a
Solution in Dynamo
Instead of continuing to attempt
to find native Revit options, I decided to turn to the amazing Dynamo community
of users. And, since I was using custom nodes from a package called Rhythm, I
sought assistance directly from the package author, John Pierson.
After brainstorming for a bit,
we came up with this simple graph:
We’ll take a look at each group
of nodes, by function, to understand the logic.
A. Gathering User
Inputs
The first step in our process is
to select the multi-segment dimension that we wish to have the beam system
values written to. This can be done with a simple Select Model Element node and a Number
Slider node. Keep reading, if you aren’t sure why I included the number
slider.
TIP: Renaming a node
can be done simply by double-clicking on the title of the node and typing in a
new label. Renaming nodes can help new Dynamo users more quickly understand
which nodes require user input or selection.
I have renamed the “Select Model
Element” node to read “Select Dimension”, and “Number Slider” has been changed
to “Buffer for Dimension”.
A. Collect and
Compare Beam Systems
Next, we need to grab the
structural beam systems, along with their bounding boxes. This is accomplished
through the use of the following nodes: Categories,
All Elements of Category and Element.BoundingBox.
A. Projecting the
Point and Generating the Bounding Box
Obtaining the underlying
geometry of a multi-segment dimension is difficult. The end result actually
places a point at the mid-point of each segment, and then copyies and offsets
that point until it intersects the beam system.
With this method, Dynamo can
understand which segment of a dimension corresponds to which beam system.
Basically, we are playing laser tag with the dimension and the beam systems,
which actually mimics what a user would do manually.
- Find the related dimension string
- Scan over and locate the beam system to pull data from
- Push the data to the dimension string
By using the Dimension.GetCurve node, we can place a
point at the mid-point and then generate a curve along the normal vector from
that point. This is where the “buffer for dimension” Number Slider gets input to the Geometry.Translate
node.
This translate node places
another dynamo point at a distance away from the midpoint of each of the
selected multi-segment dimensions, which is how we are able to grab the related
beam system. Since the dimension will not intersect the system, we simply
project a point of our own towards it.
The last node in this group is
the BoundingBox.ByGeometry. This
generates the bounding box of the point that was offset from the mid-point of
the dimension line. We will then look to see if the bounding box of this point
intersects with the bounding box of the beam system.
A. Select Objects
to Check
The next step is performed by
this group of nodes, which does an intersection check between the bounding
boxes.
In the BoundingBox.Intersects node we input the Structural Beam System
collection to the boundingBox input
and for the other input we use the
data from dimension point and translation group that was mentioned above.
Flowing from the BoundingBox.Intersects node we use the IndexOf node.
We also use a Code Block node with
a true statement. So, we are ONLY
selecting beam systems that do intersect with the offset midpoint of the
selected dimension.
The remaining nodes: List.AllIndicesOf, List.RemoveItemAtIndex and the second Code Block, with the value of negative one, will remove any Beam
System that may have been misplaced or does not have a corresponding dimension.
A. Get the Index
of the Beam System
Next, we need to get the Beam
System index, and for that we can use the List.GetItemAtIdex
node.
For the list port we feed a wire from the All Elements of Category from when we had selected all of the beam
systems.
With the index port we wire in the
list output from the List.RemoveItemAtIndex
node. Again, this just helps to eliminate
any misplaced beam systems in the current view.
A. Obtain the Dimension
Value of the Beam System
We need to get the dimension
value of the beam system, which is where this group of nodes comes in.
The first step in getting the
dimension value of the beam system is to use the Element.Parameters to get the parameters.
Next, we need to get the String
value from that object with the String
from Object node. This enables us to search for and isolate just the
centerline spacing.
After converting to a string, we
can then search for the centerline spacing by using String.Contains and a Code
Block with “Centerline Spacing”.
NOTE: Dynamo and Revit require
exact spelling and case sensitivity.
This can be done with the List.FilterByBoolMask node. The String.Split node groups the Centerline
Spacing with the associated value associated with the spacing. This is helpful
because we get the user-understandable value of the dimension and not the
decimal value.
A. Assemble the
String
Now it’s time to build the
string (text value) that will be written below the dimension value.
In the first part of this group
we have the Rhythm node BeamSystem.Members,
which obtains the framing members from the beam system. For the Beamsystem input port, we connect a wire
from the List.GetItemAtIndex node while we were .
This gets connected to the Count node, allowing us to obtain the
number of beams from the framing system.
From the group where we obtained
the dimensional value of the beam spacing (the centerline spacing), we connect
the String.Split to the List.LastItem, since we only need the
spacing value from that list.
You can use a simple + (addition) node and a Code Block to add one to the number of
lines. This is what builds our custom below value for dimensions (the part which
used to be manual).
In our final step, we need to
use the Dimension.SetBelowValue node
from the Rhythm package. For the dimension
port, we feed in the Dimension line that we picked all the way back in the
beginning of this logic, with the Select
Dimension node.
Finally, for the belowValue port, we feed in the wire
from the Code Block where we had added the count of the number of beams and the spacing.
A.
Placing the Annotation
After the user runs this script,
Revit places a Dynamo point at the midpoint of each segment of the
multi-segment dimension line as well as a Dynamo point offset from that point.
NOTE: This
offset point needs to be within the beam system you are trying to reference.
NOTE: Remember our
“buffer dimension”? This buffer dimension may need to be modified depending on
how far the user has placed the dimension line from the beam system.
1. Summarizing our
Dynamo Solution
So, the next time you need to
specify the number of members in a framing system, and the spacing between
them, keep in mind that you can automate the process with the following Dynamo
workflow:
A.
Have the user
make selections and input the required tolerance
B.
Collect and
compare your beam systems
C.
Project points
and generate corresponding bounding boxes
D.
Select objects
to check
E.
Obtain the
index of the beam system
F.
Assemble the
data string
G.
Place the data
string below it’s related dimension
Stepping through your process in
a Dynamo graph is important, because not every project is the same. Building
flexibility into our graphs in this manner sets us up for success. As always, I
would encourage you to test any script like this out on a test project, before
using it in production.
I hope this example can
demonstrate to any structural designers and engineers who may not already be
aware, just how they might be able use Dynamo on a project with beam systems. That
might spark other ideas, too, because utilizing a script on a mundane task can
also save so much time and effort.
Much of the logic behind this solution
was provided by John Pierson. Using my initial thoughts and
the resulting idea for improvement, John was able to expand upon what I
provided and assist with the onerous task of obtaining the dimension geometry.
Tom
Kunsman is a structural designer with over 20 years’ experience and
continues to find ways to utilize Dynamo in structural and other disciplines. He
has experience in BIM Execution Plans BxP, Revit family content creation in all
disciplines, and continues learning how to adopt or improve established BIM
workflows.
John
Pierson is a Design Technology Specialist at Parallax Team and a Revit
certified professional for all disciplines. He is an active member of the
Dynamo community and currently manages the Dynamo package called Rhythm.
Before you go, please take 3 minutes out of your day to participate in the AUGI Annual Salary Survey. https://www.surveymonkey.com/r/2019AUGISalarySurvey