mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 13:52:23 +00:00
Create a compsolid shape for an extrusion of a IfcCompositeProfileDef and process the opening subtraction individually
This commit is contained in:
@@ -209,26 +209,64 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
|
|||||||
original_shape_volume = shape_volume(entity_shape);
|
original_shape_volume = shape_volume(entity_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape);
|
if (entity_shape.ShapeType() == TopAbs_COMPSOLID) {
|
||||||
|
|
||||||
if ( brep_cut.IsDone() ) {
|
// For compound solids process the subtraction for the constituent
|
||||||
TopoDS_Shape brep_cut_result = brep_cut;
|
// solids individually and write the result back as a compound solid.
|
||||||
|
|
||||||
BRepCheck_Analyzer analyser(brep_cut_result);
|
TopoDS_CompSolid compound;
|
||||||
bool is_valid = analyser.IsValid() != 0;
|
BRep_Builder builder;
|
||||||
if ( is_valid ) {
|
builder.MakeCompSolid(compound);
|
||||||
entity_shape = brep_cut;
|
|
||||||
if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
|
|
||||||
const double volume_after_subtraction = shape_volume(entity_shape);
|
|
||||||
|
|
||||||
if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
|
TopExp_Explorer exp(entity_shape, TopAbs_SOLID);
|
||||||
Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",entity->entity);
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 ) {
|
||||||
|
entity_shape = brep_cut;
|
||||||
|
if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
|
||||||
|
const double volume_after_subtraction = shape_volume(entity_shape);
|
||||||
|
|
||||||
|
if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
|
||||||
|
Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",entity->entity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger::Message(Logger::LOG_ERROR,"Invalid result from subtraction:",entity->entity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger::Message(Logger::LOG_ERROR,"Invalid result from subtraction:",entity->entity);
|
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = BRepPrimAPI_MakePrism(face,height*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.Move(trsf);
|
shape.Move(trsf);
|
||||||
return ! shape.IsNull();
|
return ! shape.IsNull();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user