Create a compsolid shape for an extrusion of a IfcCompositeProfileDef and process the opening subtraction individually

This commit is contained in:
Thomas Krijnen
2014-07-24 11:22:31 +00:00
parent 9a1c7af953
commit cf2e82e8f5
2 changed files with 83 additions and 17 deletions
+38
View File
@@ -209,6 +209,43 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
original_shape_volume = shape_volume(entity_shape); original_shape_volume = shape_volume(entity_shape);
} }
if (entity_shape.ShapeType() == TopAbs_COMPSOLID) {
// For compound solids process the subtraction for the constituent
// solids individually and write the result back as a compound solid.
TopoDS_CompSolid compound;
BRep_Builder builder;
builder.MakeCompSolid(compound);
TopExp_Explorer exp(entity_shape, TopAbs_SOLID);
for (; exp.More(); exp.Next()) {
BRepAlgoAPI_Cut brep_cut(exp.Current(), opening_shape);
bool added = false;
if ( brep_cut.IsDone() ) {
TopoDS_Shape brep_cut_result = brep_cut;
BRepCheck_Analyzer analyser(brep_cut_result);
bool is_valid = analyser.IsValid() != 0;
if (is_valid) {
TopExp_Explorer exp(brep_cut_result, TopAbs_SOLID);
for (; exp.More(); exp.Next()) {
builder.Add(compound, exp.Current());
added = true;
}
}
}
if (!added) {
// Add the original in case subtraction fails
builder.Add(compound, exp.Current());
} else {
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
}
}
entity_shape = compound;
} else {
BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape); BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape);
if ( brep_cut.IsDone() ) { if ( brep_cut.IsDone() ) {
@@ -230,6 +267,7 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
} else { } else {
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity); Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
} }
}
} }
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style())); cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style()));
+29 -1
View File
@@ -96,8 +96,9 @@
#include "../ifcgeom/IfcGeom.h" #include "../ifcgeom/IfcGeom.h"
bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) { bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) {
TopoDS_Face face; TopoDS_Shape face;
if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false; if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false;
const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT); const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
gp_Trsf trsf; gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf); IfcGeom::convert(l->Position(),trsf);
@@ -105,7 +106,34 @@ bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& sh
gp_Dir dir; gp_Dir dir;
convert(l->ExtrudedDirection(),dir); convert(l->ExtrudedDirection(),dir);
shape.Nullify();
if (face.ShapeType() == TopAbs_COMPOUND) {
// For compounds (most likely the result of a IfcCompositeProfileDef)
// create a compound solid shape.
TopExp_Explorer exp(face, TopAbs_FACE);
TopoDS_CompSolid compound;
BRep_Builder builder;
builder.MakeCompSolid(compound);
int num_faces_extruded = 0;
for (; exp.More(); exp.Next(), ++num_faces_extruded) {
builder.Add(compound, BRepPrimAPI_MakePrism(exp.Current(), height*dir));
}
if (num_faces_extruded) {
shape = compound;
}
}
if (shape.IsNull()) {
shape = BRepPrimAPI_MakePrism(face, height*dir); shape = BRepPrimAPI_MakePrism(face, height*dir);
}
shape.Move(trsf); shape.Move(trsf);
return ! shape.IsNull(); return ! shape.IsNull();
} }