In the realm of Rhino 3D development with RhinoCommon, grasping the concept of Globally Unique Identifiers (Guids) and how they relate to objects is crucial. Specifically, understanding how GUIDs are associated with RhinoObject
and ObjRef
is essential for effective programming. This guide aims to clarify these relationships, ensuring a solid foundation for developers working with Rhino’s API.
At first glance, it might seem intuitive that a RhinoObject
directly holds a GUID. However, in RhinoCommon, the architecture is slightly different. A RhinoObject
, in its technical definition, is a runtime object. This means it primarily manages data relevant during the program’s execution, such as selection status or display properties. It’s important to recognize that a RhinoObject
itself does not inherently possess a GUID as a direct property.
So, where is the GUID stored? The answer lies within the ObjectAttributes
of a RhinoObject
. The ObjectAttributes
class is responsible for storing persistent properties of a Rhino object, including its unique identifier. Therefore, when you need to access the GUID of a RhinoObject
, you are essentially retrieving the ObjectId
from its associated ObjectAttributes
. This is precisely what happens when you call RhinoObject.Id
. In fact, RhinoObject.Id
is essentially a shortcut for RhinoObject.Attributes.ObjectId
. You can utilize either method to obtain the GUID, depending on your coding style and preference for verbosity.
// Example showing how to access the GUID of a RhinoObject
// Method 1: Using RhinoObject.Id
Guid objectId1 = rhinoObject.Id;
// Method 2: Using RhinoObject.Attributes.ObjectId
Guid objectId2 = rhinoObject.Attributes.ObjectId;
// objectId1 and objectId2 will be the same GUID
It’s also vital to understand that the geometry of a Rhino object is directly stored within the RhinoObject
itself. To access and manipulate an object’s geometry, you must first obtain the RhinoObject
and then request its geometry. There is no alternative pathway to retrieve the geometry without going through the RhinoObject
.
Now, let’s introduce ObjRef
, which stands for Object Reference. An ObjRef
is, as the name suggests, a reference to a RhinoObject
. ObjRef
objects are commonly created as a result of object selection operations, particularly when using methods like GetObject
. The ObjRef
encapsulates comprehensive details about the object selection process. This includes the referenced RhinoObject
, the selected geometry (or sub-geometry in cases of sub-object selection), the precise pick location, and other relevant selection information.
Consider the scenario of selecting a curve using the GetObject
command in RhinoCommon:
GetObject go = new GetObject();
go.SetCommandPrompt("Select curve");
go.GeometryFilter = ObjectType.Curve;
go.SubObjectSelect = false;
go.Get(); // Initiate the object selection process
Upon successful curve selection, you can retrieve the ObjRef
object created by GetObject
:
ObjRef objRef = go.Object(0); // Retrieve the ObjRef for the selected object
If your primary goal is to work with the selected curve’s geometry, ObjRef
provides a convenient way to directly access it:
Curve selectedCurve = objRef.Curve(); // Get the Curve geometry from the ObjRef
Behind the scenes, the ObjRef.Curve()
method streamlines the process. It effectively performs the following actions for you:
RhinoObject rhinoObject = objRef.Object();
if (rhinoObject is CurveObject curveObject)
{
return curveObject.CurveGeometry(); // Access Curve geometry if RhinoObject is a CurveObject
}
return null; // Return null if the object is not a CurveObject or RhinoObject is null
Alternatively, you can also obtain the selected curve geometry by directly accessing the Geometry
property of the RhinoObject
obtained from the ObjRef
:
RhinoObject rhinoObject = objRef.Object();
if (rhinoObject != null && rhinoObject.Geometry != null)
{
return rhinoObject.Geometry as Curve; // Cast the generic Geometry to Curve if possible
}
return null; // Return null if RhinoObject or Geometry is null
These examples illustrate multiple approaches to retrieve the Curve
geometry. The optimal method depends on your specific needs and coding context.
Similarly, if you need to access the GUID of the RhinoObject
referenced by the ObjRef
, you can use the ObjectId
property of the ObjRef
:
Guid objectIdFromObjRef = objRef.ObjectId; // Get the GUID through ObjRef
Internally, objRef.ObjectId
simplifies the process by performing these steps:
RhinoObject rhinoObject = objRef.Object();
if (rhinoObject != null)
{
return rhinoObject.Attributes.ObjectId; // Access GUID from RhinoObject's Attributes
}
return Guid.Empty; // Return an empty GUID if RhinoObject is null
Again, this demonstrates different pathways to reach the same result – obtaining the GUID of the underlying Rhino object. This flexibility is a common characteristic in programming, and RhinoCommon is no exception.
In summary, while RhinoObject
itself is a runtime entity without a direct GUID, the unique identifier is persistently stored within its ObjectAttributes
. ObjRef
acts as a powerful reference, providing access to both the RhinoObject
and its associated data, including the GUID and geometry. Understanding these distinctions is crucial for developers effectively working with RhinoCommon and manipulating objects within the Rhino environment. By grasping these concepts, you can confidently navigate the Rhino API and efficiently manage object identification and data retrieval in your Rhino 3D development projects.