Failed to create closed mesh with Mesh.CreateFromBrep(brep, meshing_params) +.., while sucessfull with rhino command _Mesh

Hello. I’m found different result when trying to create brep with my code and with rhino command _Mesh.

  1. When I select closed surface and make mesh with my code, I got mesh wit at least 36 naked edges (depending on meshing parameters I set)
  2. But when I make mesh by using rhino command _Mash, I get closed mesh
  3. When I try to mesh same closed surface with Grasshopper (using Mesh Brep component together with Custom Mesh Settings component) I again get open mesh.

Both operation 1. and 3. produce open mesh probbaly because Grashhopper is using RhinnoCommon, the same as my code. Rhino _Mesh command is probably doing the same job different way.
Any suggestion how to get closed mesh with C# code from supplied closed surfice?

My surfice is here: 619-40E_2.3dm

And part of of C# code is here:

   public static class MyBrepToMesh
    {
        public static Result convertBrepToMesh(RhinoDoc doc, bool appendToDoc)
        {
            // Select objects to mesh
            using (GetObject go = new GetObject())
            {
                go.SetCommandPrompt("Select objects to creat mesh :");
                go.SubObjectSelect = false;
                go.GroupSelect = true;
                //go.GeometryFilter = Rhino.DocObjects.ObjectType.Brep ;
                go.GeometryFilter = ObjectType.Surface | ObjectType.PolysrfFilter;
                go.GetMultiple(1, 0);
                if (go.CommandResult() != Result.Success)
                    return go.CommandResult();
                
                // Read custom meshing parameters from opened Rhino doc
                var meshing_params = doc.GetMeshingParameters(MeshingParameterStyle.Custom);
                // ..modify custom meshing prms in my from
                var customMeshingPropForm = new CustomMeshingPropertiesForm(meshing_params, doc);
                var dialog_result = customMeshingPropForm.ShowDialog(RhinoApp.MainWindow());
                if (dialog_result != DialogResult.OK)
                    return Result.Cancel;
                // ..and save them back to doc for later use in opened Rhino doc
                doc.SetCustomMeshingParameters(meshing_params);

                for (int i = 0; i < go.ObjectCount; i++)
                {
                    var brep = go.Object(i).Brep();
                    var meshes = Mesh.CreateFromBrep(brep, meshing_params);
                    var newJoinedMesh= JoinMeshes(meshes);
                    if (appendToDoc)
                        doc.Objects.AddMesh(newJoinedMesh);
                }
            }
            doc.Views.Redraw();
            return Result.Success ;
        }

        public static Mesh JoinMeshes(Mesh[] meshes)
        {
            var brep_mesh = new Mesh();
            if (meshes != null & meshes.Length > 0)
            {
                foreach (var mesh in meshes)
                {
                    brep_mesh.Append(mesh);
                }
            }
            return brep_mesh;
        }
    }

In this link below, the meshing parameters are explained and their names are linked to the names in the Mesh command. Make sure that each value is exactly the same in the Mesh command and in your plug-in command (note the angle in rad for example) and try again. It should give the same result, independent of whether you run the Mesh command from Rhino or from your plugin command.

Unfortunately, I can not create closed mash from supplied closed surface by using C# and RhinoCommon Mesh.CreateFromBrep(brep, meshing_params) method.
I organised that part of code in small project/assembly, with plugin “MyTools.rhp” created in \bin folder. Project is here: MyTools Project (VS_2015 )
After instaling plugin you will have new rhino command “myBrepToMesh” which:

  1. asks you to select surfaces to mesh,
  2. after that runs form where you can modity ALL meshing parameters
  3. and than creates mesh using modified mesh parameters
    Whatever parameters I try to set, resulting mesh from supplied surface is NOT CLOSED.
    On the other hand when I use rhino Mash command on same surface resulting mesh is closed (and litle bit different than generated with my code).
    It must be something with the way Rhino Mash command is generatidng mesh.
    Any suggestions how to get closed mesh from supplied surface with C# and RhinoCommon?

Very weird indeed. I don’t see where the difference is. Maybe @dale can help here?

Yes, it is weird. But the same weird result (Not Colsed mesh) I got when I use Grasshopper (using Mesh Brep component together with Custom Mesh Settings component).
It would be nice if somebody has an idea how to get the same result with C# and Rhinocommon as when using rhinocommand _Mesh. When using _Mesh command on supplied surface, I always get closed mesh reardless of mesh settings!!!

Yep I see the problem - thanks for pointing this out. I’ve added a YouTrack item to make sure this is fixed for Rhino 6:

http://mcneel.myjetbrains.com/youtrack/issue/RH-35007

The problem is that Mesh.CreateFromBrep is not calling a post-meshing healing function that ensures that meshes that are supposed to be closed are really closed. The Mesh command does this, of course.

Which begs the question: Does RhinoCommon have the healing function separately?

I had a similar (same?) problem a while ago and I made my own healing function. It is in C++ however, not RhinoCommon.

No, there is not. I hope to get the existing Mesh.CreateFromBrep tuned up in the Rhino WIP as soon as I can.

I’ve checked in some fixes for this that will appear in next week’s WIP release.

Note, this fix will not appear in Rhino 5.

I’ve added a new {MeshingParameters.ClosedObjectPostProcess property that controls whether or not meshes that should be closed are “healed” as a post process. This property has some good comments that are worth reading.

But in a nutshell, you can use this property as follows:

var mp = MeshingParameters.FastRenderMesh;
mp.JaggedSeams = false;
mp.ClosedObjectPostProcess = true;

var meshes = Mesh.CreateFromBrep(brep, mp);

if (meshes != null && meshes.Length > 0)
{
  var brep_mesh = new Mesh();
  foreach (var m in meshes)
    brep_mesh.Append(m);

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

– Dale

2 Likes

@menno, here is the C++ equivalent:

ON_MeshParameters mp = ON_MeshParameters::FastRenderMesh;
mp.SetJaggedSeams(false);
mp.SetClosedObjectPostProcess(true);

ON_SimpleArray<ON_Mesh*> meshes(brep->m_F.Count());
brep->CreateMesh(mp, meshes);
1 Like

RH-35007 is fixed in the latest WIP

This code works smoothly. Thank you, Dale.