Preserving Geometry GUIDs on modification

We are looking for a means of either preserving or keeping a record of the GUID history of geometric entities.

If a Brep or Extrusion geometry is modified, for example, if one of its faces is modified, or if a boolean operation is performed, then the GUID changes. I assume behind the scenes the geometry is disposed and a new element takes its place.

My question is, we need to be able to track this change as we are tracking the geometry in one of our apps. If the GUID changes it breaks our tracking so we need to know if there is a way to monitor the change.

Some ideas we’ve had and tested without any luck include:

  1. User Data - this is disposed after a boolean operation so not a solution.
  2. HistoryRecord - this (AFAIK) only tracks changes to inputs to geometry and doesn’t receive the command callback if the geometry object is modified (i.e. it has no inputs) so also not a solution.

Another untested idea which sounds hacky but might be the only way:

  1. Use the ObjectTable and event handlers to ‘listen’ to deleted geometry, then get the latest added object on the ObjectTable and do some gymnastics to try and link the event condition with the change to the ObjectTable and update the GUID in our app.

Is there a reliable way to do this? NamedPositionTable?

Hello - are you working in plain Rhino or in a script or plug-in code? There is no control over this in Rhino, that I know of but it should, I think, be possble in code. (Using, for example, ReplaceObject() )


Hi @pascal its a Rhino plug-in written in C#. I think I’m in the wrong forum as I notice there is a dedicated Developers forum!

Nevertheless, we’ve also ruled out NamedPositionTable now; once the geometry is disposed, the position table will remove the pointer from the key value pair which puts us back at square one again.

I should also add some additional details as there are some technical limitations I am aware of:

  1. We assume a 1 to 1 relationship, i.e. the user modifies a BRep by intersection. The result is still one BRep after the operation, only there is a new GUID, so if we can monitor the change of the GUID from the old to the new then this would be exactly what we need.
  2. If a BRep is intersected such that it splits it into multiple new BReps then this is a 1 to many relationship and we wouldn’t need to track this change as we are only interested in 1 to 1 relationships. However it would still be useful to know the old BRep and the resultant new BReps GUIDs as we can use this for useful reporting to the user (i.e. breaks our supported relationship mechanism).

It would be good to know how Rhino handles booleans and other geometry modifications so seamlessly given that the new GUID assigned when these modifications take place suggests the disposal of the original and creation of an entirely new object which the user isn’t even aware of.

Yes - but depending on the input, the attributes of the new object may vary - on Join for example, if the objects are selected one by one, the first object chosen ‘wins’ and its attributes, where applicable, are on the resulting object; but with a preselection, the object in the list that is nearer the top of the object table is used. But indeed you should ask this stuff on the develolper forum - you’ll get a more competent answer - I will change the category…


Hi Pascale, thanks for adding some more insights and moving my post to the correct forum. I’ll await some answers here. :+1:

Hi Thomas

FWIW it seems subscribing to events is the way to go:

Also what might help with your gymnastics is the undostack:


Hi @Willem

Thanks for the links - I was hoping we could use something more direct than events but at least we know its the best approach. Thanks again!

1 Like