From 250fad696e6cb7608572c36866e36b1d22103521 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 7 Oct 2024 20:47:01 +0200 Subject: [PATCH] --unify-shapes setting --- src/ifcgeom/AbstractKernel.h | 2 +- src/ifcgeom/ConversionSettings.h | 9 +- src/ifcgeom/Converter.cpp | 34 ++-- .../kernels/opencascade/OpenCascadeKernel.cpp | 173 +----------------- .../kernels/opencascade/OpenCascadeKernel.h | 25 +-- 5 files changed, 39 insertions(+), 204 deletions(-) diff --git a/src/ifcgeom/AbstractKernel.h b/src/ifcgeom/AbstractKernel.h index 630ade01ae..13a6a0441f 100644 --- a/src/ifcgeom/AbstractKernel.h +++ b/src/ifcgeom/AbstractKernel.h @@ -70,7 +70,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels { virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map&) { throw std::runtime_error("Not implemented"); } virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0; - + virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw std::runtime_error("Unification of shapes not implemented in this kernel"); } }; AbstractKernel* construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings); diff --git a/src/ifcgeom/ConversionSettings.h b/src/ifcgeom/ConversionSettings.h index 5a622daa98..a1506e20f2 100644 --- a/src/ifcgeom/ConversionSettings.h +++ b/src/ifcgeom/ConversionSettings.h @@ -201,6 +201,13 @@ namespace ifcopenshell { static constexpr bool defaultvalue = false; }; + struct UnifyShapes : public SettingBase { + static constexpr const char* const name = "unify-shapes"; + static constexpr const char* const description = "Unify adjacent co-planar and co-linear subshapes (topological entities " + "sharing the same geometric domain) before triangulation or further processing"; + static constexpr bool defaultvalue = false; + }; + struct UseMaterialNames : public SettingBase { static constexpr const char* const name = "use-material-names"; static constexpr const char* const description = "Use material names instead of unique IDs for naming materials upon serialization. " @@ -493,7 +500,7 @@ namespace ifcopenshell { }; class IFC_GEOM_API Settings : public SettingsContainer< - std::tuple + std::tuple > {}; } diff --git a/src/ifcgeom/Converter.cpp b/src/ifcgeom/Converter.cpp index d08cec8bb2..c806bb7b3e 100644 --- a/src/ifcgeom/Converter.cpp +++ b/src/ifcgeom/Converter.cpp @@ -208,29 +208,37 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe Logger::Message(Logger::LOG_ERROR, "Error processing openings for:", product); } - if (caught_error && opened_shapes.size() < shapes.size()) { - opened_shapes = shapes; - } - - if (settings_.get().get()) { - for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) { - it->prepend(place); + if (!(caught_error && opened_shapes.size() < shapes.size())) { + if (settings_.get().get()) { + for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) { + it->prepend(place); + } + place = ifcopenshell::geometry::taxonomy::make(); + representation_id_builder << "-world-coords"; } - place = ifcopenshell::geometry::taxonomy::make(); - representation_id_builder << "-world-coords"; + shapes = opened_shapes; } - shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), opened_shapes); } else if (settings_.get().get()) { for (auto it = shapes.begin(); it != shapes.end(); ++it) { it->prepend(place); } place = ifcopenshell::geometry::taxonomy::make(); representation_id_builder << "-world-coords"; - shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes); - } else { - shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes); } + if (settings_.get().get()) { + IfcGeom::ConversionResults unified_shapes; + try { + if (kernel_->unify_shapes(shapes, unified_shapes)) { + std::swap(shapes, unified_shapes); + } + } catch (std::exception& e) { + Logger::Error(e); + } + } + + shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes); + std::string context_string = ""; // IfcShapeRepresentation. diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp index 047372396d..2a66584464 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp @@ -23,175 +23,12 @@ * * ********************************************************************************/ -// #include -// #include -// #include -// -// #include -// -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// -// #include -// #include -// -// #include -// #include -// #include -// #include -// #include -// -// #include -// #include -// -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// -// #include -// #include -// #include -// #include -// -// #include -// #include -// -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #if OCC_VERSION_HEX >= 0x70200 -// #include -// #endif -// -// #include -// -// #include -// #include -// #include -// #include -// -// #include -// #include -// -// -// #include -// -// #include -// -// #include -// #include -// -// #include -// #include -// -// #include -// #include -// #include -// -// #include -// #include -// #include -// -// #include -// #include -// -// #include -// #include -// -// #include -// -// #include -// -// #include -// -// #include -// -// #include -// -// #include -// -// #if OCC_VERSION_HEX >= 0x70200 -// #include -// #endif -// -// #include "../../../ifcparse/macros.h" -// #include "../../../ifcparse/IfcSIPrefix.h" -// -// #include "../../../ifcparse/IfcFile.h" -// - #include "OpenCascadeKernel.h" -// #include "IfcGeomTree.h" - #include "boolean_utils.h" - -// #include "wire_utils.h" - #include "base_utils.h" -// #include "layerset.h" -// -// #include -// #include -// -// #if OCC_VERSION_HEX < 0x60900 -// #ifdef _MSC_VER -// #pragma message("warning: You are linking against Open CASCADE version " OCC_VERSION_COMPLETE ". Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade.") -// #else -// #warning "You are linking against an older version of Open CASCADE. Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade." -// #endif -// #endif -// -// namespace { -// struct POSTFIX_SCHEMA(factory_t) { -// IfcGeom::Kernel* operator()(IfcParse::IfcFile* file) const { -// IfcGeom::POSTFIX_SCHEMA(Kernel)* k = new IfcGeom::POSTFIX_SCHEMA(Kernel); -// if (file) { -// -// } -// return k; -// } -// }; -// } -// -// void MAKE_INIT_FN(KernelImplementation_)(IfcGeom::impl::KernelFactoryImplementation* mapping) { -// static const std::string schema_name = STRINGIFY(IfcSchema); -// POSTFIX_SCHEMA(factory_t) factory; -// mapping->bind(schema_name, factory); -// } -// -// #define Kernel POSTFIX_SCHEMA(Kernel) -// -// void IfcGeom::Kernel::set_offset(const std::array &p_offset) { -// offset = gp_Vec(p_offset[0], p_offset[1], p_offset[2]); -// -// offset_and_rotation = util::combine_offset_and_rotation(offset, rotation); -// } -// -// void IfcGeom::Kernel::set_rotation(const std::array &p_rotation) { -// rotation = gp_Quaternion(p_rotation[0], p_rotation[1], p_rotation[2], p_rotation[3]); -// -// offset_and_rotation = util::combine_offset_and_rotation(offset, rotation); -// } -// +#include namespace { struct opening_sorter { @@ -391,7 +228,13 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* return true; } -#include +bool IfcGeom::OpenCascadeKernel::unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output) { + std::transform(input.begin(), input.end(), std::back_inserter(output), [this](auto v) { + auto& s = std::static_pointer_cast(v.Shape())->shape(); + return IfcGeom::ConversionResult(v.ItemId(), new OpenCascadeShape(util::unify(s, settings_.get().get())), v.StylePtr()); + }); + return true; +} bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, IfcGeom::ConversionResults& results) { diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h index b5c6276488..8b98cbdf7a 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h @@ -79,22 +79,6 @@ private: bool non_manifold_; void loop_(const ifcopenshell::geometry::taxonomy::loop::ptr ps, const std::function& callback); - - /* - bool construct(const IfcSchema::IfcCartesianPoint* cp, gp_Pnt* l); - bool construct(const std::vector& cp, gp_Pnt* l); - - const void* get_idx(const IfcSchema::IfcCartesianPoint* cp) { - return cp; - } - - const void* get_idx(const std::vector& cp) { - return &cp; - } - - std::vector get_idxs(const IfcSchema::IfcPolyLoop* lp); - std::vector get_idxs(const std::vector& it); - */ public: faceset_helper(OpenCascadeKernel* kernel, const ifcopenshell::geometry::taxonomy::shell::ptr l); ~faceset_helper(); @@ -111,15 +95,7 @@ private: faceset_helper* faceset_helper_; - // @todo these should be moved to the mapping - /* - gp_Vec offset = gp_Vec{0.0, 0.0, 0.0}; - gp_Quaternion rotation = gp_Quaternion{}; - gp_Trsf offset_and_rotation = gp_Trsf(); - */ - double precision_; - public: OpenCascadeKernel(const ifcopenshell::geometry::Settings& settings) : AbstractKernel("opencascade", settings) @@ -150,6 +126,7 @@ public: virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes); + virtual bool unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output); typedef boost::variant curve_creation_visitor_result_type; curve_creation_visitor_result_type convert_curve(const ifcopenshell::geometry::taxonomy::ptr);