I am searching for a way to make my Zero Touch nodes aware of units. In my library, I have very simple nodes that provide sane default values to users consuming the library. In other words, the node outputs length values for some other nodes to use, and has no input whatsoever. Currently the output will be 0.001 if I want to represent a value of 1 mm.
What I would like to do is to add an input socket that could consume the Units node Dynamo has since 2.13 I believe. If I then ask the whole thing to work in inches, I want to have an auto-converted value on the output socket of my node.
Is this possible? What would I need to do on the Zero Touch node to support this? I did not find any way to import DynamoUnits to my project so far.
I might need to add that I am using Dynamo Sandbox 2.18 at the moment, where a whole bunch of unit nodes are available, one of them the dropdown that allows you to set a unit type:
In this example, the ImportFromSATWithUnits node will use the unit to scale the imported geometry accordingly. The problem is, without being able to consume that unit in my own nodes, only the imported geometry scales, my own geometry stays constant in size. There is no preference setting afaik in Dynamo Sandbox that allows to define a unit for the application.
Correct. Dynamo is unitless. So generally if your node is working with internal geometry only and youâve got functional parametric inputs on your nodes, you can maintain that distance without the need for the Dynamo Unit. External geometry data doesnât permit that flexibility (it was recorded at a defined scale).
So if you write a graph that imports a SAT, findâs itâs bounding box dimensions, and it populates a Dynamo generated surface with a tiling of the imported geometry then the user would need to be working with the units of the import in mind. However rather than scaling all Dynamo geometry theyâd just want to scale the imported geometry to the units they have in mind (hence the Dynamo unit input on the import nodes). This works as the SAT file format has an indicator of âhow many MM per unitâ in the file header; not all file types have this (ie: .stl), and so the general assumption is the files are scaled to a MM but really if youâre in X units for both the STL and DYN work itâs a moot point - the measurements are relative.
So all of that said, what is your node doing which facilitates the need for units? Iâm not sure how to access that data type but it likely requires consuming the relevant nuget package for Dynamo core.
Thatâs an interesting read, thanks @jacob.small - to explain why Iâd need that unit node I need to explain a thing or two. The reason is historic.
I have started to develop my ZT Nodes library for panelling tasks years ago, long before the unit nodes existed. Back then I decided after some trial and error that itâs most consistent if I work in the same scale as my input geometry, which is always coming in via .sat interface. I then defined a few hundred nodes since, all of them assuming the model to be a certain size, so technically I had no need to ever switch units.
Recently, the panelling got more intricated though, and the elements kept getting smaller and smaller. I currently have a project where the element to place on the target is 1mm in each dimension! Therefore I run into the problem that the viewport clipping plane of Dynamo is so conservative that the geometry simply disappears in front of me when I try to zoom in closer. And, even though my working range is set to small, the precision errors out in some cases. All of these are reasons to work in a different scale. My hope now is that I can adress this by converting only the few length parameters in my nodes to support units, and supply the units when needed.
Technically I would work simply in a different scale of my geometry. That is also the fallback solution in case the units approach is not feasible. The beauty - if I got it working - is that I anyways have to specify an import unit now with the .sat input, and I could just propagate that further to the nodes that need it. And old node trees could still work with the new updated nodes, by supplying a sane default unit.
Makes sense once you noted the SAT import process. Iâll see if someone on the dev team can weigh in on how to get the class into your code base.
In unrelated news, this looks and feels like a manufacturing driven use which is super cool. Would love to see more of it in presentation/blog/write up. If youâre open to it but arenât sure where the Dynamo team can likely provide some sort of platform.
Hi @jacob.small this is indeed production driven, quite a few vehicles with Dynamo generated patterns are on the market already. Iâm open to discuss ideas about blog posts etc, just not here in the forum. How can I reach you via mail?
Actually @r.trummer I just noticed that the DynamoUnits assembly containing the Unit type is part of the DynamoVisualProgramming.ZeroTouch nuget package - be careful what you reference from there - I think that itâs too liberally public, and we might constrain it further in the future, but you should be able to use that type as an input like the sat node.
Hm, maybe Iâm doing something wrong on my end. I can confirm that I have that NuGet package installed (2.17.0.3493), but I cannot import the units package by adding a statement like using DynamoUnits; into my own ZeroTouch class. The error is CS0246
I wonder how I would utilize the package? Is there a step missing that I need to do? Or is there a reference file that I can check how it is supposed to be done?
Never mind, I finally got this to work! I had to run a few extra miles to do so, but here is the general idea:
make sure the ZeroTouchNode library you develop is targeting .NET 4.8 - mine was still on .NET 4.7.2, and that caused the DynamoUnits namespace import to fail
import the DynamoUnits namespace in the class header, in my case using U = DynamoUnits; is how I did it
convert between units as in the example below
public static double ConvertUnits(double number, Unit TargetUnit)
{
return U.Utilities.ConvertByUnits(number, U.Unit.ByTypeID("autodesk.unit.unit:meters-1.0.0"), TargetUnit)
}
Of course, your own example might differ, but this works beautifully for me (at the moment, as there is a deprecation warning regarding Units, but letâs see when this will become a topic).