[cgma-dev] r2800 - cgm/trunk/test

kraftche at cae.wisc.edu kraftche at cae.wisc.edu
Fri Apr 3 16:04:40 CDT 2009


Author: kraftche
Date: 2009-04-03 16:04:38 -0500 (Fri, 03 Apr 2009)
New Revision: 2800

Added:
   cgm/trunk/test/brick.cpp
Modified:
   cgm/trunk/test/Makefile.am
Log:
Add test to verify correct topology constuction and querying.  Make a 
cube and check that everything is connected as expected.


Modified: cgm/trunk/test/Makefile.am
===================================================================
--- cgm/trunk/test/Makefile.am	2009-04-03 20:02:36 UTC (rev 2799)
+++ cgm/trunk/test/Makefile.am	2009-04-03 21:04:38 UTC (rev 2800)
@@ -12,7 +12,7 @@
 	   -I$(srcdir) \
 	   $(OCC_INC_FLAG)
 
-TESTS = sheet
+TESTS = sheet brick
 if build_ACIS
   TESTS += webcut hollow_acis
 else
@@ -47,6 +47,8 @@
 r_w_LDFLAGS = $(LDFLAGS) $(LINK_FLAGS)
 test_occ_LDFLAGS = $(LDFLAGS) $(LINK_FLAGS)
 operation_LDFLAGS = $(LDFLAGS) $(LINK_FLAGS)
+brick_SOURCES = brick.cpp
+brick_LDFLAGS = $(LDFLAGS) $(LINK_FLAGS)
 
 # Files that are used as input to tests, and therefore
 # must be included in tarball for tests to run.

Added: cgm/trunk/test/brick.cpp
===================================================================
--- cgm/trunk/test/brick.cpp	                        (rev 0)
+++ cgm/trunk/test/brick.cpp	2009-04-03 21:04:38 UTC (rev 2800)
@@ -0,0 +1,284 @@
+#include "GeometryModifyTool.hpp"
+#include "GeometryQueryTool.hpp"
+#include "ModelQueryEngine.hpp"
+#include "RefVertex.hpp"
+#include "RefEdge.hpp"
+#include "RefFace.hpp"
+#include "Body.hpp"
+#include "AppUtil.hpp"
+#include "Loop.hpp"
+#include "CoEdge.hpp"
+
+#ifdef HAVE_OCC
+#  include "OCCQueryEngine.hpp"
+#  include "OCCModifyEngine.hpp"
+#endif
+#ifdef HAVE_ACIS
+#  include "AcisQueryEngine.hpp"
+#  include "AcisModifyEngine.hpp"
+#endif
+
+#include <assert.h>
+#include <algorithm>
+
+
+/* Check that CGM's presentation of the modeler topology
+   is correct by creating a simple cube and checking that
+   everything is correctly connected.
+ */
+
+
+void check_valid_edge( RefEdge* edge );
+void check_valid_face( RefFace* face );
+void check_valid_loop( Loop* loop );
+
+int main( int argc, char* argv[] )
+{
+    // Start up CGM
+  AppUtil::instance()->startup(argc, argv);
+  CGMApp::instance()->startup(argc, argv);
+  CubitObserver::init_static_observers();
+#ifdef HAVE_OCC
+  OCCQueryEngine::instance();
+  OCCModifyEngine::instance();
+#endif
+#ifdef HAVE_ACIS
+  AcisQueryEngine::instance();
+  AcisModifyEngine::instance();
+#endif
+
+    // Create a brick
+  Body* brick = GeometryModifyTool::instance()->brick( 2, 2, 2 );
+  assert(brick != 0);
+  
+    // Get all child RefEntities
+  DLIList<ModelEntity*> query_results;
+  DLIList<RefFace*> surfaces;
+  DLIList<RefEdge*> curves;
+  DLIList<RefVertex*> points;
+  
+  ModelQueryEngine::instance()->query_model( *brick, DagType::ref_face_type(), query_results );
+  CAST_LIST( query_results, surfaces, RefFace );
+  query_results.clean_out();
+  ModelQueryEngine::instance()->query_model( *brick, DagType::ref_edge_type(), query_results );
+  CAST_LIST( query_results, curves, RefEdge );
+  query_results.clean_out();
+  ModelQueryEngine::instance()->query_model( *brick, DagType::ref_vertex_type(), query_results );
+  CAST_LIST( query_results, points, RefVertex );
+  query_results.clean_out();
+  
+    // Check expected number of child RefEntities
+  assert( surfaces.size() == 6 );
+  assert( curves.size() == 12 );
+  assert( points.size() == 8 );
+  
+    // Cube should be 2x2x2 and centered at origin, so each vertex
+    // should have the coords (+/-1, +/-1, +/-1).  Check that this
+    // is the case and put vertex pointers in an array in the canonical
+    // order for hexahedra.
+  RefVertex* corners[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
+  for (int i = 0; i < points.size(); ++i) {
+    RefVertex* vtx = points.get_and_step();
+    CubitVector pos = vtx->coordinates();
+    // all coordinate values are plus or minus one
+    assert( fabs(fabs(pos.x()) - 1) < 1e-12 );
+    assert( fabs(fabs(pos.y()) - 1) < 1e-12 );
+    assert( fabs(fabs(pos.z()) - 1) < 1e-12 );
+    int idx;
+    if (pos.x() < 0) 
+      idx = pos.y() < 0 ? 0 : 3;
+    else
+      idx = pos.y() < 0 ? 1 : 2;
+    if (pos.z() > 0)
+      idx += 4;
+    // No duplicate vertices allowed
+    assert( corners[idx] == 0 );
+    corners[idx] = vtx;
+  }
+  
+    // Now figure out which of the 12 edges each RefEdge is by
+    // checking the position of each attached vertex in the
+    // above 'corners' array,  Put edge pointers in an array in
+    // the canonical edge order for a heaxahedron.
+  RefEdge* edges[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  for (int i = 0; i < curves.size(); ++i) {
+    RefEdge* edge = curves.get_and_step();
+    int start_i = std::find( corners, corners + 8, edge->start_vertex() ) - corners;
+    int end_i = std::find( corners, corners + 8, edge->end_vertex() ) - corners;
+    assert( start_i < 8 );
+    assert( end_i < 8 );
+    int idx;
+      // If edge is lateral edge from bottom face to top
+    if (start_i < 4 && end_i >= 4) {
+      idx = start_i + 4;
+      assert( end_i == idx );
+    }
+      // If edge is lateral edge from top face to bottom
+    else if (start_i >= 4 && end_i < 4) {
+      idx = end_i + 4;
+      assert( start_i == idx );
+    }
+      // If edge is part of bottom face
+    else if (start_i < 4) {
+      if ((start_i + 1)%4 == end_i) 
+        idx = start_i;
+      else if ((end_i + 1)%4 == start_i)
+        idx = end_i;
+      else
+        assert( false );
+    }
+      // If edge is part of top face
+    else {
+      if ((start_i - 3) % 4 + 4 == end_i)
+        idx = start_i + 4;
+      else if ((end_i - 3) % 4 + 4 == start_i)
+        idx = end_i + 4;
+      else 
+        assert( false );
+    }
+    // Check no duplicate edges
+    assert( 0 == edges[idx] );
+    edges[idx] = edge;    
+  }
+  
+  // Face connectivity, specified by edge numbers
+  int std_faces[6][4] = { { 0, 5, 8, 4 },
+                          { 1, 6, 9, 5 },
+                          { 2, 7, 10, 6 },
+                          { 3, 4, 11, 7 },
+                          { 3, 2, 1, 0 },
+                          { 8, 9, 10,11 } };
+  RefFace* faces[6] = { 0, 0, 0, 0, 0, 0 };
+  DLIList< DLIList<RefEdge*>* > loops;
+  for (int i = 0; i < surfaces.size(); ++i) {
+    // get ref edges
+    RefFace* face = surfaces.get_and_step();
+    face->ref_edge_loops( loops );
+    assert( loops.size() == 1 );
+    DLIList<RefEdge*> loop(*loops.get());
+    delete loops.get();
+    loops.clean_out();
+    
+    // match loop of edges to one of the expected faces
+    assert( loop.size() == 4 );
+    int k;
+    for (k = 0; k < 6; ++k) {
+      int j;
+      for (j = 0; j < 4; ++j) 
+        if (!loop.is_in_list(edges[std_faces[k][j]]))
+          break;
+      if (j == 4)
+        break;
+    }
+    assert( k < 6 ); // fail of didn't match any expected face
+    assert(0 == faces[k]); // no duplicates
+    faces[k] = face;
+  }
+  
+  for (int i = 0; i < 12; ++i)
+    check_valid_edge( edges[i] );
+  for (int i = 0; i < 6; ++i) 
+    check_valid_face( faces[i] );
+  for (int i = 0; i < 6; ++i) {
+    assert(faces[i]->number_of_Loops() == 1);
+    check_valid_loop( dynamic_cast<Loop*>(faces[i]->get_first_grouping_entity_ptr()) );
+  }
+
+  return 0;
+}
+
+void check_valid_edge( RefEdge* edge )
+{
+    // Check that start and end vertices are in the correct order
+    // by comparing vertex coordinates to edge position from start
+    // and end parameters.
+  double start_u, end_u;
+  edge->get_param_range( start_u, end_u );
+  CubitStatus s;
+  CubitVector start_p, end_p;
+  s = edge->position_from_u( start_u, start_p );
+  assert(CUBIT_SUCCESS == s);
+  assert( (start_p - edge->start_vertex()->coordinates()).length() < 1e-6 );
+  s = edge->position_from_u( end_u, end_p );
+  assert(CUBIT_SUCCESS == s);
+  assert( (end_p - edge->end_vertex()->coordinates()).length() < 1e-6 );
+  
+    // Check reverse query from vertex to edge brings us back to the
+    // input edge.
+  DLIList<RefEntity*> ents;
+  edge->start_vertex()->get_parent_ref_entities( ents );
+  assert( ents.is_in_list( edge ) );
+  ents.clean_out();
+  edge->end_vertex()->get_parent_ref_entities( ents );
+  assert( ents.is_in_list( edge ) );
+}
+
+void check_valid_face( RefFace* face )
+{
+  DLIList<RefEntity*> edges, parents;
+  face->get_child_ref_entities( edges );
+  
+  double u_min, u_max, v_min, v_max, u, v;
+  face->get_param_range_U( u_min, u_max );
+  face->get_param_range_V( v_min, v_max );
+  
+    // Check that each edge is on the face
+  for (int i = 0; i < edges.size(); ++i) {
+    RefEdge* edge = dynamic_cast<RefEdge*>(edges.get_and_step());
+    assert(!!edge);
+    
+      // Get three points to sample at
+    CubitVector p[3];
+    p[0] = edge->start_vertex()->coordinates();
+    p[1] = edge->center_point();
+    p[2] = edge->end_vertex()->coordinates();
+    
+      // For each sample point
+    for (int j = 0; j < 3; ++j) {
+        // Check that point is on geometric surface
+      CubitVector close(p[j]);
+      face->move_to_surface( close );
+      assert( (close - p[j]).length() < 1e-6 );
+        // Check that point is within UV bounds
+      CubitStatus s = face->u_v_from_position( p[j], u, v );
+      assert( CUBIT_SUCCESS == s );
+      assert( (u - u_min) > -1e-6 );
+      assert( (u_max - u) > -1e-6 );
+      assert( (v - v_min) > -1e-6 );
+      assert( (v_max - v) > -1e-6 );
+    }
+  }
+  
+    // Check reverse query from edge to face brings us back to the
+    // input face.
+  for (int i = 0; i < edges.size(); ++i) {
+    parents.clean_out();
+    RefEntity* edge = edges.get_and_step();
+    edge->get_parent_ref_entities( parents );
+    assert( parents.is_in_list( face ) );
+  }
+}
+
+// Check that coedges in loop chare expected vertices.
+void check_valid_loop( Loop* loop )
+{
+  DLIList<CoEdge*> coedges;
+  loop->ordered_co_edges( coedges );
+  CoEdge* prev = coedges.get_and_step();
+  for (int i = 0; i < coedges.size(); ++i) {
+    CoEdge* curr = coedges.get_and_step();
+    RefVertex* common_1 = prev->get_sense() == CUBIT_REVERSED ?
+                          prev->get_ref_edge_ptr()->start_vertex() :
+                          prev->get_ref_edge_ptr()->end_vertex() ;
+    RefVertex* common_2 = curr->get_sense() == CUBIT_REVERSED ?
+                          curr->get_ref_edge_ptr()->end_vertex() :
+                          curr->get_ref_edge_ptr()->start_vertex();
+    assert( common_1 == common_2 );
+    prev = curr;
+  }
+}
+
+
+    
+    
+    



More information about the cgma-dev mailing list