Adding Mesh Objects
Windows only
Overview
To create an ON_Mesh
:
- Create the
ON_Mesh
object. The constructor requires the number of faces and vertices, and whether or not you have vertex normals or texture coordinates. - Fill in the mesh vertex array,
ON_Mesh::m_V
. You can also useON_Mesh::SetVertex
. - Fill in the mesh faces array,
ON_Mesh::m_F
. You can also useON_Mesh::SetTriangle
andON_Mesh::SetQuad
. - If you have vertex normals, fill in the normals array,
ON_Mesh::m_N
. You can also useON_Mesh::SetVertexNormal
. - If you have texture coordinates, fill in the texture coordinate array,
ON_Mesh::m_T
. You can also useON_Mesh::SetTextureCoordinate
. - If you did not specify vertex normals, have Rhino compute them for you using
ON_Mesh::ComputeVertexNormals()
. - Clean up everything using
ON_Mesh::Compact
.
You are now ready to add this mesh object to the document. The opennurbs_mesh.h header file is well documented. It’s worth reading through at least once.
Example
CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context ) { // Example demonstrates how to create a mesh and add it to Rhino // Create a mesh to write. // The mesh is a pyramid with 4 triangular sides and a quadranglar // base. The mesh has 5 vertices and 5 faces. // The side faces share normals at their common vertices. The // quadrangular base has normals different from the side normal. // Coincident vertices that have distinct normals must be // duplicated in the vertex list. // // The apex will be at (1,1.5,4) with normal (0,0,1). // The base corners will be at (0,0,0), (0,2,0), (2,3,0), (0,3,0). bool bHasVertexNormals = true; // we will specify vertex normals bool bHasTexCoords = false; // we will not specify texture coordinates const int vertex_count = 5+4; // 4 duplicates for different base normals const int face_count = 5; // 4 triangle sides and a quad base ON_Mesh mesh( face_count, vertex_count, bHasVertexNormals, bHasTexCoords ); // The SetVertex(), SetNormal(), SetTCoord() and SetFace() functions // return true if successful and false if input is illegal. It is // a good idea to inspect this returned value. // vertex #0: apex location and normal mesh.SetVertex( 0, ON_3dPoint(1.0, 1.5, 5.0) ); mesh.SetVertexNormal( 0, ON_3dVector(0.0, 0.0, 1.0) ); // vertex #1: SW corner vertex for sides mesh.SetVertex( 1, ON_3dPoint(0.0, 0.0, 0.0) ); mesh.SetVertexNormal( 1, ON_3dVector(-1.0, -1.0, 0.0) ); // set normal will unitize if needed // vertex #2: SE corner vertex for sides mesh.SetVertex( 2, ON_3dPoint(2.0, 0.0, 0.0) ); mesh.SetVertexNormal( 2, ON_3dVector(+1.0, -1.0, 0.0) ); // vertex #3: NE corner vertex for sides mesh.SetVertex( 3, ON_3dPoint(2.0, 3.0, 0.0) ); mesh.SetVertexNormal( 3, ON_3dVector(+1.0, +1.0, 0.0) ); // vertex #4: NW corner vertex for sides mesh.SetVertex( 4, ON_3dPoint(0.0, 3.0, 0.0) ); mesh.SetVertexNormal( 4, ON_3dVector(-1.0, +1.0, 0.0) ); // vertex #5: SW corner vertex for base mesh.SetVertex( 5, ON_3dPoint(0.0, 0.0, 0.0) ); // == location of v1 mesh.SetVertexNormal( 5, ON_3dVector(0.0, 0.0, -1.0) ); // vertex #6: SE corner vertex for base mesh.SetVertex( 6, ON_3dPoint(2.0, 0.0, 0.0) ); // == location of v2 mesh.SetVertexNormal( 6, ON_3dVector(0.0, 0.0, -1.0) ); // vertex #7: SW corner vertex for base mesh.SetVertex( 7, ON_3dPoint(2.0, 3.0, 0.0) ); // == location of v3 mesh.SetVertexNormal( 7, ON_3dVector(0.0, 0.0, -1.0) ); // vertex #8: SW corner vertex for base mesh.SetVertex( 8, ON_3dPoint(0.0, 3.0, 0.0) ); // == location of v4 mesh.SetVertexNormal( 8, ON_3dVector(0.0, 0.0, -1.0) ); // Faces have vertices ordered counter-clockwise // South side triangle mesh.SetTriangle( 0, 1, 2, 0 ); // East side triangle mesh.SetTriangle( 1, 2, 3, 0 ); // North side triangle mesh.SetTriangle( 2, 3, 4, 0 ); // West side triangle mesh.SetTriangle( 3, 4, 1, 0 ); // last face is quadrangular base mesh.SetQuad( 4, 5, 8, 7, 6 ); ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// if( mesh.IsValid() ) { // Most applications expect vertex normals. // If they are not present, ComputeVertexNormals sets // them by averaging face normals. if ( !mesh.HasVertexNormals() ) mesh.ComputeVertexNormals(); context.m_doc.AddMeshObject( mesh ); context.m_doc.Redraw(); } return success; }
Here is another example:
CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context) { int face_count = 6; int vertex_count = 12; BOOL bVertexNormals = FALSE; BOOL bTextureCoordinates = FALSE; ON_Mesh mesh( face_count, vertex_count, bVertexNormals, bTextureCoordinates ); mesh.SetVertex( 0, ON_3fPoint(0.0f, 0.0f, 1.0f) ); mesh.SetVertex( 1, ON_3fPoint(1.0f, 0.0f, 1.0f) ); mesh.SetVertex( 2, ON_3fPoint(2.0f, 0.0f, 1.0f) ); mesh.SetVertex( 3, ON_3fPoint(3.0f, 0.0f, 0.0f) ); mesh.SetVertex( 4, ON_3fPoint(0.0f, 1.0f, 1.0f) ); mesh.SetVertex( 5, ON_3fPoint(1.0f, 1.0f, 2.0f) ); mesh.SetVertex( 6, ON_3fPoint(2.0f, 1.0f, 1.0f) ); mesh.SetVertex( 7, ON_3fPoint(3.0f, 1.0f, 0.0f) ); mesh.SetVertex( 8, ON_3fPoint(0.0f, 2.0f, 1.0f) ); mesh.SetVertex( 9, ON_3fPoint(1.0f, 2.0f, 1.0f) ); mesh.SetVertex( 10, ON_3fPoint(2.0f, 2.0f, 1.0f) ); mesh.SetVertex( 11, ON_3fPoint(3.0f, 2.0f, 1.0f) ); mesh.SetQuad( 0, 0, 1, 5, 4 ); mesh.SetQuad( 1, 1, 2, 6, 5 ); mesh.SetQuad( 2, 2, 3, 7, 6 ); mesh.SetQuad( 3, 4, 5, 9, 8 ); mesh.SetQuad( 4, 5, 6, 10, 9 ); mesh.SetQuad( 5, 6, 7, 11, 10 ); mesh.ComputeVertexNormals(); mesh.Compact(); context.m_doc.AddMeshObject( mesh ); context.m_doc.Redraw(); return CRhinoCommand::success; }