cgma
|
00001 00002 #undef NDEBUG 00003 #include <cassert> 00004 00005 #include "GeometryModifyTool.hpp" 00006 #include "GeometryQueryTool.hpp" 00007 #include "ModelQueryEngine.hpp" 00008 #include "RefVertex.hpp" 00009 #include "RefEdge.hpp" 00010 #include "RefFace.hpp" 00011 #include "Body.hpp" 00012 #include "AppUtil.hpp" 00013 #include "Loop.hpp" 00014 #include "CoEdge.hpp" 00015 #include "InitCGMA.hpp" 00016 00017 #include <algorithm> 00018 00019 00020 /* Check that CGM's presentation of the modeler topology 00021 is correct by creating a simple cube and checking that 00022 everything is correctly connected. 00023 */ 00024 00025 00026 #ifndef TEST_ENGINE 00027 # define TEST_ENGINE 0 00028 #endif 00029 00030 void check_valid_edge( RefEdge* edge ); 00031 void check_valid_face( RefFace* face ); 00032 void check_valid_loop( Loop* loop ); 00033 00034 int main( int argc, char* argv[] ) 00035 { 00036 // Start up CGM 00037 CubitStatus result = InitCGMA::initialize_cgma(TEST_ENGINE); 00038 if (CUBIT_SUCCESS != result) return 1; 00039 00040 // Create a brick 00041 Body* brick = GeometryModifyTool::instance()->brick( 2, 2, 2 ); 00042 assert(brick != 0); 00043 00044 // Get all child RefEntities 00045 DLIList<TopologyEntity*> query_results; 00046 DLIList<RefFace*> surfaces; 00047 DLIList<RefEdge*> curves; 00048 DLIList<RefVertex*> points; 00049 00050 ModelQueryEngine::instance()->query_model( *brick, DagType::ref_face_type(), query_results ); 00051 CAST_LIST( query_results, surfaces, RefFace ); 00052 query_results.clean_out(); 00053 ModelQueryEngine::instance()->query_model( *brick, DagType::ref_edge_type(), query_results ); 00054 CAST_LIST( query_results, curves, RefEdge ); 00055 query_results.clean_out(); 00056 ModelQueryEngine::instance()->query_model( *brick, DagType::ref_vertex_type(), query_results ); 00057 CAST_LIST( query_results, points, RefVertex ); 00058 query_results.clean_out(); 00059 00060 // Check expected number of child RefEntities 00061 assert( surfaces.size() == 6 ); 00062 assert( curves.size() == 12 ); 00063 assert( points.size() == 8 ); 00064 00065 // Cube should be 2x2x2 and centered at origin, so each vertex 00066 // should have the coords (+/-1, +/-1, +/-1). Check that this 00067 // is the case and put vertex pointers in an array in the canonical 00068 // order for hexahedra. 00069 RefVertex* corners[8] = { 0, 0, 0, 0, 0, 0, 0, 0}; 00070 for (int i = 0; i < points.size(); ++i) { 00071 RefVertex* vtx = points.get_and_step(); 00072 CubitVector pos = vtx->coordinates(); 00073 // all coordinate values are plus or minus one 00074 assert( fabs(fabs(pos.x()) - 1) < 1e-12 ); 00075 assert( fabs(fabs(pos.y()) - 1) < 1e-12 ); 00076 assert( fabs(fabs(pos.z()) - 1) < 1e-12 ); 00077 int idx; 00078 if (pos.x() < 0) 00079 idx = pos.y() < 0 ? 0 : 3; 00080 else 00081 idx = pos.y() < 0 ? 1 : 2; 00082 if (pos.z() > 0) 00083 idx += 4; 00084 // No duplicate vertices allowed 00085 assert( corners[idx] == 0 ); 00086 corners[idx] = vtx; 00087 } 00088 00089 // Now figure out which of the 12 edges each RefEdge is by 00090 // checking the position of each attached vertex in the 00091 // above 'corners' array, Put edge pointers in an array in 00092 // the canonical edge order for a heaxahedron. 00093 RefEdge* edges[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 00094 for (int i = 0; i < curves.size(); ++i) { 00095 RefEdge* edge = curves.get_and_step(); 00096 int start_i = std::find( corners, corners + 8, edge->start_vertex() ) - corners; 00097 int end_i = std::find( corners, corners + 8, edge->end_vertex() ) - corners; 00098 assert( start_i < 8 ); 00099 assert( end_i < 8 ); 00100 int idx; 00101 // If edge is lateral edge from bottom face to top 00102 if (start_i < 4 && end_i >= 4) { 00103 idx = start_i + 4; 00104 assert( end_i == idx ); 00105 } 00106 // If edge is lateral edge from top face to bottom 00107 else if (start_i >= 4 && end_i < 4) { 00108 idx = end_i + 4; 00109 assert( start_i == idx ); 00110 } 00111 // If edge is part of bottom face 00112 else if (start_i < 4) { 00113 if ((start_i + 1)%4 == end_i) 00114 idx = start_i; 00115 else if ((end_i + 1)%4 == start_i) 00116 idx = end_i; 00117 else 00118 assert( false ); 00119 } 00120 // If edge is part of top face 00121 else { 00122 if ((start_i - 3) % 4 + 4 == end_i) 00123 idx = start_i + 4; 00124 else if ((end_i - 3) % 4 + 4 == start_i) 00125 idx = end_i + 4; 00126 else 00127 assert( false ); 00128 } 00129 // Check no duplicate edges 00130 assert( 0 == edges[idx] ); 00131 edges[idx] = edge; 00132 } 00133 00134 // Face connectivity, specified by edge numbers 00135 int std_faces[6][4] = { { 0, 5, 8, 4 }, 00136 { 1, 6, 9, 5 }, 00137 { 2, 7, 10, 6 }, 00138 { 3, 4, 11, 7 }, 00139 { 3, 2, 1, 0 }, 00140 { 8, 9, 10,11 } }; 00141 RefFace* faces[6] = { 0, 0, 0, 0, 0, 0 }; 00142 DLIList< DLIList<RefEdge*> > loops; 00143 for (int i = 0; i < surfaces.size(); ++i) { 00144 // get ref edges 00145 RefFace* face = surfaces.get_and_step(); 00146 face->ref_edge_loops( loops ); 00147 assert( loops.size() == 1 ); 00148 DLIList<RefEdge*> loop(loops.get()); 00149 //delete loops.get(); 00150 loops.clean_out(); 00151 00152 // match loop of edges to one of the expected faces 00153 assert( loop.size() == 4 ); 00154 int k; 00155 for (k = 0; k < 6; ++k) { 00156 int j; 00157 for (j = 0; j < 4; ++j) 00158 if (!loop.is_in_list(edges[std_faces[k][j]])) 00159 break; 00160 if (j == 4) 00161 break; 00162 } 00163 assert( k < 6 ); // fail of didn't match any expected face 00164 assert(0 == faces[k]); // no duplicates 00165 faces[k] = face; 00166 } 00167 00168 for (int i = 0; i < 12; ++i) 00169 check_valid_edge( edges[i] ); 00170 for (int i = 0; i < 6; ++i) 00171 check_valid_face( faces[i] ); 00172 for (int i = 0; i < 6; ++i) { 00173 assert(faces[i]->number_of_Loops() == 1); 00174 check_valid_loop( dynamic_cast<Loop*>(faces[i]->get_first_grouping_entity_ptr()) ); 00175 } 00176 00177 return 0; 00178 } 00179 00180 void check_valid_edge( RefEdge* edge ) 00181 { 00182 // Check that start and end vertices are in the correct order 00183 // by comparing vertex coordinates to edge position from start 00184 // and end parameters. 00185 double start_u, end_u; 00186 edge->get_param_range( start_u, end_u ); 00187 CubitStatus s; 00188 CubitVector start_p, end_p; 00189 s = edge->position_from_u( start_u, start_p ); 00190 assert(CUBIT_SUCCESS == s); 00191 assert( (start_p - edge->start_vertex()->coordinates()).length() < 1e-6 ); 00192 s = edge->position_from_u( end_u, end_p ); 00193 assert(CUBIT_SUCCESS == s); 00194 assert( (end_p - edge->end_vertex()->coordinates()).length() < 1e-6 ); 00195 00196 // Check reverse query from vertex to edge brings us back to the 00197 // input edge. 00198 DLIList<RefEntity*> ents; 00199 edge->start_vertex()->get_parent_ref_entities( ents ); 00200 assert( ents.is_in_list( edge ) ); 00201 ents.clean_out(); 00202 edge->end_vertex()->get_parent_ref_entities( ents ); 00203 assert( ents.is_in_list( edge ) ); 00204 } 00205 00206 void check_valid_face( RefFace* face ) 00207 { 00208 DLIList<RefEntity*> edges, parents; 00209 face->get_child_ref_entities( edges ); 00210 00211 double u_min, u_max, v_min, v_max, u, v; 00212 if (face->is_parametric()) { 00213 face->get_param_range_U( u_min, u_max ); 00214 face->get_param_range_V( v_min, v_max ); 00215 } 00216 00217 // Check that each edge is on the face 00218 for (int i = 0; i < edges.size(); ++i) { 00219 RefEdge* edge = dynamic_cast<RefEdge*>(edges.get_and_step()); 00220 assert(!!edge); 00221 00222 // Get three points to sample at 00223 CubitVector p[3]; 00224 p[0] = edge->start_vertex()->coordinates(); 00225 p[1] = edge->center_point(); 00226 p[2] = edge->end_vertex()->coordinates(); 00227 00228 // For each sample point 00229 for (int j = 0; j < 3; ++j) { 00230 // Check that point is on geometric surface 00231 CubitVector close(p[j]); 00232 face->move_to_surface( close ); 00233 assert( (close - p[j]).length() < 1e-6 ); 00234 // Check that point is within UV bounds 00235 if (face->is_parametric()) { 00236 CubitStatus s = face->u_v_from_position( p[j], u, v ); 00237 assert( CUBIT_SUCCESS == s ); 00238 assert( (u - u_min) > -1e-6 ); 00239 assert( (u_max - u) > -1e-6 ); 00240 assert( (v - v_min) > -1e-6 ); 00241 assert( (v_max - v) > -1e-6 ); 00242 } 00243 } 00244 } 00245 00246 00247 // Check reverse query from edge to face brings us back to the 00248 // input face. 00249 for (int i = 0; i < edges.size(); ++i) { 00250 parents.clean_out(); 00251 RefEntity* edge = edges.get_and_step(); 00252 edge->get_parent_ref_entities( parents ); 00253 assert( parents.is_in_list( face ) ); 00254 } 00255 } 00256 00257 // Check that coedges in loop chare expected vertices. 00258 void check_valid_loop( Loop* loop ) 00259 { 00260 DLIList<CoEdge*> coedges; 00261 loop->ordered_co_edges( coedges ); 00262 CoEdge* prev = coedges.get_and_step(); 00263 for (int i = 0; i < coedges.size(); ++i) { 00264 CoEdge* curr = coedges.get_and_step(); 00265 RefVertex* common_1 = prev->get_sense() == CUBIT_REVERSED ? 00266 prev->get_ref_edge_ptr()->start_vertex() : 00267 prev->get_ref_edge_ptr()->end_vertex() ; 00268 RefVertex* common_2 = curr->get_sense() == CUBIT_REVERSED ? 00269 curr->get_ref_edge_ptr()->end_vertex() : 00270 curr->get_ref_edge_ptr()->start_vertex(); 00271 assert( common_1 == common_2 ); 00272 prev = curr; 00273 } 00274 } 00275 00276 00277 00278 00279