Figure 12 shows an example surface that is submappable. The nodes on the boundary of the surface are used as input to the surface submapper. As shown in Figure 12, the outer loop is ordered counter-clockwise when viewed from a position down the positive normal of the surface and the inner loop(s) are ordered clockwise when viewed from the same position.
Figure 12: Submapper input
The following code snippets show how the CMLSurfSubMapper object is used to generate a submapped mesh on a surface.
// read input file int num_points = 0; int num_loops = 0; int *loop_sizes = NULL; // array allocated in read_loop_file double *points = NULL; // array allocated in read_loop_file if (!read_loop_file(num_points, points, num_loops, loop_sizes)) { exit(EXIT_FAILURE); }
First the input is generated. In this example the input is read from a file. For the surface in Figure 12, the total number of points, num_points, is 24 and the number of loops, num_loops, is 2. The points array holds all of the coordinates of the input points. The size of points is 3 * num_points. The array should be ordered as follows. The first 3 entries in the array will be the x, y, and z coordinates of the first point, the next 3 entries will be the x, y, and z coordinates of the second point, and so on. The loop_sizes array is a num_loops long. It holds the number of points in each loop. For the surface in Figure 12, the first entry in loop_sizes would be 18, and the second entry would be 6.
In this example, the submapper will compute the node types from the loops. Node types are used to find corners and break the surface loops into mappable regions. A node type can be either an end (interior angle of about 90 degrees), a side (interior angle of about 180 degrees), a corner (interior angle of about 270 degrees), or a reversal (interior angle of about 360 degrees). For the surface in Figure 12 nodes 1, 4, 8, 13, and 15 are of type end and nodes 17, 19, 21, 22, and 24 are of type corner. Again, these values will be computed internally.
// mesh the surface int *quads = NULL; int new_points = 0; int num_quads = 0; if (ret_value) { MySurfEval geom_eval; CMLSurfSubMapper surf_submapper(&geom_eval); ret_value = surf_submapper.set_boundary_mesh(num_points, points, num_loops, loop_sizes); if (!ret_value) { printf("Failed setting boundary mesh\n"); } // delete memory allocated in read_loop_file delete [] points; delete [] loop_sizes; points = NULL; // generate the mesh if (ret_value) { ret_value = surf_submapper.generate_mesh(new_points, num_quads); if (!ret_value) { printf("Failed generating mesh\n"); } }
The input is sent to CMLSurfSubMapper using the CMLSurfSubMapper::set_boundary_mesh() function. Then the mesh is generated by calling the CMLSurfSubMapper::generate_mesh() function.
// allocate memory to accept quad mesh and retrieve it if (ret_value) { quads = new int [num_quads * 4]; points = new double [new_points * 3]; if (quads == NULL || points == NULL) { printf("Failed allocating memory to receive mesh\n"); ret_value = false; } } if (ret_value) { ret_value = surf_submapper.get_mesh(new_points, points, num_quads, quads); if (!ret_value) { printf("Failed reading quad mesh\n"); }
This next part shows how the mesh is retrieved from CMLSurfSubMapper. Memory is allocated for the generated nodes and quads. For the example in Figure 12, new_points is 26 and num_quads is 14. Both of these values are returned during the call to CMLSurfSubMapper::generate_mesh(). The points array will hold the nodal coordinates of the resulting nodes and quads will hold the connectivity of the resulting quads. The format for points will be the same as for the input nodes.
The format for quads will be as follows. The first four entries in quads will be the indices of the nodes making up quad number 1, the second four entries in quads will be the indices of the nodes making up quad number 2, and so on. The node numbering for each quad will be counter-clockwise around the quad when looking from a positive position the surface normal. The nodes and quads are retrieved using the funciton CMLSurfSubMapper::get_mesh().
// write output file if (ret_value) { ret_value = write_quad_file(new_points, points, num_quads, quads); if (!ret_value) { printf("Failed writing quad mesh file\n"); } }
Finally, a call to write_quad_file() writes the quadrilateral mesh to an output file, deletes the allocated memory and exits. Figure 13 shows the resulting mesh for the example in Figure 12.
Figure 13: Submapper output
CAMAL 5.2-0 documentation created on 1 Jun 2010
Comments to csimsoft.com