MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 // Brandon Smith 00002 // January 20, 2009 00003 00004 /* 00005 loop over all surface meshsets 00006 get all quads of surface meshset 00007 loop over all quads 00008 make tris from quad 00009 add tris to the surface meshset 00010 remove quad from surface meshset 00011 delete quad 00012 end loop 00013 end loop 00014 */ 00015 00016 #include "quads_to_tris.hpp" 00017 #include "moab/CartVect.hpp" 00018 using namespace moab; 00019 00020 // Generic function to create two tris from a quad. This can be improved later. 00021 ErrorCode make_tris_from_quad( Interface* MBI, EntityHandle quad, /* input */ 00022 EntityHandle& tri0, /* output */ 00023 EntityHandle& tri1 /* output */ ) 00024 { 00025 00026 // get connectivity (ordered counterclockwise for 2D elements in MOAB) 00027 ErrorCode result; 00028 const EntityHandle* quad_conn; 00029 int n_verts = 0; 00030 result = MBI->get_connectivity( quad, quad_conn, n_verts ); 00031 assert( 4 == n_verts ); 00032 assert( MB_SUCCESS == result ); 00033 00034 // find length of diagonals 00035 std::vector< CartVect > coords( n_verts ); 00036 result = MBI->get_coords( quad_conn, n_verts, coords[0].array() ); 00037 if( MB_SUCCESS != result ) return result; 00038 CartVect diagA = coords[0] - coords[2]; 00039 double lenA_sqr = diagA.length_squared(); 00040 CartVect diagB = coords[1] - coords[3]; 00041 double lenB_sqr = diagB.length_squared(); 00042 00043 // choose the shortest diagonal 00044 EntityHandle tri0_conn[3], tri1_conn[3]; 00045 if( lenA_sqr < lenB_sqr ) 00046 { 00047 tri0_conn[0] = quad_conn[0]; 00048 tri0_conn[1] = quad_conn[1]; 00049 tri0_conn[2] = quad_conn[2]; 00050 tri1_conn[0] = quad_conn[0]; 00051 tri1_conn[1] = quad_conn[2]; 00052 tri1_conn[2] = quad_conn[3]; 00053 } 00054 else 00055 { 00056 tri0_conn[0] = quad_conn[0]; 00057 tri0_conn[1] = quad_conn[1]; 00058 tri0_conn[2] = quad_conn[3]; 00059 tri1_conn[0] = quad_conn[1]; 00060 tri1_conn[1] = quad_conn[2]; 00061 tri1_conn[2] = quad_conn[3]; 00062 } 00063 00064 // make tris from quad 00065 result = MBI->create_element( MBTRI, tri0_conn, 3, tri0 ); 00066 assert( MB_SUCCESS == result ); 00067 result = MBI->create_element( MBTRI, tri1_conn, 3, tri1 ); 00068 assert( MB_SUCCESS == result ); 00069 00070 return MB_SUCCESS; 00071 } 00072 00073 ErrorCode make_tris_from_quads( Interface* MBI, const Range quads, Range& tris ) 00074 { 00075 tris.clear(); 00076 for( Range::const_iterator i = quads.begin(); i != quads.end(); ++i ) 00077 { 00078 EntityHandle tri0, tri1; 00079 ErrorCode result = make_tris_from_quad( MBI, *i, tri0, tri1 ); 00080 assert( MB_SUCCESS == result ); 00081 if( MB_SUCCESS != result ) return result; 00082 tris.insert( tri0 ); 00083 tris.insert( tri1 ); 00084 } 00085 return MB_SUCCESS; 00086 } 00087 00088 ErrorCode quads_to_tris( Interface* MBI, EntityHandle input_meshset ) 00089 { 00090 00091 // create a geometry tag to find the surfaces with 00092 ErrorCode result; 00093 Tag geom_tag, id_tag; 00094 result = MBI->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_DENSE | MB_TAG_CREAT ); 00095 if( MB_SUCCESS != result ) return result; 00096 00097 // create an id tag to find the surface id with 00098 id_tag = MBI->globalId_tag(); 00099 00100 // get all surface meshsets 00101 Range surface_meshsets; 00102 int dim = 2; 00103 void* input_dim[] = { &dim }; 00104 result = MBI->get_entities_by_type_and_tag( input_meshset, MBENTITYSET, &geom_tag, input_dim, 1, surface_meshsets ); 00105 assert( MB_SUCCESS == result ); 00106 std::cout << surface_meshsets.size() << " surfaces found." << std::endl; 00107 00108 // ****************************************************************** 00109 // Loop over every surface meshset and grab each surface's quads. 00110 // ****************************************************************** 00111 for( Range::iterator i = surface_meshsets.begin(); i != surface_meshsets.end(); ++i ) 00112 { 00113 00114 // get the surface id of the surface meshset 00115 int surf_id = 0; 00116 result = MBI->tag_get_data( id_tag, &( *i ), 1, &surf_id ); 00117 assert( MB_SUCCESS == result ); 00118 std::cout << " Surface " << surf_id << " has "; 00119 00120 // get all quads of the surface 00121 Range quads; 00122 result = MBI->get_entities_by_type( *i, MBQUAD, quads ); 00123 assert( MB_SUCCESS == result ); 00124 std::cout << quads.size() << " quads." << std::endl; 00125 00126 // ****************************************************************** 00127 // For each quad, make two triangles then delete the quad. 00128 // ****************************************************************** 00129 for( Range::iterator j = quads.begin(); j != quads.end(); ++j ) 00130 { 00131 00132 // make the tris 00133 EntityHandle tri0 = 0, tri1 = 0; 00134 result = make_tris_from_quad( MBI, *j, tri0, tri1 ); 00135 assert( MB_SUCCESS == result ); 00136 00137 // add all the tris to the same surface meshset as the quads were inside. 00138 result = MBI->add_entities( *i, &tri0, 1 ); 00139 if( MB_SUCCESS != result ) std::cout << "result=" << result << std::endl; 00140 assert( MB_SUCCESS == result ); 00141 result = MBI->add_entities( *i, &tri1, 1 ); 00142 assert( MB_SUCCESS == result ); 00143 00144 // remove the quad from the surface meshset 00145 result = MBI->remove_entities( *i, &( *j ), 1 ); 00146 assert( MB_SUCCESS == result ); 00147 00148 // delete the quad 00149 result = MBI->delete_entities( &( *j ), 1 ); 00150 assert( MB_SUCCESS == result ); 00151 00152 } // end quad loop 00153 } // end surface meshset loop 00154 return MB_SUCCESS; 00155 }