How can I leverage the new Unit system in own Zero Touch Nodes?

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 always work with ‘unit’ and leave it to the user if that unit is a meter or foot. Maybe I did it wrong but why do you need to name that unit?

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.

1 Like

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.

Clipped part example:

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.

2 Likes

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. :slight_smile:

2 Likes

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?

I’ll send you a DM here with contact info for me and one of my colleagues shortly.

1 Like

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:

  1. 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

  2. import the DynamoUnits namespace in the class header, in my case using U = DynamoUnits; is how I did it

  3. 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).

2 Likes