Yes, this one was a long time coming. I am not saying that anyone should be surprised with the new way of handling units in Revit API, but at the same time if anyone else out there likes to procrastinate for as long as I did, then bang, this was a surprise. I didn’t do it for my archi-lab.net 2021 releases, and now that the old way was straight up deleted it was time to take a look at it. You know, there is nothing better than people complaining something doesn’t work, to get you going in the right direction. That’s exactly why I had to make the change.
So archi-lab.net has a few nodes that deal with units. One of them is for simple conversion between Internal Units into any Display Unit. For those of you that know this, apologies for a refresher, but for those of you that might be new to Revit, Revit internally works in Feet. All values returned by the API will be in decimal feet. Dynamo deals with converting that to whatever the Display Units are set to. Display Units are what you have set here:
In this case the Length is displayed in “mm”, so even though values are queried internally in feet, when Dynamo displays them to you, they will be shown in mm. Let’s demonstrate that in action. If I select a Wall from the model, and query the “Unconnected Height” parameter from it, I will get the following value:
Since the model’s Display Units are in mm, so is the value returned to us. However, Dynamo wouldn’t be Dynamo if there weren’t some Easter Eggs to go along with this completely logical solution. Here’s a value returned by the Width property of a Wall Type:
Mhmmmm, that certainly cannot be 1.14mm. Can it? Of course not! It’s in internal units (feet). Why? Because Autodesk. Because of these inconsistencies, I had some unit conversion nodes in archi-lab.net package that will allow you to convert these units into mm, or any other units of your choice. Here’s how:
This looks more accurate.
Now, that you know why we need these unit conversion nodes in Dynamo, let’s get back to the crux of this post. Revit 2022 and changes to units in Revit API. Say goodbye to Display Unit Types, and say hello to Forge Type Ids. I know. That Forge thing is now everywhere. Makes me wonder if they will start charging us tokens for unit conversions now. 🤣 Anyways, if we wanted to do the same thing as I did above in Revit 2022, we would have to do this instead:
So what are these Forge Units, and why do we have them in Revit now. I think Autodesk is trying to unify unit handling across all of its applications. What we can expect in the future is some kind of interoperability workflows utilizing its Forge Platform. I guess with the advent of platforms like Forge Automation, where you can execute a script on a model using Autodesk’s Services, the idea is to allow these models to be passed for example from Revit Automation to CAD Automation, but then also view it in Forge Viewer. Units are critically important for all of the translations that the model geometry would undergo in the process. Having a uniform schema for units across all platforms is kind of cool, so I am not going to knock them for that. I will take these changes in good faith. There is a good documentation page for how these changes affect two of the most popular Unit Utilities, one being Convert From Internal Units, and another being Format Utility. Documentation. I haven’t shown any examples of the Format utility so let’s do that since it’s using another thing that’s new called Forge Spec.
Let’s take that same Wall Type width that we had above. We can achieve the same conversion from internal units, into display units like so:
The concept here is a little different. We are attempting to format value from one unit system into another. Assuming that we are getting a value in the internal units, we can use this node to convert that value into another. For example from metric to imperial. Because Wall Type width has a glitch, and it gives us values in internal-internal units (feet), ignoring the units set by user for display purposes, feeding it the Units returned by Units.GetInternal (it’s the units set for the model by the user so in this case mm), will actually convert ft > mm. I guess that’s a confusing example. Let’s use a more straight forward one. Let’s say we want to convert that value into Feet and Fractional Inches.
I know this looks a little scary, but let’s explain. The display units for this model are set to mm (metric), so if we want to convert a value into something like inches (imperial), we can create our own units, and make them imperial. Once, we have an imperial units created, we can set their own display units aka. Format Options for what used to be called Unit Type, but now is called Forge Spec. The spec we want to set is “length”. We want our length values to be displayed in Feet and Fractional Inches. Once we set that we can pass these Units to our Format node, and will get our value displayed as 1 – 2″. Cool, isn’t it?
Another thing that you might be wondering about here, seeing the new values for Forge Units and Forge Specs is the last three digit at the end of each one. It’s the version number. Why do we need version numbers for units? I guess Autodesk wants an option to change these unit definitions. Why? I really don’t know, but I am going to speculate that some of these more scientific conversions, might be pegged around some world standards that can potentially change as research around these advances. Here’s an article about pretty recent re-definition of SI units from 2018: Article. I guess change happens, and keeping track of versions for these units, will allow Autodesk to allow you to choose your unit version. That’s kind of cool. I like that flexibility.
Now on the code side of things the changes are not that big. We really substituted Display Unit Type with a Forge Unit Type Id:
The above code that used to use DisplayUnitType which was an Enum, now can be executed by creating an instance of a ForgeTypeId class:
That’s really not that bad at all. I guess we will have to deal with versions of unit types in the future as they change. That’s pretty much it. Maybe another interesting thing to note here, is that previously we had DisplayUnitTypes as an Enum so it was pretty easy to grab the one that we wanted. Same with UnitTypes. These new ForgeTypeId classes don’t have an Enum, so to get one that we want we have to get a whole list of them, and search through that. It’s a little bit less efficient in some cases. Of course just to make things inconsistent, we actually do have a static collection to reference specific Spec for the SpecTypeId class. I guess these are not expected to change a whole lot, or there were less of these and Autodesk decided to give us an easier way to get access to these. I don’t know. Things are never very consistent with them. Also, as far as I know, not getting into these unit changes earlier wasn’t that bad of a deal. It seems to me that they changed this since last year anyways. I am glad I am doing these changes once, instead of twice. Less is more, in the words of famous Mies van der Rohe.
One more thing worth noting here is that these unit changes for Revit 2022, caused archi-lab.net not to load properly into Dynamo. For some reason if your package wasn’t updated to handle these new units, your package is not likely to load properly into Dynamo. I am not sure why, since it normally should just fail to initialize the specific node that would want to use that code. Again, some of the stuff they do there at the Autodesk factory is a mystery to me. It was crashing my package, and I was forced to update these seldom used nodes to appease the masses. Phew!
nodes like family instance by geometry and get compound structure layers has error with units.some workaround please?
it important for my work.
Please post a request here: https://github.com/ksobon/archilab/issues
It is on this occasion that i can put away my dislike for napoleon and wish the french navy were able to cross the channel and erase imperial units out of the damn world.