cgma
brick.cpp
Go to the documentation of this file.
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     
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines