Make sure compound structure is retained as SvgSerializer depends on it

This commit is contained in:
Thomas Krijnen
2025-10-01 15:01:50 +02:00
parent babf95785c
commit d684d47dc8
10 changed files with 32 additions and 5 deletions
+1
View File
@@ -282,6 +282,7 @@ namespace IfcGeom {
virtual ConversionResultShape* halfspaces() = 0;
virtual ConversionResultShape* box() = 0;
virtual ConversionResultShape* solid() = 0;
virtual ConversionResultShape* wrap_in_compound() = 0;
virtual std::vector<ConversionResultShape*> vertices() = 0;
virtual std::vector<ConversionResultShape*> edges() = 0;
+1 -1
View File
@@ -68,7 +68,7 @@ IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool
delete accum;
accum = n;
} else {
accum = s;
accum = s->wrap_in_compound();
}
}
@@ -610,6 +610,11 @@ ConversionResultShape * ifcopenshell::geometry::CgalShape::box()
throw std::runtime_error("Not implemented");
}
ConversionResultShape* ifcopenshell::geometry::CgalShape::wrap_in_compound()
{
return new CgalShape(poly(), convex_tag_);
}
std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShape::vertices()
{
// @todo this is ridiculous
@@ -1001,4 +1006,10 @@ void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::map(const std::vec
shape_ = std::move(nw);
}
ConversionResultShape* ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::wrap_in_compound()
{
throw std::runtime_error("Not implemented");
}
#endif
@@ -244,6 +244,7 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* halfspaces();
virtual ConversionResultShape* solid();
virtual ConversionResultShape* box();
virtual ConversionResultShape* wrap_in_compound();
virtual std::vector<ConversionResultShape*> vertices();
virtual std::vector<ConversionResultShape*> edges();
@@ -312,6 +313,7 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* halfspaces();
virtual ConversionResultShape* solid();
virtual ConversionResultShape* box();
virtual ConversionResultShape* wrap_in_compound();
virtual std::vector<ConversionResultShape*> vertices();
virtual std::vector<ConversionResultShape*> edges();
@@ -484,6 +484,15 @@ ConversionResultShape * ifcopenshell::geometry::OpenCascadeShape::box()
throw std::runtime_error("Not implemented");
}
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::wrap_in_compound()
{
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
builder.Add(compound, shape_);
return new OpenCascadeShape(std::move(compound));
}
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::vertices()
{
TopTools_IndexedMapOfShape map;
@@ -556,7 +565,9 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::concat(Conversi
auto& left = shape_;
auto& right = ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_;
if (left.ShapeType() == TopAbs_COMPOUND) {
// This reads a bit strange, but we want to specifically avoid compounds of faces that are
// the result of shell instances that are not sewn into a shell (yet).
if (left.ShapeType() == TopAbs_COMPOUND && !IfcGeom::util::is_compound_of_faces(left)) {
compound = TopoDS::Compound(left);
} else {
builder.MakeCompound(compound);
@@ -90,6 +90,7 @@ namespace ifcopenshell {
virtual ConversionResultShape* halfspaces();
virtual ConversionResultShape* solid();
virtual ConversionResultShape* box();
virtual ConversionResultShape* wrap_in_compound();
virtual std::vector<ConversionResultShape*> vertices();
virtual std::vector<ConversionResultShape*> edges();
@@ -607,7 +607,7 @@ gp_Pnt IfcGeom::util::point_above_plane(const gp_Pln& pln, bool agree) {
}
}
bool IfcGeom::util::is_compound(const TopoDS_Shape& shape) {
bool IfcGeom::util::is_compound_of_faces(const TopoDS_Shape& shape) {
bool has_solids = TopExp_Explorer(shape, TopAbs_SOLID).More() != 0;
bool has_shells = TopExp_Explorer(shape, TopAbs_SHELL).More() != 0;
bool has_compounds = TopExp_Explorer(shape, TopAbs_COMPOUND).More() != 0;
+1 -1
View File
@@ -51,7 +51,7 @@ namespace IfcGeom {
IFC_GEOMLIBRARY_API bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid, double tol);
IFC_GEOMLIBRARY_API bool shape_to_face_list(const TopoDS_Shape& s, TopTools_ListOfShape& li);
IFC_GEOMLIBRARY_API bool create_solid_from_faces(const TopTools_ListOfShape& face_list, TopoDS_Shape& solid, double tol, bool force_sewing = false);
IFC_GEOMLIBRARY_API bool is_compound(const TopoDS_Shape& shape);
IFC_GEOMLIBRARY_API bool is_compound_of_faces(const TopoDS_Shape& shape);
IFC_GEOMLIBRARY_API bool is_convex(const TopoDS_Wire& wire, double tol);
IFC_GEOMLIBRARY_API TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
IFC_GEOMLIBRARY_API gp_Pln plane_from_face(const TopoDS_Face& face);
@@ -1431,7 +1431,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
}
TopoDS_Shape IfcGeom::util::ensure_fit_for_subtraction(const TopoDS_Shape& shape, double tol) {
const bool is_comp = is_compound(shape);
const bool is_comp = is_compound_of_faces(shape);
if (!is_comp) {
return shape;
}
+1
View File
@@ -81,6 +81,7 @@
%newobject IfcGeom::ConversionResultShape::intersect;
%newobject IfcGeom::ConversionResultShape::concat;
%newobject IfcGeom::ConversionResultShape::moved;
%newobject IfcGeom::ConversionResultShape::wrap_in_compound;
%newobject IfcGeom::ConversionResultShape::area;
%newobject IfcGeom::ConversionResultShape::volume;