diff --git a/src/ifcgeom/ConversionSettings.h b/src/ifcgeom/ConversionSettings.h index eb405a9e7c..febd789f6b 100644 --- a/src/ifcgeom/ConversionSettings.h +++ b/src/ifcgeom/ConversionSettings.h @@ -452,6 +452,12 @@ namespace ifcopenshell { static constexpr bool defaultvalue = false; }; + struct MakeVolume : public SettingBase { + static constexpr const char* const name = "make-volume"; + static constexpr const char* const description = "Try to isolate and fix a valid volume from non-manifold elements prior to opening subtraction"; + static constexpr bool defaultvalue = false; + }; + struct DeferProcessingFirstElement : public SettingBase { static constexpr const char* const name = "defer-processing-first-element"; static constexpr const char* const description = "Don't process first element in Iterator::initialize call()"; @@ -647,7 +653,7 @@ namespace ifcopenshell { }; class Settings : public SettingsContainer< - std::tuple + std::tuple > {}; } diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp index fcb390b6cc..a5a9d94149 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp @@ -29,6 +29,7 @@ #include "base_utils.h" #include +#include namespace { struct opening_sorter { @@ -132,11 +133,24 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* parts.push_back(it3_shape); } - for (auto& entity_part : parts) { + for (auto entity_part : parts) { bool is_manifold = util::is_manifold(entity_part); if (!is_manifold) { - Logger::Warning("Non-manifold first operand"); + if (settings_.get().get()) { + BOPAlgo_MakerVolume mv; + mv.AddArgument(entity_part); + mv.SetAvoidInternalShapes(true); + try { + mv.Perform(); + entity_part = mv.Shape(); + Logger::Warning("Sucessfully detected exterior volume to non-manifold first operand"); + } catch (const Standard_Failure& e) { + Logger::Warning("MakeVolume failed: " + std::string(e.GetMessageString()), entity); + } + } else { + Logger::Warning("Non-manifold first operand, use --make-volume to try and make manifold"); + } } TopoDS_Shape entity_part_result;