This commit is contained in:
Thomas Krijnen
2025-03-24 14:09:00 +01:00
parent dd53f9b494
commit eec8c88e6f
2 changed files with 14 additions and 19 deletions
+10 -12
View File
@@ -75,12 +75,12 @@ bool is_valid_for_kernel(const ifcopenshell::geometry::kernels::AbstractKernel*
} }
class HybridKernel : public ifcopenshell::geometry::kernels::AbstractKernel { class HybridKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
std::vector<AbstractKernel*> kernels_; std::vector<std::unique_ptr<AbstractKernel>> kernels_;
ifcopenshell::geometry::abstract_mapping* mapping_; ifcopenshell::geometry::abstract_mapping* mapping_;
public: public:
HybridKernel(const std::string& name, IfcParse::IfcFile* file, Settings& settings, std::vector<AbstractKernel*> kernels) HybridKernel(const std::string& name, IfcParse::IfcFile* file, Settings& settings, std::vector<std::unique_ptr<AbstractKernel>>&& kernels)
: AbstractKernel(name, settings) : AbstractKernel(name, settings)
, kernels_(kernels) , kernels_(std::move(kernels))
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings)) , mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings))
{} {}
virtual bool convert(const taxonomy::ptr item, IfcGeom::ConversionResults& rs) { virtual bool convert(const taxonomy::ptr item, IfcGeom::ConversionResults& rs) {
@@ -88,7 +88,7 @@ public:
bool has_openings = ops && ops->size(); bool has_openings = ops && ops->size();
for (auto& k : kernels_) { for (auto& k : kernels_) {
#ifdef IFOPSH_WITH_CGAL #ifdef IFOPSH_WITH_CGAL
if (has_openings && dynamic_cast<ifcopenshell::geometry::kernels::SimpleCgalKernel*>(k)) { if (has_openings && dynamic_cast<ifcopenshell::geometry::kernels::SimpleCgalKernel*>(k.get())) {
// @todo this would fail later on in the find_openings() call, because we have a // @todo this would fail later on in the find_openings() call, because we have a
// SimpleCgalShape which cannot be used on a kernel that supports booleans. // SimpleCgalShape which cannot be used on a kernel that supports booleans.
// @todo 1 implement the translation between various conversion result shapes // @todo 1 implement the translation between various conversion result shapes
@@ -138,7 +138,7 @@ public:
for (auto& k : kernels_) { for (auto& k : kernels_) {
bool is_valid = true; bool is_valid = true;
for (auto& s : entity_shapes) { for (auto& s : entity_shapes) {
if (!is_valid_for_kernel(k, s)) { if (!is_valid_for_kernel(k.get(), s)) {
is_valid = false; is_valid = false;
break; break;
} }
@@ -179,7 +179,7 @@ ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels
if (geometry_library_lower.rfind("hybrid-", 0) == 0) { if (geometry_library_lower.rfind("hybrid-", 0) == 0) {
geometry_library_lower = geometry_library_lower.substr(strlen("hybrid")); geometry_library_lower = geometry_library_lower.substr(strlen("hybrid"));
std::vector<AbstractKernel*> kernels; std::vector<std::unique_ptr<AbstractKernel>> kernels;
while (!geometry_library_lower.empty()) { while (!geometry_library_lower.empty()) {
if (geometry_library_lower.find("-", 0) == 0) { if (geometry_library_lower.find("-", 0) == 0) {
geometry_library_lower = geometry_library_lower.substr(strlen("-")); geometry_library_lower = geometry_library_lower.substr(strlen("-"));
@@ -189,25 +189,23 @@ ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels
auto n = kernels.size(); auto n = kernels.size();
#ifdef IFOPSH_WITH_OPENCASCADE #ifdef IFOPSH_WITH_OPENCASCADE
if (geometry_library_lower.find("opencascade", 0) == 0) { if (geometry_library_lower.find("opencascade", 0) == 0) {
kernels.push_back(new IfcGeom::OpenCascadeKernel(conv_settings)); kernels.emplace_back(new IfcGeom::OpenCascadeKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("opencascade")); geometry_library_lower = geometry_library_lower.substr(strlen("opencascade"));
} }
#endif #endif
#ifdef IFOPSH_WITH_CGAL #ifdef IFOPSH_WITH_CGAL
if (geometry_library_lower.find("cgal-simple", 0) == 0) { if (geometry_library_lower.find("cgal-simple", 0) == 0) {
kernels.push_back(new SimpleCgalKernel(conv_settings)); kernels.emplace_back(new SimpleCgalKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("cgal-simple")); geometry_library_lower = geometry_library_lower.substr(strlen("cgal-simple"));
} }
if (geometry_library_lower.find("cgal", 0) == 0) { if (geometry_library_lower.find("cgal", 0) == 0) {
kernels.push_back(new CgalKernel(conv_settings)); kernels.emplace_back(new CgalKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("cgal")); geometry_library_lower = geometry_library_lower.substr(strlen("cgal"));
} }
#endif #endif
if (kernels.size() != n + 1) { if (kernels.size() != n + 1) {
for (auto k : kernels)
delete k;
throw IfcParse::IfcException("Invalid hybrid kernel " + geometry_library); throw IfcParse::IfcException("Invalid hybrid kernel " + geometry_library);
} }
} }
@@ -217,7 +215,7 @@ ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels
} }
if (!kernels.empty()) { if (!kernels.empty()) {
return new HybridKernel(geometry_library, file, conv_settings, kernels); return new HybridKernel(geometry_library, file, conv_settings, std::move(kernels));
} }
} }
@@ -929,11 +929,11 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
bool is_2d = count(a, TopAbs_FACE) > 0 && count(a, TopAbs_SHELL) == 0; bool is_2d = count(a, TopAbs_FACE) > 0 && count(a, TopAbs_SHELL) == 0;
bool success = false; bool success = false;
BRepAlgoAPI_BooleanOperation* builder; std::unique_ptr<BRepAlgoAPI_BooleanOperation> builder;
TopTools_ListOfShape b_tmp; TopTools_ListOfShape b_tmp;
if (op == BOPAlgo_CUT) { if (op == BOPAlgo_CUT) {
builder = new BRepAlgoAPI_Cut(); builder.reset(new BRepAlgoAPI_Cut());
if (do_subtraction_eliminate_disjoint_bbox) { if (do_subtraction_eliminate_disjoint_bbox) {
PERF("boolean subtraction: eliminate disjoint bbox"); PERF("boolean subtraction: eliminate disjoint bbox");
@@ -968,9 +968,9 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
} }
} else if (op == BOPAlgo_COMMON) { } else if (op == BOPAlgo_COMMON) {
builder = new BRepAlgoAPI_Common(); builder.reset(new BRepAlgoAPI_Common());
} else if (op == BOPAlgo_FUSE) { } else if (op == BOPAlgo_FUSE) {
builder = new BRepAlgoAPI_Fuse(); builder.reset(new BRepAlgoAPI_Fuse());
} else { } else {
return false; return false;
} }
@@ -978,7 +978,6 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
if (b.Extent() == 0) { if (b.Extent() == 0) {
Logger::Warning("No other operands remaining, using first operand"); Logger::Warning("No other operands remaining, using first operand");
result = a; result = a;
delete builder;
return true; return true;
} }
@@ -1131,7 +1130,6 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
} else { } else {
Logger::Notice("Processed fully in 2D"); Logger::Notice("Processed fully in 2D");
result = mp.Shape(); result = mp.Shape();
delete builder;
return true; return true;
} }
} else { } else {
@@ -1431,7 +1429,6 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
Logger::Notice(str_str); Logger::Notice(str_str);
} }
} }
delete builder;
if (!success) { if (!success) {
if (allow_retry) { if (allow_retry) {
return boolean_operation(settings, a, b, op, result, new_fuzziness); return boolean_operation(settings, a, b, op, result, new_fuzziness);