[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