Mesh the Polysurface C++


#1

Hi,

I would like to mesh polysurfaces automatically. I have seen the “How To: Mesh Objects using RhinoMeshObjects” example…but if I already have an ON_Brep, it seems a bit much to generate a CRhinoObject from it just to mesh it. So i thought of using the CreateMesh function of the ON_Brep class. But, this gives me separate meshes for separate Brep faces…and i need just one mesh for the entire polysurface…

How do I do this? Do I have to resort to the CRhinoObject solution? Should I use the CreateMesh and join somehow the meshes afterwards? Is there some setting in the ON_MeshParameters to export a single mesh?

Thanks!
Milos


(Dale Fugier) #2

Hi Milos,

After creating the meshes, using ON_Brep::CreateMesh, you need to set each mesh piece on the corresponding face using ON_BrepFace::SetMesh. Here is a simple example:

https://github.com/mcneel/Rhino5Samples_CPP/blob/master/SampleCommands/cmdSampleBrepBoxWithMesh.cpp


#3

Hi Dale,

thanks, but I don`t understand. In this example brep object is drawn at the end. Where is my final (joined) mesh? Is the idea to use CRhinoBrepObject and mesh it following the “How To: Mesh Objects using RhinoMeshObjects” example?


(Dale Fugier) #4

Hmm, not sure how I misread your post. Oh well, this is how you join mesh pieces into a single mesh:

ON_SimpleArray<ON_Mesh*> meshes( brep->m_F.Count() );
int mesh_count = brep->CreateMesh( mp, meshes );
if( mesh_count == brep->m_F.Count() )
{
  ON_Mesh* joined_mesh = new ON_Mesh( *meshes[0] );
  for( int i = 1; i < meshes.Count(); i++ )
    joined_mesh->Append( *meshes[i] );

  // TODO: Do something with joined_mesh

  delete joined_mesh; // Don't leak...
}

#5

Thanks Dale,

this works…but the final product is still not what i want, so i hope i can ask you two more short questions:

  1. I would like a “solid”…clean mesh. No double points or edges. When drawing, I would do Weld Vertices… is there a function for that?

  2. I very often use SelNakedMeshEdgePt, cause it is important to identify the edge of the mesh…is there a function for this? Or some ON_Mesh member that holds this information?

Thanks!
Milos


#6

…I am going to try and answer my questions so I can ask another quick one.

I am guessing that RhinoWeldMesh is the solution for welding?..and I am guessing the NakedMeshEdge secret is hidden in the “mesh_edge.m_topf_count” like in the Create a Bounding Polyline of a Mesh Object example?

The new short question I have is about ON_MeshParameters mp settings, I have been playing with it and it mostly works fine…except for some parameters, one of them is mp.m_face_type. It just doesn`t care if I put 0,1 or 2…it always does what it wants (usually mixed quads and triangles).
I also noticed that if I do mp = mp.FastRenderMesh, it doesn’t matter what mp parameters i change afterwards( grid count, edge length, …), they are not considered.


(Dale Fugier) #7

Yep[quote=“dimcic, post:6, topic:6289”]
I am guessing the NakedMeshEdge secret is hidden in the “mesh_edge.m_topf_count”…
[/quote]

This should do the trick:

const ON_MeshTopology& top = pMesh->Topology();
if( top.TopEdgeCount() > 0 )
{
  int b, c, d;
  for( b = 0; b < top.m_tope.Count(); b++ )
  {
    const ON_MeshTopologyEdge& tope = top.m_tope[b];
    for( c = 0; c < 2; c++ )
    {
      const ON_MeshTopologyVertex& topv = top.m_topv[ tope.m_topvi[c] ];
      if( tope.m_topf_count == 1 || topv.m_v_count > 1 )
      {
        for( d = 0; d < topv.m_v_count; d++ )
        {
          int vi = topv.m_vi[d];
          // TODO...
        }
      }
    }
  }
}
```[quote="dimcic, post:6, topic:6289"]
The new short question I have is about ON_MeshParameters...
[/quote]

Yes, some of the mesh parameters are interpreted a little differently in V5. This was necessary in order to improve meshing (and to fix some bugs) without breaking the SDK. If you are unable to produce the mesh you want (where you could in V4), then please provide me some sample geometry and code. Note, you might want to move this to a new topic, as I believe the original topic has been answered.

#8

Thanks!

About the mesh, as I said…m_face_type does not make any difference. I made a test command that I use to select a brep and then:

ON_MeshParameters mp;
mp.m_grid_amplification = 50;
mp.m_face_type = 2;

int ui_style = 0; // simple ui

ON_SimpleArray<ON_Mesh*> mesh_list;

brep->CreateMesh(mp, mesh_list);

	for(i=0; i<mesh_list.Count();i++)
		context.m_doc.AddMeshObject(*mesh_list[i]);

	//Delete the meshes
	for(i=0; i<mesh_list.Count();i++)
	{
		delete mesh_list[i];
		mesh_list[i] = 0;
	}

…and that’s its…I try changing m_face_type giving it 0,1 or 2…but it doesn’t affect the result (which is usually a combination of triangles and quads)


(Dale Fugier) #9

Rhino will try its best to use the mesh parameters. But there are occasions where the mesher needs to deviate from what has been specified in order to generate a valid mesh. If you need quads or triangles, you can always call ON::ConvertQuadsToTriangles or ON_Mesh::ConvertTrianglesToQuads after the fact.