Confusion about Rhino.DocObjects / CurveObjects

Hi All,

I’m working on a simple C# script that first gets all the objects on the current layer, and then filters out all non-curve objects. I’m doing this (probably inefficiently), by looping through the array of RhinoObjects, checking it’s object type, and if it is a curve then adding it to a new List<> of RhinoObjects. Something like this:

Rhino.DocObjects.RhinoObject[] rhinoObjects = doc.Objects.FindByLayer(currentLayerName);
List<Rhino.DocObjects.RhinoObject> rhinoCurveObjects = new List<Rhino.DocObjects.RhinoObject>();

foreach (Rhino.DocObjects.RhinoObject obj in rhinoObjects){

  //make sure we are only looking for curve objects
  if(obj.GetType().ToString() == "Rhino.DocObjects.CurveObject"){
    rhinoCurveObjects.Add(obj);
  }
}

Which works fine (although I’m open to receiving feedback about the wonky string comparison). Now I’m a bit confused because I don’t fully understand what these curve objects (or rhino objects) are. What I mean is that I would expect to be able to access attributes of a curve object like curve length, isClosed, etc. But those are not properties of the CurveObject as shown on:

https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_DocObjects_CurveObject.htm

I What I am hoping for is clarification on how to take these CurveObjects and be able to read the actual curve properties from them.

Any guidance is appreciated!
Best,
Brian

Hi @brianthomasharms,

Let’s say you have a RhinoObject:

RhinoObject rh_obj = ...;

You can verify it’s a Rhino curve object like this:

bool bIsCurve = rh_obj.ObjectType == Rhino.DocObjects.ObjectType.Curve;

If true, then you can try to cast the RhinoObject as a CurveObject.

CurveObject crv_obj = rh_obj as CurveObject;
if (null != crv_obj)
{
  // TODO...
}

Finally, once you have a CurveObject, you can get the curve geometry like this:

Curve crv = crv_obj.CurveGeometry;

Another approach is just to try to cast the Rhino object’s geometry as a curve:

Curve curve = rh_obj.Geometry as Curve;
if (null != curve)
{
  // TODO...
}

Hope this helps.

– Dale

Dale,

Thanks so much for the prompt reply! This is exactly what I needed.
Best,
Brian Harms

@Dale Fugier

Sorry I think I sent you a message instead of replying here :confused:

I have a quick follow up to this question, if you don’t mind.

Now that I have the geometry, and am outputting it from the C# component, is there a way I can imbue these geometries with specific attributes? Right now they seem to be geometry only, lacking any of the attributes that the original referenced geometries have. This makes sense, since these geometries are new instances as opposed to the original curves. But I’m wondering if I can now take the attributes from the original curves and copy them onto these new geometries, even though I wont be baking them into the document.

Best,
Brian Harms

What kind of attributes?

If by attributes you mean things like color, layer, material, etc., then you are correct. Geometry is just that - geometry. A Rhino object is made up of two pieces: the geometry and the attributes.

Not sure I’ve helped…

– Dale

Hi Dale, thanks for the response.

I think the issue is that I wasn’t very clear before :slight_smile:

So what I have noticed, is that when I output a RhinoObject (like a curve with user text properties, for example) I can’t plug that output into a crv parameter component and have it cast to a crv. For example I get the “1. Data conversion failed from Goo to Curve” error on the Crv component.

I understand that I could output both the geometry, and the attributes (user text) seperately (as two different outputs from the C# script component) but I am hoping to have them combined as one output.

My goal is to have the output both be able to act as the curve geometry itself, as well as containing the user text, so in components downstream of this one I can extract either/or.

Is that possible?

Best,
Brian Harms

Hi @brianthomasharms,

Like attributes, curves can contain user text. Perhaps this is where you should be storing it?

– Dale

I think this is the crux of my confusion - this is my understanding, please correct me if I’m wrong:

A rhinoObject is made up of 2 things, geometry, and attributes. RhinoObjects do not exist in the rhino document until they are baked.

A rhinoObject cannot be cast to a geometry directly when it is output from a C# component. My understanding is that in order to output the geometry to manipulate it with other components downstream, you would need to just output the rhinoObjects geometry.

The RhinoObject’s geometry is no longer associated with the RhinoObject’s attributes. So if you output the geometry, you lose the attributes.

So what I am hoping to do is: Find a way to output the geometry WITH the attributes, so that a single GH wire will contain both the geometry and the attributes, but without baking the geometry first.

Is that possible, or have I made an incorrect assumption?

Best,
Brian

This is correct.

That is also correct. This is ecause a RhinoObject does not inherit from GeometryBase.

Yes.

Your assumptions are correct. However, because geometry can store user data, you can store the id of the RhinoObject on the geometry. From this id, you can retrieve the original RhinoObject again and retrieve it’s object attributes.

Something like this:

RhinoObject rh_obj = ...;
var curve = rh_obj.Geometry as Curve;
if (null != curve)
{
  curve.UserDictionary.Set("id", rh_obj.Id);
  // ...
}

– Dale

Ahhhh, cool! Thanks, I’ll give that a try!