diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index dfdf468dd2..efa1624be6 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -340,7 +340,8 @@ int main(int argc, char** argv) { "Specifies a material file that describes the material object types will have" "if an object does not have any specified material in the IFC file.") ("validate", "Checks whether geometrical output conforms to the included explicit quantities.") - ("no-wire-intersection-check", "Skip wire intersection check"); + ("no-wire-intersection-check", "Skip wire intersection check") + ("strict-tolerance", "Use strict tolerance for detecting wire intersections"); std::string bounds; #ifdef HAVE_ICU @@ -483,6 +484,7 @@ int main(int argc, char** argv) { const bool validate = vmap.count("validate") != 0; const bool edge_arrows = vmap.count("edge-arrows") != 0; const bool no_wire_intersection_check = vmap.count("no-wire-intersection-check") != 0; + const bool strict_tolerance = vmap.count("strict-tolerance") != 0; if (!quiet || vmap.count("version")) { print_version(); @@ -744,6 +746,7 @@ int main(int argc, char** argv) { settings.set(IfcGeom::IteratorSettings::BUILDING_LOCAL_PLACEMENT, building_local_placement); settings.set(IfcGeom::IteratorSettings::VALIDATE_QUANTITIES, validate); settings.set(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_CHECK, no_wire_intersection_check); + settings.set(IfcGeom::IteratorSettings::STRICT_TOLERANCE, strict_tolerance); 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 3a2fa22883..83c4843fd8 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -225,6 +225,7 @@ private: double dimensionality; double layerset_first; double no_wire_intersection_check; + double precision_factor; // For stopping PlacementRelTo recursion in convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) const IfcParse::declaration* placement_rel_to; @@ -258,6 +259,7 @@ public: , layerset_first(-1.) , disable_boolean_result(-1.) , no_wire_intersection_check(-1) + , precision_factor(10.) {} MAKE_TYPE_NAME(Kernel)(const MAKE_TYPE_NAME(Kernel)& other) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index c6d0f964c4..837054fa72 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1418,6 +1418,9 @@ void IfcGeom::Kernel::setValue(GeomValue var, double value) { case GV_NO_WIRE_INTERSECTION_CHECK: no_wire_intersection_check = value; break; + case GV_PRECISION_FACTOR: + precision_factor = value; + break; default: throw std::runtime_error("Invalid setting"); } @@ -1449,6 +1452,8 @@ double IfcGeom::Kernel::getValue(GeomValue var) const { return disable_boolean_result; case GV_NO_WIRE_INTERSECTION_CHECK: return no_wire_intersection_check; + case GV_PRECISION_FACTOR: + return precision_factor; } throw std::runtime_error("Invalid setting"); } diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.h b/src/ifcgeom/IfcGeomIteratorImplementation.h index 18b1a8edaa..98b788030c 100644 --- a/src/ifcgeom/IfcGeomIteratorImplementation.h +++ b/src/ifcgeom/IfcGeomIteratorImplementation.h @@ -350,7 +350,7 @@ namespace IfcGeom { if (any_precision_encountered) { // Some arbitrary factor that has proven to work better for the models in the set of test files. - lowest_precision_encountered *= 10.; + lowest_precision_encountered *= kernel.getValue(IfcGeom::Kernel::GV_PRECISION_FACTOR); lowest_precision_encountered *= unit_magnitude; if (lowest_precision_encountered < 1.e-7) { @@ -1008,6 +1008,11 @@ namespace IfcGeom { ? +1.0 : -1.0 ); + kernel.setValue(IfcGeom::Kernel::GV_PRECISION_FACTOR, + settings.get(IteratorSettings::STRICT_TOLERANCE) + ? 1.0 + : 10.0 + ); kernel.setValue(IfcGeom::Kernel::GV_DISABLE_BOOLEAN_RESULT, settings.get(IteratorSettings::DISABLE_BOOLEAN_RESULT) diff --git a/src/ifcgeom/IfcGeomIteratorSettings.h b/src/ifcgeom/IfcGeomIteratorSettings.h index a589d99988..bf615237bf 100644 --- a/src/ifcgeom/IfcGeomIteratorSettings.h +++ b/src/ifcgeom/IfcGeomIteratorSettings.h @@ -96,9 +96,10 @@ namespace IfcGeom DISABLE_BOOLEAN_RESULT = 1 << 20, // Disables wire intersection checks NO_WIRE_INTERSECTION_CHECK = 1 << 21, - + // Sets kernel precision factor to 1 + STRICT_TOLERANCE = 1 << 22, /// Number of different setting flags. - NUM_SETTINGS = 21, + NUM_SETTINGS = 22, }; /// Used to store logical OR combination of setting flags. typedef unsigned SettingField; diff --git a/src/ifcgeom_schema_agnostic/Kernel.h b/src/ifcgeom_schema_agnostic/Kernel.h index a7d7ac2fd8..36f07d2549 100644 --- a/src/ifcgeom_schema_agnostic/Kernel.h +++ b/src/ifcgeom_schema_agnostic/Kernel.h @@ -55,7 +55,8 @@ namespace IfcGeom { GV_DIMENSIONALITY, GV_LAYERSET_FIRST, GV_DISABLE_BOOLEAN_RESULT, - GV_NO_WIRE_INTERSECTION_CHECK + GV_NO_WIRE_INTERSECTION_CHECK, + GV_PRECISION_FACTOR, }; Kernel(IfcParse::IfcFile* file_ = 0);