Keep object reference during transform? [Solved]

rhino5

#1

I have two variables referencing two Rhino objects (meshes). When I mirror the two Rhino objects I end up referencing the two GH object copies with my variables, “losing contact” with the original objects, so to speak.

I would like to delete the original objects (m_ScMesh and m_HmMesh) from the Rhino file and keep only the mirrored GH objects (to be baked later), but how do I keep a reference to the original objects (so I can delete them) while performing the Transform? :

The code:

        // Mirror if Left oriented
        if (m_ScCentroid.X > m_HmCentroid.X)
        {
            // Right, leave as is
            m_IsMirrored = false;
        }
        else
        {
            // Left, do Mirror:
            Plane plane = Rhino.Geometry.Plane.WorldYZ;
            Transform xform = Rhino.Geometry.Transform.Mirror(plane);
            m_ScMesh.Transform(xform);              // <-- How to keep original and mirrored ref
            m_HmMesh.Transform(xform);              // <-- How to keep original and mirrored ref
            m_IsMirrored = true;
        }

// Rolf


(Menno Deij - van Rijswijk) #2

Rather than getting the Rhino.Geometry.Mesh from the grasshopper input, you can also get a GH_Mesh from the input. This is the grasshopper wrapper around the (possibly) referenced object in the Rhino document; access the .Value property to get the actual mesh.
On the wrapper there are properties to see if this object was referenced, and if so, what its Rhino GUID is. I don’t know the specific property names by heart though…


#3

Thanks for replying.

I’m actually not retrieving the meshes from the GH inputs. This component has no inputs and I’m examining the RhinoDoc for meshes by code, identifying the two meshes I’m interested in (based on size).

        foreach (RhinoObject rh_obj in Rhino.RhinoDoc.ActiveDoc.Objects.GetObjectList(ObjectType.Mesh))
        { 
        }

There can be right and left oriented versions of the source meshes, and this is where I’m at now - mirroring the meshes in order to be able to process only right handed versions (and mirroring back again when done processing the meshes, which is why I keep track of whether it was mirrored or not (m_IsMirrored)).

I will also move the meshes to left side of the Y axis, and also there I want to get rid of the original meshes.


Edit:

OK @menno, you put me on track with your comment on Object Id's, so I picked up the id’s for the meshes I work with in my component, like so

         foreach (RhinoObject rh_obj in ...) 
         {
             m_mesh = (Mesh)rh_obj.Geometry;
             RhGuids.Add(rh_obj.Id);
             // ...
         }

… which I could then use to delete the objects later in the method.

        // If Mirrored, Remove the original Meshes
        if (m_IsMirrored)
        {
            foreach (Guid guid in RhGuids)
            {
                Rhino.RhinoDoc.ActiveDoc.Objects.Delete(guid, true);
            }
        }

Thanks for the hint.

// Rolf


(David Rutten) #4

Typically transforming is done not by calling Transform() methods on GeometryBase type classes, but by getting IGH_GeometricGoo and calling transform on those. It allows you do handle all types that Grasshopper knows how to transform.

However, once transformed, the object is no longer considered referenced (it has changed from the original after all), but you can probably reapply the ReferenceId field before and after the transformation.


#5

How do I do that?

I had to copy the GeometryBase.Transform in order to get a valid reference to the transform, and of course that didn’t feel right… :slight_smile:

            m_ScMesh.Transform(xform);
            m_HmMesh.Transform(xform);
            m_ScMesh = m_ScMesh.DuplicateMesh();        // Ouch...
            m_HmMesh = m_HmMesh.DuplicateMesh();

// Rolf


(David Rutten) #6

All data in Grasshopper is stored as IGH_Goo, and IGH_GeometricGoo is a special flavour of goo that has an extra bunch of geometry related features. If you’re getting objects out of the Rhino document and transforming them right away inside a single script, then I guess you wouldn’t come across any IGH_Goo types. However the transform components take in data of type IGH_GeometricGoo and also output them. So instead of

Mesh mesh = null;
if (!DA.GetData(0 ref mesh)) return;
mesh.Transform(blahblah);
DA.SetData(0, mesh);

you’d use

IGH_GeometricGoo goo = null;
if (!DA.GetData(0 ref goo)) return;
goo = goo.Transform(blahblah);
DA.SetData(0, goo);

Note that the Transform method on geometric goo returns a new instance, it leaves the current one unmolested. This is useful for geometry that cannot be transformed without turning into some other kind of geometry. Such as squishing circles or tapering arcs.


#7

Hm. I need to pick up the data using my own code, because I need to automatically identify individual meshes (and then send them to dedicated outports for further processing ).

So this is how I get hold of the meshes in the first place (no inputs on my GH_Component) :

    foreach (RhinoObject rh_obj in Rhino.RhinoDoc.ActiveDoc.Objects.GetObjectList(ObjectType.Mesh))
    { 
         Mesh m_mesh = (Mesh)rh_obj.Geometry;
         ...
    }

So how do I type cast from rh_obj.Geometry to IGH_GeometricGoo ?

// Rolf


(David Rutten) #8

If all this code is internal, you don’t have to.

If you know you have a mesh, just create a new GH_Mesh(), that class implements IGH_GeometricGoo. If you don’t exactly know what type of object you have, you can try GH_Convert.ToGeometricGoo().


#9

I found the constructor GH_Mesh(Guid id) or GH_Mesh(Mesh mesh) which seems to be what I can use.

Thanks,
// Rolf