diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp index fb26abeed4..0947129b57 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp @@ -19,8 +19,9 @@ using ifcopenshell::geometry::NumberEpeck; #define NumberType NumberEpeck #endif -ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t & shape) { +ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t & shape, bool convex) { shape_ = shape; + convex_tag_ = convex; if (shape.size_of_facets() != 1) { // this is for handling the specical case of storing a single point in a polyhedron, // @todo come up with a proper variant for storing lower dimensional entities @@ -35,8 +36,10 @@ void ifcopenshell::geometry::CgalShape::to_poly() const { shape_.emplace(); convert_to_polyhedron(*nef_, *shape_); - // @todo why is this necessary? we have the mark of the volumes? - CGAL::Polygon_mesh_processing::orient_to_bound_a_volume(*shape_); + if (shape_->size_of_vertices() > 0) { + // @todo why is this necessary? we have the mark of the volumes? + CGAL::Polygon_mesh_processing::orient_to_bound_a_volume(*shape_); + } // nef_->convert_to_polyhedron(*shape_); } @@ -44,8 +47,10 @@ void ifcopenshell::geometry::CgalShape::to_poly() const { void ifcopenshell::geometry::CgalShape::to_nef() const { if (!nef_) { - if (CGAL::Polygon_mesh_processing::does_self_intersect(*shape_)) { - throw std::runtime_error("Self-intersections detected, unable to proceed"); + if (!convex_tag_) { + if (CGAL::Polygon_mesh_processing::does_self_intersect(*shape_)) { + throw std::runtime_error("Self-intersections detected, unable to proceed"); + } } nef_ = utils::create_nef_polyhedron(*shape_); } @@ -382,7 +387,7 @@ std::vector ifcopenshell::geometry::CgalShape::convex_de // directly, so for now we need to isolate the individual volumes. CGAL::Polyhedron_3 P; copy.convert_inner_shell_to_polyhedron(ci->shells_begin(), P); - result.push_back(new CgalShape(P)); + result.push_back(new CgalShape(P, /*convex=*/ true)); } } return result; @@ -394,7 +399,7 @@ ConversionResultShape* ifcopenshell::geometry::CgalShape::halfspaces() #ifdef IFOPSH_SIMPLE_KERNEL throw std::runtime_error("Not implemented"); #else - return new CgalShapeHalfSpaceDecomposition(nef()); + return new CgalShapeHalfSpaceDecomposition(nef(), convex_tag_); #endif } @@ -529,7 +534,7 @@ ConversionResultShape* ifcopenshell::geometry::CgalShape::moved(ifcopenshell::ge } } - return new CgalShape(s); + return new CgalShape(s, convex_tag_); } void ifcopenshell::geometry::CgalShape::map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to) { diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.h b/src/ifcgeom/kernels/cgal/CgalConversionResult.h index d6c1148175..16f53aaf38 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.h +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.h @@ -177,16 +177,18 @@ namespace ifcopenshell { namespace geometry { class CgalShape : public IfcGeom::ConversionResultShape { private: + bool convex_tag_ = false; mutable boost::optional shape_; #ifndef IFOPSH_SIMPLE_KERNEL mutable boost::optional> nef_; #endif public: - CgalShape(const cgal_shape_t& shape); + CgalShape(const cgal_shape_t& shape, bool convex = false); #ifndef IFOPSH_SIMPLE_KERNEL - CgalShape(const CGAL::Nef_polyhedron_3& shape) { + CgalShape(const CGAL::Nef_polyhedron_3& shape, bool convex = false) { nef_ = shape; + convex_tag_ = convex; } #endif @@ -252,6 +254,9 @@ namespace ifcopenshell { namespace geometry { virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to); virtual void map(const std::vector>& from, const std::vector>& to); virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const; + + bool convex_tag() const { return convex_tag_; } + bool& convex_tag() { return convex_tag_; } }; #ifndef IFOPSH_SIMPLE_KERNEL @@ -261,9 +266,12 @@ namespace ifcopenshell { namespace geometry { std::list> planes_; public: - CgalShapeHalfSpaceDecomposition(const CGAL::Nef_polyhedron_3& shape) { - auto shape_copy = shape; - shape_ = std::move(build_halfspace_tree_decomposed(shape_copy, planes_)); + CgalShapeHalfSpaceDecomposition(const CGAL::Nef_polyhedron_3& shape, bool is_convex) { + if (is_convex) { + shape_ = std::move(build_halfspace_tree_is_decomposed(shape, planes_)); + } else { + shape_ = std::move(build_halfspace_tree_decomposed(shape, planes_)); + } } CgalShapeHalfSpaceDecomposition(const CGAL::Plane_3& shape) {