Rhino.Geometry.Plane UserData or ID

Hi Folks,
i’m working on a plugin for Rhino/Grasshopper with extensive use of UserData and discovered, that Rhino.Geometry.Plane class is not inheriting GeometryBase, so it doesn’t inherit the UserData or UserDictionary properties.

Is there a chance, that this could be added to RhinoCommon in the future?

If not, i’ll try some workaround, with a generic database object, which holds data + id of the desired planes.
At runtime i can refer to the data for that plane in db with the plane id.

My question here would be, how to obtain some kind of id? The GetHashCode() method will not work, since it changes every time the plane coordinates change.

Since rhinocommon is wrapping unmanaged code, may there be a pinned memory location for any plane object?

Could i use a memory pointer to track the plane object.
It’s not necessary, that data is stored when rhino closes. Since it will be a grasshopper plugin, the db will be generated each time that plane object has been created in memory. Its ID must be consistent only at runtime.

I hope this description explains the concept. Don’t hesitate to ask any questions, if it’s not clear.

Florian Frank

Plane in RhinoCommon is a struct data type and does not wrap any unmanaged code. This is similar to a Point3d which is just 3 doubles. We aren’t going to change this to support UserData since the overhead for common usage would be significant.

One possible solution for you may be to use the PlaneSurface class instead of Plane

Hi Steve,
hm this sounds bad for the project. I’ll see if PlaneSurface is some option…

Thanks a lot for your fast reply!

Ok i got it…there is a ON_Plane object created by rhinocommon, but then destroyed after copied to the struct:

bool rc = false;
const ON_3dPoint* _origin = (const ON_3dPoint*)&origin;
const ON_3dVector* _normal = (const ON_3dVector*)&normal;
ON_Plane temp;
rc = temp.CreateFromNormal( _origin, _normal);
CopyToPlaneStruct(*p, temp);
return rc;

Suggestion: If the plane struct had a GUID property, would this have a significant overhead for common usage?

public struct Plane : IEquatable, IEpsilonComparable

#region members
internal Point3d m_origin;
internal Vector3d m_xaxis;
internal Vector3d m_yaxis;
internal Vector3d m_zaxis;
internal Guid m_uuid;
#region properties
/// <summary>
/// Gets the universally unique identifier of the plane
/// </summary>
public Guid Id
  get { return m_uuid; }

*public Plane(Point3d origin, Vector3d normal) : this()
UnsafeNativeMethods.ON_Plane_CreateFromNormal(ref this, origin, normal);
this.m_uuid = Guid.NewGuid();

Sorry if i’m still sticking at this plane id / userdata issue. This is my last comment on this topic i promise :wink:

Florian Frank

This will have a significant overhead and it is not going to happen. Is there a problem with using PlaneSurface instead?

Ok i understand. It would have bad influence on performance for common usage. It’s not worth it. Was a bad idea :smiley:

I did some tests with PlaneSurface, the problem is the Grasshopper workflow. Since components with plane inputs are converting the PlaneSurface to Plane, the UserDictionary ect. is gone.

Alright, i’ll find some other solution.
Thanks a lot anyway!