Create mesh and triangle mesh for selected objects

I ran into a group of problems and ask for help. First, I need to use the NonManifoldMerge command for the selected objects (Imprint between surfeaces (command)) on my video I call it without problems, but I don’t know how to call it using the Rhino C # API. After I need to make Mesh for these objects as shown in the video. Here is my code for creating a Mesh, but it still doesn’t appear in Rhino itself.

 protected override Result RunCommand (RhinoDoc doc, RunMode mode)
        {
            doc.Views.RedrawEnabled = false;

            List <ObjRef> objRef = new List <ObjRef> ();
            using (GetObject go = new GetObject ())
            {
                go.SetCommandPrompt ("Select objects");
                go.GeometryFilter = ObjectType.Surface;
                go.GroupSelect = true;
                go.GetMultiple (1, 0);

                if (go.CommandResult ()! = Result.Success)
                {
                    return go.CommandResult ();
                }
              
                for (int i = 0; i <go.ObjectCount; i ++)
                {
                    objRef.Add (go.Object (i));
                }
            }

            foreach (var item in objRef)
            {
                if (doc.Objects.Find (item.ObjectId) is RhinoObject rhinoObject)
                {
                                     MeshingParameters meshingParameters = new MeshingParameters
                    {
                        Tolerance = 0.01,
                        MaximumEdgeLength = 5
                    };

                    rhinoObject.CreateMeshes (MeshType.Render, meshingParameters, true);
                  
                    }
                }
            }

            doc.Views.RedrawEnabled = true;
            doc.Views.Redraw ();

            return Result.Success;
        }

After I need to use the TriangulateMesh command using the Rhino C # API. If anyone has ideas on how to solve these problems, I will be very grateful in advance thanks))

With respect Dmitry))

I managed to make Mesh and Triangulate Mesh, but I don’t know how to call the NonManifoldMerge command in Rhino Api. How could this code be simplified? Thanks in advance))

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
doc.Views.RedrawEnabled = false;

        List<ObjRef> objRef = new List<ObjRef>();
        GetObject go = new GetObject();

        go.SetCommandPrompt("Select objects");
        go.GeometryFilter = ObjectType.Surface;
        go.GroupSelect = true;
        go.GetMultiple(1, 0);

        if (go.CommandResult() != Result.Success)
        {
            return go.CommandResult();
        }

        for (int i = 0; i < go.ObjectCount; i++)
        {
            if (doc.Objects.Find(go.Object(i).ObjectId) is RhinoObject rhinoObject)
            {
                MeshingParameters meshingParameters = new MeshingParameters
                {
                    Tolerance = 0.01,
                    MaximumEdgeLength = 8
                };

                Mesh[] meshes = Mesh.CreateFromBrep(go.Object(i).Brep(), meshingParameters);
                if (meshes == null || meshes.Length == 0)
                {
                    return Result.Failure;
                }

                Mesh brep_mesh = new Mesh();

                foreach (Mesh mesh in meshes)
                {
                    Mesh triangleMesh = Triangulate(mesh);
                    brep_mesh.Append(triangleMesh);
                }

                doc.Objects.AddMesh(brep_mesh);
                doc.Views.Redraw();
            }
        }

        doc.Views.RedrawEnabled = true;
        doc.Views.Redraw();

        return Result.Success;
    }

    private Mesh Triangulate(Mesh x)
    {
        int facecount = x.Faces.Count;
        for (int i = 0; i < facecount; i++)
        {
            var mf = x.Faces[i];
            if (mf.IsQuad)
            {
                double dist1 = x.Vertices[mf.A].DistanceTo(x.Vertices[mf.C]);
                double dist2 = x.Vertices[mf.B].DistanceTo(x.Vertices[mf.D]);
                if (dist1 > dist2)
                {
                    x.Faces.AddFace(mf.A, mf.B, mf.D);
                    x.Faces.AddFace(mf.B, mf.C, mf.D);
                }
                else
                {
                    x.Faces.AddFace(mf.A, mf.B, mf.C);
                    x.Faces.AddFace(mf.A, mf.C, mf.D);
                }
            }
        }

        var newfaces = new List<MeshFace>();
        foreach (var mf in x.Faces)
        {
            if (mf.IsTriangle) newfaces.Add(mf);
        }

        x.Faces.Clear();
        x.Faces.AddFaces(newfaces);
        return x;
    }

Hi @leusd100,

There is no SDK equivalent to what the NonmanifoldMerge command does. I can add something to the Rhino WIP if that help.

– Dale

Thanks for the quick response. If such a command does not exist in the Rhino API, but it works according to a certain algorithm. Could I implement the functionality of this command on my own? If possible, you could help implement this command.

Best regards, Dmitriy

Hi @leusd100,

Does this help?

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Brep_MergeBreps.htm

– Dale

Unfortunately, this did not help. Perhaps I was mistaken in something. By the way, the logic of the BolleanUnion command does not fit. NonmanifoldMerge is needed. Here is my code how MergeBreps implemented:

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
doc.Views.RedrawEnabled = false;

        List<ObjRef> objRef = new List<ObjRef>();
        GetObject go = new GetObject();

        go.SetCommandPrompt("Select objects");
        go.GeometryFilter = ObjectType.Surface;
        go.GroupSelect = true;
        go.GetMultiple(1, 0);

        if (go.CommandResult() != Result.Success)
        {
            return go.CommandResult();
        }

        List<Brep> listBreps = new List<Brep>();
        for (int i = 0; i < go.ObjectCount; i++)
        {
            if (doc.Objects.Find(go.Object(i).ObjectId) is RhinoObject rhinoObject)
            {
                listBreps.Add(go.Object(i).Brep());
            }
        }

        Brep.MergeBreps(listBreps, 1);
        foreach (var brep in listBreps)
        {
            MeshingParameters meshingParameters = new MeshingParameters
            {
                Tolerance = 0.01,
                MaximumEdgeLength = 8
            };

            Mesh[] meshes = Mesh.CreateFromBrep(brep, meshingParameters);
            if (meshes == null || meshes.Length == 0)
            {
                return Result.Failure;
            }

            Mesh brep_mesh = new Mesh();
            foreach (Mesh mesh in meshes)
            {
                Mesh triangleMesh = Triangulate(mesh);
                brep_mesh.Append(triangleMesh);
            }

            doc.Objects.AddMesh(brep_mesh);
            doc.Views.Redraw();
        }


        doc.Views.RedrawEnabled = true;
        doc.Views.Redraw();

        return Result.Success;
    }

    private Mesh Triangulate(Mesh x)
    {
        int facecount = x.Faces.Count;
        for (int i = 0; i < facecount; i++)
        {
            var mf = x.Faces[i];
            if (mf.IsQuad)
            {
                double dist1 = x.Vertices[mf.A].DistanceTo(x.Vertices[mf.C]);
                double dist2 = x.Vertices[mf.B].DistanceTo(x.Vertices[mf.D]);
                if (dist1 > dist2)
                {
                    x.Faces.AddFace(mf.A, mf.B, mf.D);
                    x.Faces.AddFace(mf.B, mf.C, mf.D);
                }
                else
                {
                    x.Faces.AddFace(mf.A, mf.B, mf.C);
                    x.Faces.AddFace(mf.A, mf.C, mf.D);
                }
            }
        }

        var newfaces = new List<MeshFace>();
        foreach (var mf in x.Faces)
        {
            if (mf.IsTriangle) newfaces.Add(mf);
        }

        x.Faces.Clear();
        x.Faces.AddFaces(newfaces);
        return x;
    }

Best regards, Dmitry

Thank you very much)) Everything worked out, I just made a mistake