Hi all. I would like to uniquely identify the faces of a subd . Unfortunately it seems to me that based on the type of transformation carried out on an element of the face, the Id property can change. and i think also the order in the subd.Faces list. is it correct? and how can i do that? because there is no user data or tag to add to a subdface.
Hi @gianfranco74,
It’s not clear to me what you are trying to achieve. Do you have an example script, or at least of the transformations you are applying?
Rhino.Geometry.SubDComponent.Id
properties (on SubD faces, edges and vertices) are unique (at most one component has a given id in a SubD), and stable (they change as little as possible when the SubD is modified).
Anything that only changes the geometry (i.e. moving the vertices) of a SubD, or the rendering content (e.g. changing face colors), should keep all Ids in the SubD unchanged. If the topology is changed (for example a face was deleted), then Ids of the modified components can change.
The Ids in SubD.Faces
should be in strictly increasing order, which is why it can appear the order can change. For example, in a SubD with faces [1, 2, 3, 4, 5]
, deleting face with Id 3
will give you a faces list of [1, 2, 4, 5]
. Recreating a face where face 3
was could result in [1, 2, 4, 5, 6]
, although in some cases the unused Id 3
could be given to the new face.
Note that symmetries (_Reflect
and _Radiate
) don’t fully respect the stability property: anytime a symmetric SubD is modified, the whole child motifs are rebuilt from the parent motif. The Ids in the parent motif are stable, but the Ids in the child motifs might change completely from one change to the next.
Finally, I don’t think user data would help you here, as they would be tied to the Id of the component and follow the same rules of change.
Thank you very much for your time. it’s hard to give you a working piece of code without giving you the whole plugin. I can give you this video and what I see in events like RhinoDoc_ReplaceRhinoObject and RhinoDoc_AddRhinoObject. Now I’m using brepFaces because I realized the problem is the same as subdfaces I think. I see that in the first event e.OldRhinoObject and e.NewRhinoObject may or may not have the same brep face indices. and in the second event e.TheObject has indices that can be different from the e.NewRhinoObject detected in the previous event. So I have no way to identify a correspondence between the faces of the object to be transformed and the transformed one. I tried using the distance from the centers of the faces of the e.NewRhinoObject and the e.TheObject because I noticed that they have almost the same geometry, but in some cases it maintains the order of the faces of the e.OldRhinoObject, in others it doesn’t. I think it happens especially if there is symmetry. Do you need further information? Can I help you more?
I think that here you can understand better what i mean
i tried without simmetry and i think that simmetry is the problem.
Is there any way to locate the parents and children in case of symmetry in order to find the match I’m looking for?
Hi @gianfranco74,
It’s really hard to understand what’s going on here without at least a couple lines of code to reproduce the problem. I don’t see face indices changing in example SubDs, with a Reflect symmetry, while copying or replacing the object and changing the position of the vertices, when using built-in commands.
Can you check that you are getting the correct face indices by using the TestSubDLabel
command to tag the faces with their Ids?
Is the SubD that goes through RhinoDoc.AddRhinoObject()
generated any differently than the one that goes through RhinoDoc.ReplaceRhinoObject()
? Are you copying all the same properties in both cases?
I’d rather stay focused on the SubD issue here, everything in your videos is SubD objects only, with no conversion to Brep faces, correct?
ON_SubD::GetSymmetrySet()
is one way to get all the parent and children motifs related to a SubD component. Alternatively, motif group id is saved by SubD symmetry code in ON_SubDComponent::MarkBits()
, so it only stays around for as long as another piece of code does not change these values. The parent motif has id 1, the rest is higher.
Thank you verymuch ,i have only one problemi.i use c# .Is It possibile with c#?
Oops sorry it sounded like this was going to be a C++ plugin. These methods have not made it to the C# SDK yet unfortunately. I’ve logged this request to add them: https://mcneel.myjetbrains.com/youtrack/issue/RH-80727/RhinoCommon-SDK-Add-SubD-symmetry-operations