[cgma-dev] r1906 - in cgm/trunk: geom/OCC test

janehu at mcs.anl.gov janehu at mcs.anl.gov
Tue Jun 17 15:27:59 CDT 2008


Author: janehu
Date: 2008-06-17 15:27:58 -0500 (Tue, 17 Jun 2008)
New Revision: 1906

Modified:
   cgm/trunk/geom/OCC/OCCModifyEngine.cpp
   cgm/trunk/test/modify.cpp
Log:
Tested chop operation and added Unite operation.

Modified: cgm/trunk/geom/OCC/OCCModifyEngine.cpp
===================================================================
--- cgm/trunk/geom/OCC/OCCModifyEngine.cpp	2008-06-17 19:18:45 UTC (rev 1905)
+++ cgm/trunk/geom/OCC/OCCModifyEngine.cpp	2008-06-17 20:27:58 UTC (rev 1906)
@@ -3292,7 +3292,7 @@
   tool_bodies.append(tool_body_ptr);
   //get tool_body's underlying shape, copy it, so boolean wouldn't touch it.
   CubitStatus stat = 
-       get_shape_list(tool_bodies, tool_shapes, is_tool_volume, keep_old); 
+       get_shape_list(tool_bodies, tool_shapes, is_tool_volume, CUBIT_TRUE); 
   if(!stat)
     return stat;
 
@@ -3324,8 +3324,6 @@
     if(from_shape->IsNull())
     {
       PRINT_INFO("The %d body did not have common part with the tool_body.\n", i+1);
-      if (!keep_old)
-        OCCQueryEngine::instance()->delete_solid_model_entities(from_body);
       continue; 
     }
     else
@@ -3342,6 +3340,13 @@
   if(!keep_old)
     OCCQueryEngine::instance()->delete_solid_model_entities(tool_body_ptr);   
 
+  for(int i = 0; i < tool_shapes.size(); i++)
+  {
+    TopoDS_Shape* shape = tool_shapes.get_and_step();
+    shape->Nullify();
+    delete shape;
+  }
+
   if(keep_old)
   {
     int size  = shape_list.size();
@@ -3377,7 +3382,7 @@
      double orig_mass = myProps.Mass();
      BRepGProp::VolumeProperties(cut_shape, myProps);
      double after_mass = myProps.Mass();
-     if((-after_mass + orig_mass) <= tol)
+     if(fabs(-after_mass + orig_mass) <= tol)
      {
         has_changed= CUBIT_FALSE; //common is itself
         return;
@@ -3397,7 +3402,7 @@
      double orig_mass = myProps.Mass();
      BRepGProp::SurfaceProperties(cut_shape, myProps);
      double after_mass = myProps.Mass();
-     if((-after_mass + orig_mass) <= tol)
+     if(fabs(-after_mass + orig_mass) <= tol)
      {
        has_changed= CUBIT_FALSE; //common is itself, or not cut
        return;
@@ -3451,10 +3456,9 @@
   
   //outsideBodies keeps the surface, curve ids if keep_old is false.
   BodySM* blank_body = bodies.get();
-  BodySM* blank_copy = copy_body(blank_body);
   
   DLIList<BodySM*> tool_bodies, from_bodies;
-  from_bodies.append(blank_copy);
+  from_bodies.append(blank_body);
   BodySM* tool_body = bodies.step_and_get();
   tool_bodies.append(tool_body);
   
@@ -3464,28 +3468,141 @@
   if(!stat)
     return CUBIT_FAILURE;
 
-  from_bodies.clean_out();
-  from_bodies.append(blank_body);
   stat = subtract(tool_bodies, from_bodies, outsideBodies, 
                   CUBIT_FALSE, keep_old);
   
-  OCCQueryEngine::instance()->delete_solid_model_entities(blank_copy);
   return stat;
 }
 
 //===============================================================================
 // Function   : unite
 // Member Type: PUBLIC
-// Description: unite boolean operation between facet-based bodies
-// Author     : John Fowler
-// Date       : 10/02
+// Description: unite boolean operation between OCC-based bodies
+// Author     : Jane Hu
+// Date       : 06/08
 //===============================================================================
 CubitStatus     OCCModifyEngine::unite(DLIList<BodySM*> &bodies, 
-                                         DLIList<BodySM*> &newBodies,
-                                         bool keep_old) const
+                                       DLIList<BodySM*> &newBodies,
+                                       bool keep_old) const
 {
-  PRINT_ERROR("Option not supported for mesh based geometry.\n");
-  return CUBIT_FAILURE; 
+  if(bodies.size() < 2)
+    return CUBIT_SUCCESS;
+
+  //all bodies must have only one lump in order for boolean operation to work.
+  DLIList<Lump*> lumps;
+  for (int i = 0; i < bodies.size(); i++)
+  {
+    lumps = CAST_TO(bodies.get_and_step(), OCCBody)->lumps();
+    if (lumps.size() > 1)
+    {
+      PRINT_WARNING("All bodies must have only one lump for boolean operations to work.\n");
+      return CUBIT_FAILURE;
+    }
+  }
+ 
+  DLIList<TopoDS_Shape*> shape_list;
+  DLIList<CubitBoolean> is_volume;
+  CubitStatus stat =
+    get_shape_list(bodies, shape_list, is_volume, keep_old);
+
+  if(!stat)
+    return stat;
+
+  TopoDS_Shape* first_shape = shape_list.pop();
+  
+  int size = shape_list.size();
+  OCCBody* deleted_body = NULL;
+  CubitBoolean restore_first_shape = CUBIT_FALSE;
+  for(int i = 0; i < size; i++)
+  {
+    TopoDS_Shape* second_shape = shape_list.get_and_step();
+    
+    BRepAlgoAPI_Fuse fuser(*first_shape, *second_shape);
+    TopTools_ListOfShape shapes;
+    shapes.Assign(fuser.Modified(*first_shape));
+    if(shapes.Extent() != 1)
+    {
+      restore_first_shape = CUBIT_TRUE;
+      PRINT_WARNING("The unite boolean didn't work in opencascade.\n");
+      break;
+    }
+
+    CubitBoolean has_changed;
+    if(is_volume[size] == CUBIT_TRUE || is_volume[i] == CUBIT_TRUE)
+    {
+      if(is_volume[size] == CUBIT_FALSE)
+      {
+        //exchange the first and second bodies.
+        TopoDS_Shape* temp_shape = first_shape;
+        first_shape = second_shape;
+        second_shape = temp_shape;
+        OCCBody temp_body1 = *CAST_TO(bodies[size], OCCBody);
+        OCCBody temp_body2 = *CAST_TO(bodies.get(), OCCBody);
+        BodySM* first_body = bodies.get();
+        first_body = &temp_body1;
+        BodySM* second_body = bodies[size];
+        second_body = &temp_body2; 
+      }
+      check_operation(shapes.First(), first_shape, CUBIT_TRUE, has_changed, &fuser);
+    }
+    else
+      check_operation(shapes.First(), first_shape, CUBIT_FALSE,has_changed, &fuser);
+ 
+    BodySM* second_body = bodies.get_and_step();
+    if(second_body)
+    {
+      deleted_body = CAST_TO(second_body, OCCBody);
+      //delete the second body, keep lower entities.
+      DLIList<Lump*> lumps = deleted_body->lumps();
+      OCCQueryEngine::instance()->delete_solid_model_entities(lumps.get(),
+                                                              CUBIT_FALSE);
+      second_body = NULL;
+    }
+    TopExp_Explorer Ex;
+    for (Ex.Init(*second_shape, TopAbs_FACE);Ex.More(); Ex.Next())
+    {
+      TopoDS_Face face =  TopoDS::Face(Ex.Current());
+      TopoDS_Shape nullshape;
+      if(fuser.IsDeleted(face))
+        OCCSurface::update_OCC_entity(face,nullshape, &fuser);
+      else
+      {
+        shapes.Assign(fuser.Modified(face));
+        if(shapes.Extent() > 1)
+        {
+           restore_first_shape = CUBIT_TRUE;
+           PRINT_WARNING("The unite boolean didn't work in opencascade.\n");
+           break;
+        }
+        OCCSurface::update_OCC_entity(face, shapes.First(), &fuser);
+      }
+    }
+  }      
+
+  //ok, we're done wih all unites, construct new Body'
+  DLIList<TopologyBridge*> tbs;
+  tbs += OCCQueryEngine::instance()->populate_topology_bridge(*first_shape);
+
+  for (int i = 0; i< tbs.size(); i++)
+  {
+    BodySM* bodysm = CAST_TO(tbs.get_and_step(), BodySM);
+    if (bodysm)
+      newBodies.append(bodysm);
+  }
+
+  //ok, we're done wih all unites, delete unnecessaries.
+  if(keep_old)
+  {
+    int size  = shape_list.size();
+    for (int i = 0; i < size; i++)
+    {
+      TopoDS_Shape* shape = shape_list.pop();
+      shape->Nullify();
+      delete shape;
+    }
+  }
+
+  return CUBIT_SUCCESS; 
 }
 
 

Modified: cgm/trunk/test/modify.cpp
===================================================================
--- cgm/trunk/test/modify.cpp	2008-06-17 19:18:45 UTC (rev 1905)
+++ cgm/trunk/test/modify.cpp	2008-06-17 20:27:58 UTC (rev 1906)
@@ -167,6 +167,8 @@
   BodySM* stitched_body = NULL;
   DLIList<Body*> new_bodies;
   gmti->create_solid_bodies_from_surfs(face_list, new_bodies);
+  //Created volume(s): 8 
+  //Destroyed volume(s): 2 to 7
 
   CubitStatus rsl = CUBIT_SUCCESS;
   DLIList<RefEntity*> ref_entity_list;
@@ -194,6 +196,7 @@
   char *argv = "stitch.occ";
   CubitStatus status = read_geometry(1, &argv, true);
   if (status == CUBIT_FAILURE) exit(1);
+  //Read in 1 volume.
 
   bodies.clean_out();
   free_entities.clean_out();
@@ -260,12 +263,17 @@
   new_bodies.clean_out();
   rsl = gmti->subtract(from_body2, from_bodies, new_bodies, 
                        CUBIT_TRUE, CUBIT_FALSE);
+  //Updated volume(s): 18
+  //Destroyed volume(s): 19
   //new bodies has one body, new body has 10 ref-faces, 5 of them are remaining
   //with old id, 5 of them are new faces.
+
   from_bodies=new_bodies;
   new_bodies.clean_out();
   rsl = gmti->subtract(tool_body,from_bodies, new_bodies,
                        CUBIT_TRUE, CUBIT_FALSE);
+  //Created volume(s): 21, 22
+  //Destroyed volume(s): 18, 20
   d = new_bodies.step_and_get()->measure();
   v = new_bodies.get()->center_point();
   int n = new_bodies.get()->num_ref_faces();
@@ -297,6 +305,7 @@
   from_bodies.append(cp_from_body);
   new_bodies.clean_out();
   CubitStatus stat = gmti->imprint(from_bodies, ref_edges, new_bodies, CUBIT_FALSE, CUBIT_TRUE );
+  //Updated volume(s): 25
 
   //test edge imprint on surface
   CubitVector vv(5,1,4.0);
@@ -315,6 +324,7 @@
   assert(face_list.size() == 1);
   ref_edges.step_and_get()->ref_vertices(vertices);
   stat = gmti->imprint(unimprint_faces, ref_edges, new_bodies, CUBIT_FALSE);
+  //Updated volume(s): 26
 
   new_bodies.clean_out();
   face_list.clean_out();
@@ -340,18 +350,24 @@
   from_bodies.append(cp_from_body2);
   new_bodies.clean_out(); 
   stat = gmti->imprint(from_bodies, vectors, new_bodies, CUBIT_FALSE);
+  //Updated volume(s): 26
 
   n = new_bodies.get()->num_ref_edges();//n = 17
 
   new_bodies.clean_out();
   stat = gmti->imprint(face_list, ref_edges, new_bodies, CUBIT_FALSE);
+  //Updated volume(s): 26
 
+  n = new_bodies.get()->num_ref_edges();//n = 21
+
   //test for multi-cut imprint for subtract.
   from_bodies.clean_out();
   from_bodies.append(from_body);
   new_bodies.clean_out();
   rsl = gmti->subtract(tool_body, from_bodies, new_bodies,
                        CUBIT_TRUE, CUBIT_FALSE);
+  //Updated volume(s): 23
+
   n = new_bodies.get()->num_ref_faces();
   //n = 8
   n = new_bodies.get()->num_ref_edges();
@@ -411,6 +427,7 @@
   from_bodies.append(copy_tool_body);
   from_bodies.append(from_body2);
   stat = gmti->imprint(from_bodies, new_bodies, CUBIT_FALSE); 
+  //Updated volume(s): 30 one body gets cut once with 7 faces, the other is not
 
   //test body imprinted by curves.
   ref_edges.clean_out();
@@ -419,6 +436,7 @@
   new_bodies.clean_out();
   from_bodies.append(copy_tool_body2);
   stat = gmti->imprint(from_bodies, ref_edges, new_bodies, CUBIT_FALSE, CUBIT_TRUE );
+  //Updated volume(s): 31, no cuts performed
 
   //test body cutting a shell, one surface got cut as the result. 
   CubitVector v_move6(1,-1,0);
@@ -428,6 +446,8 @@
   new_bodies.clean_out();
   rsl = gmti->subtract(tool_body, from_bodies, new_bodies,
                        CUBIT_TRUE, CUBIT_TRUE);
+  //Created volume(s): 32
+
   d = new_bodies.step_and_get()->measure();
   v = new_bodies.get()->center_point();
   n = new_bodies.get()->num_ref_faces();
@@ -439,6 +459,8 @@
   //test a shell cutting a body, failed operation with an Error message.
   rsl = gmti->subtract(from_body2, from_bodies, new_bodies,
                        CUBIT_TRUE, CUBIT_TRUE);
+  //WARNING: Surfaces or Shells can't be used to cut a body.
+  //ERROR: Subtract FAILED
 
   //test solid solid imprint
   tool_body  = gmti->brick(4, 4, 4);
@@ -450,6 +472,9 @@
   from_bodies.append(from_body);
   from_bodies.append(tool_body);
   stat =  gmti->imprint(from_bodies, new_bodies, CUBIT_FALSE);
+  //Updated volume(s): 33, 34
+  //one body gets 4 cuts, the other 3.
+  //one body gets 10 faces, the other 9.
   
   //test imprint projected edges
   bodies.clean_out();
@@ -474,8 +499,113 @@
   new_bodies.clean_out();
   gmti->imprint_projected_edges(ref_faces,ref_edges, new_bodies, CUBIT_TRUE,
        CUBIT_FALSE); 
+  //Created volume(s): 37
   if(new_bodies.size())
-    n = new_bodies.get()->num_ref_faces();
+    n = new_bodies.get()->num_ref_faces();//n = 8, new_bodies.size() == 1
+
+  //delete all bodies.
+  bodies.clean_out();
+  gti->bodies(bodies);
+  //delete all entities
+  gti->delete_Body(bodies);
+
+  free_entities.clean_out();
+  gti->get_free_ref_entities(free_entities);
+
+  //test body-body intersect.
+  //1. from body is the commom body, no update
+  tool_body  = gmti->brick(4, 4, 4);
+  from_body = gmti->brick(1,1,1);
+  from_bodies.clean_out();
+  new_bodies.clean_out();
+  from_bodies.append(from_body);
+  stat =  gmti->intersect(tool_body, from_bodies, new_bodies, CUBIT_FALSE);
+  //Updated volume(s): 39
+  //Destroyed volume(s): 38
+  d = new_bodies.get()->measure(); //d = 1
+  
+  //2. common body is part of from body, update the correponding face
+  tool_body  = gmti->brick(4, 4, 4);
+  CubitVector v_move7(0,0.5,0);
+  gti->translate(tool_body,v_move7);
+  from_bodies.clean_out();
+  from_bodies.append(from_body);
+  new_bodies.clean_out();
+  stat =  gmti->intersect(tool_body, from_bodies, new_bodies, CUBIT_FALSE);
+  d = new_bodies.get()->measure(); //d = 0.5
+  //Updated volume(s): 39
+  //Destroyed volume(s): 40
+
+  //3. there's no common body, from body is deleted or kept depending on
+  //keep-old flag. 
+  tool_body  = gmti->brick(4, 4, 4);
+  gti->translate(tool_body,v_move7);
+  gti->translate(tool_body,v_move7);
+  from_bodies.clean_out();
+  new_bodies.clean_out();
+  from_bodies.append(from_body);
+  //nothing changed 
+  stat =  gmti->intersect(tool_body, from_bodies, new_bodies, CUBIT_TRUE);
+  //"The 1 body did not have common part with the tool_body."
+
+  //from_body get deleted
+  stat =  gmti->intersect(tool_body, from_bodies, new_bodies, CUBIT_FALSE);
+  //"The 1 body did not have common part with the tool_body."
+  //Destroyed volume(s): 39, 41
+
+  bodies.clean_out();
+  gti->bodies(bodies);
+  //delete all entities
+  gti->delete_Body(bodies);
+
+  free_entities.clean_out();
+  gti->get_free_ref_entities(free_entities);
+
+  //test chop operation
+  tool_body  = gmti->brick(4, 4, 4);
+  from_body = gmti->brick(1,1,1);
+  gti->translate(tool_body,v_move7);
+  from_bodies.clean_out();
+  from_bodies.append(from_body);
+  from_bodies.append(tool_body);
+  new_bodies.clean_out();
+
+  //new_bodies = intersect bodies;bodies = outside bodies; body is dummy 
+  stat =  gmti->chop(from_bodies, new_bodies, bodies, body, CUBIT_FALSE);
+  d = new_bodies.get()->measure(); //d = 0.5
+  //Created volume(s): 44
+  //Destroyed volume(s): 42
+  //Updated volume(s): 43 
+
+  bodies.clean_out();
+  gti->bodies(bodies);
+  //delete all entities
+  gti->delete_Body(bodies);
+
+  free_entities.clean_out();
+  gti->get_free_ref_entities(free_entities);
+
+  //test chop 2
+  from_body = gmti->brick(4, 4, 4);
+  tool_body = gmti->brick(1,1,1);
+  gti->translate(tool_body,v_move7);
+  from_bodies.clean_out();
+  from_bodies.append(from_body);
+  from_bodies.append(tool_body);
+  new_bodies.clean_out();
+  bodies.clean_out();
+  stat =  gmti->chop(from_bodies, new_bodies, bodies, body, CUBIT_FALSE);
+  //Created volume(s): 47
+  //Destroyed volume(s): 46
+  //Updated volume(s): 45
+  d = bodies.get()->measure();//d = 63
+  
+  bodies.clean_out();
+  gti->bodies(bodies);
+  //delete all entities
+  gti->delete_Body(bodies);
+
+  free_entities.clean_out();
+  gti->get_free_ref_entities(free_entities);
   return CUBIT_SUCCESS;
-
 }




More information about the cgma-dev mailing list