Changing rhino unitsystem

Hi all,
I am having troubles trying to convert one script from python to c#. I realized that I have to change all of the structure. The code is about units. I would like to have one tool that notify me which units I am using in Rhino. here there are the scripts that I made. Also, I would like to know what the syntax for units in rhino is.


and here is the python script that I want to achieve in c#

thanks in advance for your help.

Hi @santi.canorestrepo,

Let me know if the attached helps.

UnitSystem.gh (4.4 KB)

– Dale

2 Likes

Hi @dale
thank you very much. It was very helpful. Also, I would like to know if there is any way to change the units from Grasshopper to Rhino? and alert me whenever I am not using feet or inches.
thank you Dale!

Santiago.

Hi @santi.canorestrepo,

To modify the Rhino document’s model unit system, use RhinoDoc.AdjustModelUnitSystem.

To be notified when the Rhino document’s model unit system has change, you will need to handle the RhinoDoc.DocumentPropertiesChanged event.

– Dale

Dear Dale, how can I do this from a c++ plug-in? I don’t see AdjustModelUnitSystem as declaration. Is it under a different name?

Here is an example.

https://github.com/mcneel/rhino-developer-samples/blob/6/cpp/SampleCommands/cmdSampleChangeUnitSystem.cpp

– Dale

Sorry, for necrobump of this one though I have a related question which can fit here.

Dear @dale is it possible to know the result of below dialog or i need to ask again on my own for my purposes?
image

Also i found weird behavior when I will choose Yes (scale model) and use Insert command it seems to be adapted in insertion window i have Uniform 1 1 1 but when i reset the scale of object it seems like original one wasn’t scaled internally but InstanceObject has some xform on it? That’s problematic as original definition didn’t changed on scale action… So if ill use under such conditions Rhino.RhinoDoc.ActiveDoc.Objects.AddInstanceObject it behaves like scaling to the entire doc wouldn’t happen at all …

Adding recording to explain better:

Is this xform hidden under some property to get one ? Tracking it by dev on his own doesn’t make much sense from my pov. I guess this won’t be considered as a bug though it seems like some shortcut here.

Hi @D-W,

Picking Yes to scale the model will trigger a RhinoDoc.DocumentPropertiesChanged event and, if your model has objects, some RhinoDoc.ReplaceRhinoObject events.

Also, an InstanceDefinition object now the unit system of the model from which it came from. The Insert command will look at this unit system and scales a new InstanceObject accordingly so it comes in at the scale the user expects.

Hope this helps.

– Dale

1 Like

Hi @dale,
thanks for quick response

Umm ok changing units will fire one DocumentPropertiesChanged and scaling should fire second one? Need to inspect that, though thanks for hint with RhinoDoc.ReplaceRhinoObject i can try to find workaround to find out what user picked.

I imagine that and i realized it’s like that especially for cases with linked blocks though afaik there is no exposed method or property bound to InstanceDefiniton to get that information to prep own xform or get one - i mean i would like to have the same info about it when doing Insert via Rhino.RhinoDoc.ActiveDoc.Objects.AddInstanceObject otherwise I’m ending with objects in the wrong scale.

Hi @D-W,

RhinoCommon for Rhino 7 exposes a new InstanceDefinition.UnitSystem property.

For example:

private void RunScript(Guid id, ref object geometry)
{
  var doc = Rhino.RhinoDoc.ActiveDoc;
  if (null == doc)
    return;

  var iref = doc.Objects.FindId(id) as Rhino.DocObjects.InstanceObject;
  if (null == iref || iref.ObjectType != Rhino.DocObjects.ObjectType.InstanceReference)
    return;

  var idef = iref.InstanceDefinition;
  if (null == idef)
    return;

  var bScale = false;
  var xform = Transform.Identity;
  if (idef.UnitSystem != Rhino.UnitSystem.None && idef.UnitSystem != doc.ModelUnitSystem)
  {
    var scale = Rhino.RhinoMath.UnitScale(idef.UnitSystem, doc.ModelUnitSystem);
    xform = Transform.Scale(Plane.WorldXY, scale, scale, scale);
    bScale = xform.IsValid;
  }

  var out_geometry = new List<GeometryBase>();
  var i = 0;
  while (true)
  {
    var rh_object = idef.Object(i++);
    if (null == rh_object)
      break;

    var geo = rh_object.Geometry.Duplicate();
    if (bScale)
      geo.Transform(xform);
    out_geometry.Add(geo);
  }

  geometry = out_geometry;
}

– Dale

2 Likes

Glad to hear that!

For now need to find out a way for v6 - so last one.

Is there sth in cpp API i can pinvoke on my own?

Oh and thanks for full example above :+1:

1 Like
ON_InstanceDefinition::UnitSystem()

– Dale

Thanks :wink:

Found the root!