Home > User Guide > Display and User Input > Faceting
Converting Code that Traverses Facet Vertices and Polygons in an INDEXED_MESH into Code that Traverses Facets in a LINKED_MESH
The following examples illustrate reading facet data from an INDEXED_MESH, and taking advantage of a higher performance faceter class. The newer class LINKED_MESH is a super-set of data that is contained in the older class INDEXED_MESH. When api_facet_entity uses LINKED_MESH_MANAGER instead of INDEXED_MESH_MANAGER, it performs significantly faster but results in a slightly larger memory footprint. A base class, SEQUENTIAL_MESH, was created to provide a common access to both classes. These examples are not only for those who wish to convert data using the faster LINKED_MESH class, but also serves as examples for those unfamiliar with the LINKED_MESH and the INDEXED_MESH classes.
This section contains snippets of C++ code to illustrate how to traverse facets in an INDEXED_MESH. These snippets are designed to be very simple starting points for developing your own code - they are not complete, compiling and runtime programs.
INDEXED_MESH code converted to LINKED_MESH code Example -2
The following function is an example of one of the ways to traverse facets in an INDEXED_MESH. This shows how to traverse the vertices first, then the polygons.
Note: To see how to traverse only the polygons, see Linked Mesh Example - 1.
void writeIndicesOfINDEXED_MESH(ENTITY * inEntity, FILE* fp) { // Get the transform on the body, if any. SPAtransf xform; ENTITY * owner; api_get_owner( inEntity, owner ); if ( is_BODY( owner ) ) { BODY * body; body = (BODY*)owner; if ( body->transform() ) xform = body->transform()->transform(); } ENTITY_LIST faceList; api_get_faces( inEntity, faceList ); // Loop through each face and print facet data for ( int faceIndex = 0; faceIndex < faceList.count(); faceIndex++ ) { FACE * face = (FACE*)faceList[faceIndex]; // Find the attribute for facets attached to the face. This is the mesh. MESH * face_mesh = NULL; af_query( (ENTITY*)face, IDX_MESH_APP, IDX_MESH_ID, face_mesh ); INDEXED_MESH *mesh = (INDEXED_MESH*)face_mesh; if (mesh && mesh->get_type_of_mesh() != INDEXED_MESH_TYPE) mesh = 0; if ( mesh == NULL ) { printf( "No indexed mesh available for face\n" ); continue; } // Get the number of nodes of the whole face int nodeCount = mesh->get_num_vertex(); fprintf( fp, "Face index: %d. Number of nodes for the whole face = %d\n", faceIndex, nodeCount); // Loop through each facet node and print its data for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) { SPAposition pos (mesh->get_position( nodeIndex )); SPAunit_vector vec (mesh->get_normal( nodeIndex )); SPApar_pos uv (mesh->get_uv_as_entered( nodeIndex )); pos *= xform; vec *= xform; fprintf(fp, " %d: (%g %g) (%g %g %g) (%g %g %g)\n", nodeIndex, (double)uv.u, (double)uv.v, pos.x(), pos.y(), pos.z(), vec.x(), vec.y(), vec.z()); } // Print the number of facets for this face int polygonCount = mesh->get_num_polygon(); fprintf( fp, "Face index: %d. Number of facets = %d\n", faceIndex, polygonCount ); // Loop through each facet and print its data (node indices) for ( int polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++ ) { // Get the facet's data as an indexed_polygon indexed_polygon *poly = mesh->get_polygon( polygonIndex ); if (poly) { // Print the number of nodes in this facet int nodeCount = poly->num_vertex(); fprintf( fp, " %d: %d:", polygonIndex, nodeCount ); // Print the node indices of this facet for ( int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++ ) { polygon_vertex* vert = poly->get_vertex( nodeIndex ); int index = mesh->get_vertex_index( vert ); fprintf( fp," %d", index ); } // Print which edge is shared with the next facet int ishare_edge = poly->get_share_info(); fprintf( fp," %d", ishare_edge ); fprintf( fp, "\n"); } } } // End braces for Loop through each face }The following example performs the same operation as the one above, but uses a SEQUENTIAL_MESH. This is the base class for both INDEXED_MESH and LINKED_MESH. Using a LINKED_MESH improves faceting performance.
void writeIndicesOfSEQUENTIAL_MESH( ENTITY * inEntity, FILE* fp ) { // Get the transform on the body, if any. SPAtransf xform; ENTITY * owner; api_get_owner( inEntity, owner ); if ( is_BODY( owner ) ) { BODY * body; body = (BODY *)owner; if (body->transform()) xform = body->transform()->transform(); } ENTITY_LIST faceList; api_get_faces( inEntity, faceList ); // Loop through each face and print facet data for ( int faceIndex = 0; faceIndex < faceList.count(); faceIndex++ ) { FACE * face = (FACE*)faceList[faceIndex]; // Find the attribute for facets attached to the face. This is the mesh. MESH * face_mesh = NULL; af_query( (ENTITY*)face, IDX_MESH_APP, IDX_MESH_ID, face_mesh ); if ( face_mesh == NULL ) { printf( "No indexed mesh or linked mesh available for a face\n" ); continue; } SEQUENTIAL_MESH *mesh = (SEQUENTIAL_MESH*)face_mesh; if ( !mesh ) continue; // Get the number of nodes of the whole face int nodeCount = mesh->get_num_node(); fprintf( fp, "Face index: %d. Number of nodes for the whole face = %d\n", faceIndex, nodeCount); // Loop through each facet node and print its data MESH_NODE meshNode; // Get the first node of the whole face if ( !mesh->get_first_node( meshNode ) ) continue; for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) { SPAposition pos ( mesh->get_position( meshNode ) ); SPAunit_vector vec ( mesh->get_normal( meshNode ) ); SPApar_pos uv; mesh->get_par_pos_surface( mesh->get_par_pos( meshNode ), uv ); pos *= xform; vec *= xform; fprintf( fp, " %d: (%g %g) (%g %g %g) (%g %g %g)\n", nodeIndex, (double)uv.u, (double)uv.v, pos.x(), pos.y(), pos.z(), vec.x(), vec.y(), vec.z() ); // Setup for the next loop by getting the next node of the whole face mesh->get_next_node( meshNode ); } // Print the number of facets for this face int polygonCount = mesh->get_num_polygon(); fprintf( fp, "Face index: %d. Number of facets = %d\n", faceIndex, polygonCount ); // Loop through each facet and print its data (node indices) MESH_POLYGON meshPolygon; // Get the handle of the first facet if ( !mesh->get_first_polygon( meshPolygon ) ) continue; for ( int polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++ ) { // Print the number of nodes in this facet int nodeCount = mesh->get_num_polynode( meshPolygon ); fprintf( fp, " %d: %d:", polygonIndex, nodeCount ); // Print the node indices of this facet MESH_POLYNODE meshPolynode; // Get the handle of the first node of this facet if ( !mesh->get_first_polynode( meshPolygon, meshPolynode ) ) continue; for ( int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++ ) { int index = mesh->get_node_index( meshPolynode ); fprintf( fp," %d", index ); // Setup for the next loop by getting the next node of the facet mesh->get_next_polynode( meshPolynode ); } // Print which edge is shared with the next facet int ishare_edge = mesh->get_share_info( meshPolygon ); fprintf( fp," %d", ishare_edge ); fprintf( fp, "\n" ); // Setup for the next loop by getting the next facet mesh->get_next_polygon( meshPolygon ); } } // End braces for Loop through each face }
Related topics:
Refinements
Mesh Managers
Step-by-Step Faceting
Discarding or Keeping Facet Data
Faceting Functions and Classes
Faceting Using Scheme[Top]
© 1989-2007 Spatial Corp., a Dassault Systèmes company. All rights reserved.