Automatic Dimensions from Columns to Grids
The first video shows the new updated version of the node.
The basic principles are the same though.
If you’ve seen the video (which I highly recommend) you know what the node does. You can find the node on the downloads page. So I have an old video showing what seems to be the same thing, but the older node has some drawbacks - It doesn’t delete dimensions that were already created for these columns - It’s creating annoying 0-value dimensions when the column is placed on the gridlines. This is now fixed. In the video I’m showing the python code node, which is now packed in a custom node with named inputs:
I’ve hidden the offset, units factor and the update/create new inputs, but if you need them you can find it if you edit the node:
If you want to use some of them as inputs, just add an input node and connect it to the appropriate input of the python node as shown in the video. If you’ve downloaded the node, the easiest way to make it reusable is to drag it to the Dynamo canvas and then click save as and navigate to your Dynamo definitions folder usually found in C:\Users\#user#\AppData\Roaming\Dynamo\Dynamo Revit\1.3\definitions This is for version 1.3 of Dynamo of course. If you’re using another select the appropriate folder. #user# is your username. I’m pretty sure you know how it works.
Initially, I wanted to make a blog post showing how to achieve the same result without python, only with nodes. I was pretty unlucky about that. Although it is possible to use a far simpler python node and do the rest with nodes. This becomes messy easily though. In Dynamo there's a node called "Dimension.ByElements"
And it works for Walls and Grids, but when you select columns, for example, it says “The references are not geometric references” Not the most correct error message, but I get it. I haven't found any decent dimensioning nodes in the packages as well. If you know any feel free to comment below. However, when I started creating this definition I used nodes for the calculating of which Grid is closest to which column. I always start with nodes first and then if needed I try compressing it in a Python node. Why do I do so? If I take this node as an example. If you have seen the video you know that first I have to find which 2 gridlines are the closest to every column. The gridlines are placed in 2 groups - one group with numbers as names and another with letters. (In my node at least, a different approach would be to group them by perpendicularity but I assumed the grids won't be always perpendicular to each other)
We need to get the location of the columns which is a point.
We get all the gridlines and take their names first so we can divide them into 2 groups. I’m using the String.ToNumber node and if it returns a Null that means that the string is not a number. In python it’s easier there is a function called IsAplha() that return true if a string contains alphabetic characters only. Then I’m using Object.IsNull to and List.FilterByBool mask to filter the list of the Grids. That means that I connect All Elements of Category to the list input.
From there I’m using Geometry.DistanceTo to find the distance from each point to each curve in both lists. The lacing of the node is set to “Cross Product”. I only need the closest grid to each point so I’m using List.MinimumItem. Notice that it is set to the second list level so It matches the sublists. Thus I’m getting the smallest distance from every sublist. I Use IndexOf to get the index of that value in the list and finally I use the index to fetch the Grid with List.GetItem at index.
So one thing is all of this is a small, but important part of the whole workflow. It takes a lot of space visually and it’s not the most optimized way to achieve the result. You can even define all of this as a function in the Python node and use it as many times as you want. Of course, we can also grab all these nodes and try to right-click and “Node to code”
This is what I got and it works. The code could be optimized but still, it looks better if you don’t mind looking at the code, of course.
An interesting thing is the way I approach updating the dimensions. The method for creating dimensions in the API does just that - it creates them. So in the previous versions, shown in my older videos everytime you run the script new dimensions are created.
Now I have this switch. If it’s set to false it just adds new dimensions. If it is set to True it tries to update them. "Update" is probably not the correct term though. It deletes the previously created dimensions and creates new. So the first time you run the script it checks if there’s a text file with the name of your project in the project directory and tries to read it. Of course the first time there is no such text file. It is created after the first run and it contains the Id numbers of each dimension. I’m showing this in the video. Initially, I was sending the Ids to the clipboard, but I find writing them down to the hard drive more reliable.
I also have to thank Mostafa El Ayoubi from https://data-shapes.net/ for showing me why I couldn’t extract the point reference of the column. I struggled with this a lot and the very first version of the script was using the underlying analytical model as a reference. Mostafa is a very nice guy with huge contributions to the Dynamo community. He has helped many people on the forum and created the data-shapes package which, if you haven’t already, I advise you to check.