From 6246dda8d69b47e905f62b094cb4754971a145db Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sun, 9 Jan 2022 15:15:29 +0100 Subject: [PATCH] #1960 make configurable --- src/ifcconvert/IfcConvert.cpp | 3 +++ src/ifcgeom/IfcGeom.h | 1 + src/ifcgeom/IfcGeomFunctions.cpp | 14 ++++++++++---- src/ifcgeom/IfcGeomIteratorImplementation.h | 6 ++++++ src/ifcgeom/IfcGeomIteratorSettings.h | 6 ++++-- src/ifcgeom_schema_agnostic/Kernel.h | 3 ++- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 73a950c3ae..e327d350c0 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -305,6 +305,8 @@ int main(int argc, char** argv) { ("disable-boolean-results", "Specifies whether to disable the boolean operation within representations " "such as clippings by means of IfcBooleanResult and subtypes") + ("no-2d-boolean", + "Do not attempt to process boolean subtractions in 2D.") ("enable-layerset-slicing", "Specifies whether to enable the slicing of products according " "to their associated IfcMaterialLayerSet.") @@ -817,6 +819,7 @@ int main(int argc, char** argv) { settings.set(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_CHECK, no_wire_intersection_check); settings.set(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_TOLERANCE, no_wire_intersection_tolerance); settings.set(IfcGeom::IteratorSettings::STRICT_TOLERANCE, strict_tolerance); + settings.set(IfcGeom::IteratorSettings::BOOLEAN_ATTEMPT_2D, !vmap.count("no-2d-boolean")); settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names); settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids); diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 67670f2feb..85564d93cb 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -274,6 +274,7 @@ private: double no_wire_intersection_tolerance; double precision_factor; double boolean_debug_setting; + double boolean_attempt_2d; size_t operation_counter_ = 0; diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index d6c42132dd..de929b9de6 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1782,6 +1782,9 @@ void IfcGeom::Kernel::setValue(GeomValue var, double value) { case GV_DEBUG_BOOLEAN: boolean_debug_setting = value; break; + case GV_BOOLEAN_ATTEMPT_2D: + boolean_attempt_2d = value; + break; default: throw std::runtime_error("Invalid setting"); } @@ -1819,6 +1822,8 @@ double IfcGeom::Kernel::getValue(GeomValue var) const { return no_wire_intersection_tolerance; case GV_DEBUG_BOOLEAN: return boolean_debug_setting; + case GV_BOOLEAN_ATTEMPT_2D: + return boolean_attempt_2d; } throw std::runtime_error("Invalid setting"); } @@ -4665,8 +4670,8 @@ namespace { if (u11 < U1 && U1 < u12 && u21 < U2 && U2 < u22) { // Edge curves belonging to different operands intersect, don't process // using builder. - return false; Logger::Notice("Intersecting boundaries"); + return false; } } } @@ -4772,8 +4777,9 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_input, const TopTo const bool do_unify = true; const bool do_subtraction_eliminate_disjoint_bbox = true; const bool do_subtraction_eliminate_touching = true; - + const bool do_attempt_2d_boolean = getValue(GV_BOOLEAN_ATTEMPT_2D) > 0.; const bool debug = getValue(GV_DEBUG_BOOLEAN) > 0.; + std::string debug_identifier; if (debug) { std::stringstream ss; @@ -4906,8 +4912,8 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_input, const TopTo TopTools_ListOfShape b_faces, b_remainder_3d; - bool is_extrusion_a; - { + bool is_extrusion_a = false; + if (do_attempt_2d_boolean) { PERF("boolean subtraction: extrusion check"); is_extrusion_a = is_extrusion(gp::DY(), a, a_face, a_interval); diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.h b/src/ifcgeom/IfcGeomIteratorImplementation.h index fae39da274..24074078ef 100644 --- a/src/ifcgeom/IfcGeomIteratorImplementation.h +++ b/src/ifcgeom/IfcGeomIteratorImplementation.h @@ -1173,6 +1173,12 @@ namespace IfcGeom { : -1.0 ); + kernel.setValue(IfcGeom::Kernel::GV_BOOLEAN_ATTEMPT_2D, + settings.get(IteratorSettings::BOOLEAN_ATTEMPT_2D) + ? +1.0 + : -1.0 + ); + if (settings.get(IteratorSettings::BUILDING_LOCAL_PLACEMENT)) { if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) { Logger::Message(Logger::LOG_WARNING, "building-local-placement takes precedence over site-local-placement"); diff --git a/src/ifcgeom/IfcGeomIteratorSettings.h b/src/ifcgeom/IfcGeomIteratorSettings.h index a525986cb5..0211fc5758 100644 --- a/src/ifcgeom/IfcGeomIteratorSettings.h +++ b/src/ifcgeom/IfcGeomIteratorSettings.h @@ -113,12 +113,14 @@ namespace IfcGeom STRICT_TOLERANCE = 1 << 22, /// Write boolean operands to file in current directory for debugging purposes DEBUG_BOOLEAN = 1 << 23, + /// Try to perform boolean subtractions in 2d. Defaults to true. + BOOLEAN_ATTEMPT_2D = 1 << 24, /// Number of different setting flags. - NUM_SETTINGS = 24, + NUM_SETTINGS = 25, }; IteratorSettings() - : settings_(WELD_VERTICES) // OR options that default to true here + : settings_(WELD_VERTICES | BOOLEAN_ATTEMPT_2D) // OR options that default to true here , deflection_tolerance_(1.e-3) , angular_tolerance_(0.5) { diff --git a/src/ifcgeom_schema_agnostic/Kernel.h b/src/ifcgeom_schema_agnostic/Kernel.h index f13178e6ef..3aab1e4632 100644 --- a/src/ifcgeom_schema_agnostic/Kernel.h +++ b/src/ifcgeom_schema_agnostic/Kernel.h @@ -76,7 +76,8 @@ namespace IfcGeom { GV_NO_WIRE_INTERSECTION_CHECK, GV_PRECISION_FACTOR, GV_NO_WIRE_INTERSECTION_TOLERANCE, - GV_DEBUG_BOOLEAN + GV_DEBUG_BOOLEAN, + GV_BOOLEAN_ATTEMPT_2D }; Kernel(IfcParse::IfcFile* file_ = 0);