#2237 workaround for openings on extrusions of compound profiles

This commit is contained in:
Thomas Krijnen
2022-06-11 15:48:04 +02:00
parent bf3eb68b67
commit 0f85890c72
4 changed files with 122 additions and 83 deletions
+41 -4
View File
@@ -1377,20 +1377,43 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
// Iterate over the shapes of the IfcProduct // Iterate over the shapes of the IfcProduct
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++it3) { for (IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++it3) {
bool is_manifold = Kernel::is_manifold(it3->Shape()); TopoDS_Compound C;
BRep_Builder B;
B.MakeCompound(C);
TopoDS_Shape combined_result;
std::list<TopoDS_Shape> parts;
bool is_multiple = it3->Shape().ShapeType() == TopAbs_COMPOUND && TopoDS_Iterator(it3->Shape()).More() && util::is_nested_compound_of_solid(it3->Shape());
if (is_multiple) {
TopoDS_Iterator sit(it3->Shape());
for (; sit.More(); sit.Next()) {
parts.push_back(sit.Value());
}
} else {
parts.push_back(it3->Shape());
}
for (auto& entity_part : parts) {
bool is_manifold = Kernel::is_manifold(entity_part);
if (!is_manifold) { if (!is_manifold) {
Logger::Warning("Non-manifold first operand"); Logger::Warning("Non-manifold first operand");
} }
TopoDS_Shape entity_part_result;
for (int as_shell = 0; as_shell < 2; ++as_shell) { for (int as_shell = 0; as_shell < 2; ++as_shell) {
TopoDS_Shape entity_shape_solid; TopoDS_Shape entity_shape_solid;
TopoDS_Shape entity_shape_unlocated; TopoDS_Shape entity_shape_unlocated;
if (as_shell) { if (as_shell) {
entity_shape_unlocated = it3->Shape(); entity_shape_unlocated = entity_part;
} else { } else {
entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(), entity_shape_solid); entity_shape_unlocated = ensure_fit_for_subtraction(entity_part, entity_shape_solid);
} }
const gp_GTrsf& entity_shape_gtrsf = it3->Placement(); const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
if (entity_shape_gtrsf.Form() == gp_Other) { if (entity_shape_gtrsf.Form() == gp_Other) {
@@ -1441,12 +1464,26 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
continue; continue;
} }
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(it3->ItemId(), result, it3->StylePtr())); entity_part_result = result;
// For manifold first operands we're not even going to try if processing // For manifold first operands we're not even going to try if processing
// as loose faces gives a better result. // as loose faces gives a better result.
break; break;
} }
if (is_multiple) {
B.Add(C, entity_part_result);
} else {
combined_result = entity_part_result;
}
}
if (is_multiple) {
combined_result = C;
}
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(it3->ItemId(), combined_result, it3->StylePtr()));
} }
return true; return true;
} }
+1 -19
View File
@@ -541,24 +541,6 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, Ifc
return true; return true;
} }
namespace {
bool is_nested_compound_of_solid(const TopoDS_Shape& s, int depth=0) {
if (s.ShapeType() == TopAbs_COMPOUND) {
TopoDS_Iterator it(s);
for (; it.More(); it.Next()) {
if (!is_nested_compound_of_solid(it.Value(), depth + 1)) {
return false;
}
}
return true;
} else if (s.ShapeType() == TopAbs_SOLID) {
return depth > 0;
} else {
return false;
}
}
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape) { bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape) {
TopoDS_Shape s1; TopoDS_Shape s1;
@@ -715,7 +697,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
bool valid_result; bool valid_result;
if (s1.ShapeType() == TopAbs_COMPOUND && TopoDS_Iterator(s1).More() && is_nested_compound_of_solid(s1)) { if (s1.ShapeType() == TopAbs_COMPOUND && TopoDS_Iterator(s1).More() && util::is_nested_compound_of_solid(s1)) {
TopoDS_Compound C; TopoDS_Compound C;
BRep_Builder B; BRep_Builder B;
B.MakeCompound(C); B.MakeCompound(C);
+16
View File
@@ -354,3 +354,19 @@ bool IfcGeom::Kernel::is_manifold(const TopoDS_Shape& a) {
return true; return true;
} }
} }
bool IfcGeom::util::is_nested_compound_of_solid(const TopoDS_Shape& s, int depth) {
if (s.ShapeType() == TopAbs_COMPOUND) {
TopoDS_Iterator it(s);
for (; it.More(); it.Next()) {
if (!is_nested_compound_of_solid(it.Value(), depth + 1)) {
return false;
}
}
return true;
} else if (s.ShapeType() == TopAbs_SOLID) {
return depth > 0;
} else {
return false;
}
}
+4
View File
@@ -130,6 +130,10 @@ namespace IfcGeom {
KernelFactoryImplementation& kernel_implementations(); KernelFactoryImplementation& kernel_implementations();
} }
namespace util {
bool is_nested_compound_of_solid(const TopoDS_Shape& s, int depth = 0);
}
} }
#endif #endif