Trouble uniquely identifying a Mesh

Hello @nathanletwory,

related to this, I’ve been delving in what would be an Import/Export to an external software process and I’ve found that the geometry, (in the particular case I’m using, the Mesh) provided by the Changequeue is different from the one you can get from the RhinoDoc.

What I mean to ask is, how should I proceed to uniquely identify a mesh, object, instance, etc in both the changequeue and the RhinoDoc simultaneously?

Thanks in advance,

Alonso.

Edit: To clear this up, Im trying to use a single string identifier to unambiguously identify an element in the scene, be it through the changequeue or accessing the tables in the Document, setting certain parameters in an intermediate structure.

In what way are they different from each other?

Does this mean you’re looking to use custom user data on objects?

Not exactly, let me explain better.

The Mesh that you obtain from the changequeue has an unique Id of its own, as in this:

In its structure, its very similar to what a RhinoObject would be. On the other hand, the Geometry based Mesh has not an unique Id, and thus this confuses me a bit.

Regarding the custom data, the thing is that I’m trying to have a parallel scene structure, which means I’d like to embed as few data as possible within the rhino objects, though it may be necessary in the end, at least to host the identifiers.

Perhaps the Id() is a misnomer and it should’ve really been called ObjectId (and as a property, at that). The Guid returned from that is not the Mesh identifier, but instead it is the object identifier. The Id identifies the object the mesh is for.

1 Like

Yeah, that clears the issue quite a bit :sweat_smile:. Sorry if I’m being a bit dense and thanks for your attention again @nathanletwory.

That’s ok. Keep the questions coming, it can be a learning process. It after all took several years to stich this system together!

If you run into other issues, but not related to identifying meshes, please don’t forget to start a new thread topic :slight_smile:

Will do! :+1:

Recently, I’ve been trying to mount a system based on the conclusion @nathanletwory and I reached here, but the trouble I’m facing is related to this post.

Let’s put an example. I wan’t to modify data on InstanceBox1. InstanceBox1 has been generated within my parallel structure with the name “Instance_” + <InstanceId> using the ChangeQueue’s ApplyMeshInstanceChanges provided data, thus, the MeshInstance data.

If I generate a command that takes the selected objects from the screen, and, for example, wants to change some data associated to said objects within my parallel structure, the data available are not those from the ChangeQueue, but data from the RhinoDoc, the only source from which I can identify which objects are selected in the viewport. And, if the selected objects are instances, there seems to be no way to uniquely associate the results obtained from a ChangeQueue to the possible results obtained from a RhinoDoc. I thought of associating userdata to each instance, but said user data are seemingly not accessible from the ChangeQueue.

This means that from the RhinoDoc there is no way I can ascertain which parallel structure im referring to…

I thought of using a similar structure to what @nathanletwory did in RhinoCycles plugin:

/// <summary>
/// Record what meshinstanceid (objectid) points to what meshid
/// </summary>

private readonly Dictionary<uint, Tuple<Guid, int>> _rhObjectidMeshid = new
Dictionary<uint, Tuple<Guid, int>>();

But, the objectid contained within the meshinstanceID, though unique, is not directly the Guid of said object in structures.

What I mean is, is there a way to have available at the same time the id of the instance in RhinoDoc and the one provided from the ChangeQueue? This way i could build something similar to the dictionary that @nathanletwory did and solve this problem.

@alonso.rosado, I am asking @andy, who may have some ideas regarding this.

1 Like

Thanks @nathanletwory, sorry for the insistance over this issue. I’m grateful you are bearing with me.

Hey there, I just realized that it is already possible to access userdata attached to geometry objects, even through the ChangeQueue. I actually use this to tag objects as cutting volumes for Raytraced cutout support ( essentially a generalised form of clipping planes). I tag an object with custom user data, and in my ChangeQueue implementation I override ProvideOriginalObject, returning true.

Once you start returning true from ProvideOriginalObject you’ll find that ChangeQueue.Mesh will have its Attributes property populated. This gives you access to ObjectAttributes, which will carry any of the user data that is attached to the original objects Attributes.

This means you can also find the ObjectId of the original object, and much more.

Accessing the ObjectAttributes in ChangeQueue.ApplyMeshChanges():

Attaching custom user data to an objects’ Attributes:

The custom user data for this case:

Well thank you @nathanletwory!

This is quite a lot of info, so It’ll take some time , but its hightly probable that Im able to get a workaround going with this! I’ll let you know what happens.

Thanks,

Alonso

@nathanletwory, I’ve been analysing your proposed solution and, while it opens possibilities to several features regarding RhinoObjects per se, when dealing with instances it still doesn’t allow several things.

The MeshIntance given info is somewhat limited.

As far as we’ve discussed, the MeshInstance InstanceId is a CRC of several data of the instance, and while it’s unique, it doesn’t allow for identification when, for example, I want to use the selected objects on the viewport to define some settings on the parallel structure for the required objects.

For example:

var selected = doc.Objects.GetSelectedObjects(false, false);

This returns the selected RhinoObjects, which easily may ot may not be instances.It can be checked doing:

public static bool IsInstance(RhinoObject obj)
{
return obj != null && obj.ObjectType == Rhino.DocObjects.ObjectType.InstanceReference;
}

Even if I were to use the way of obtaining an InstanceObject shown here:

var iref = objref.Object() as Rhino.DocObjects.InstanceObject;

I would not be able to bond easily said object to the info given to me by MeshInstance, simply because the only common ground is the transform.

This wouldn’t be a problem if each instance provided by the changequeue were to have its own UserData, as I could simply use those to set the data necessary for identification within.

Right now, this means I cannot use the ChangeQueue to populate my parallel structure, because if I were to try and modify something, if it were not to be modified from the changequeue, I wouldn’t be able to properly identify it.

Also, while we are at it, I’m wondering which would be an adequate place to initiate a changequeue that keeps track of the changes in a doc while there’s no render engine.

Thanks in advance,

Alonso

Right, Attributes on a MeshInstance would indeed very useful. Logged as: RH-45700

I didn’t really test the idea, but I suppose you could start a queue in a command, disconnected from any rendering engine. I suggest you try instantiating a change queue from a command with the active view for the given document.

Hello,

I have found this entry.
As far as I know identifying the source of the mesh is still limited.
I see that it was logged as something to do in the future but was not really started.

To have a solution for this would be important for me too. Currently I use heuristic methods to identify the source InstanceObject which works OK, but really slows down the export process.

Rhino.Render.ChangeQueue.Mesh has an Object property. Couldn’t you add something like this to the Rhino.Render.ChangeQueue.MeshInstance too to see the source it comes from (RhinoObject or MeshInstance) ?
It would be really great.
(Object Attributes only could work too, but the original object contains information (for example the user has given a name to the object, etc… - so I would prefer that)

Márton

Could I up-vote this requested API change somehow?

I see it is not in priority at all, but in the case of our plugin it would improve the speed a lot. The current plugin has to do a lot of extra work to find the source InstanceObject.

Passing the id of the source InstanceObject along with the mesh would be enough.

Márton

Márton

1 Like

I’m looking into adding Guid of direct parent, and for root.

Hello Nathan,

Thank you, that would be really great!

Márton

I’ve hadded ParentId and RootId to MeshInstance in Rhino 7. It should be available in the next BETA release sometime next week.

Ohh, I haven’t seen your answer.

Thank you very much!!! This is great news for me!

There is no chance to have it in Rhino6 too, right? Would be good but I can understand of course…

Márton