From 734c456fa53317d1bade8d76e2eda14088555979 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Tue, 15 Oct 2019 12:53:44 +0200 Subject: [PATCH 1/3] Properly adjust wire intersection tolerance based on vertex clustering --- src/ifcgeom/IfcGeomFunctions.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index b421adf1e1..6f8e3bc957 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -3684,7 +3684,9 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO // ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION)); const double eps = faceset_helper_ - ? faceset_helper_->epsilon() + // eps is added to both ends of the parametric domain, so 3. is chosen to be on the safe side here. + ? (faceset_helper_->epsilon() / 3.) + // @todo re-evaluate 2. here for the reasons above: : (std::min)(min_edge_length(wire) / 2., getValue(GV_PRECISION) * 10.); for (int i = 2; i < n; ++i) { From 503029733c7beff4b191167d50ca35b726c6abc7 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Tue, 15 Oct 2019 14:14:50 +0200 Subject: [PATCH 2/3] Fix face-face distance calc and hardcode tolerance independent of precision. --- src/ifcgeom/IfcGeomFunctions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 6f8e3bc957..c2639f94ea 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -456,7 +456,7 @@ namespace { if (cls.Perform(gp_Pnt2d(u, v)) == TopAbs_IN) { gp_Pnt test2; p1->D0(u, v, test2); - double w = gp_Vec(p1->Position().Direction().XYZ()).Dot(test2.XYZ() - test.XYZ()); + double w = std::abs(gp_Vec(p1->Position().Direction().XYZ()).Dot(test2.XYZ() - test.XYZ())); if (w < M) { M = w; } @@ -4165,7 +4165,7 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_, const TopTools_L } else if ((v = min_vertex_edge_distance(r, getValue(GV_PRECISION), fuzziness * 3.)) < fuzziness * 3.) { reason = 1; success = false; - } else if ((v = min_face_face_distance(r, fuzziness * 3.)) < fuzziness * 3.) { + } else if ((v = min_face_face_distance(r, 1.e-4)) < 1.e-4) { reason = 2; success = false; } From 4000fef4c77b1f5dcc2b63cbec0a5995abc64991 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Tue, 15 Oct 2019 15:06:51 +0200 Subject: [PATCH 3/3] Don't apply too many half space subtraction operands at once --- src/ifcgeom/IfcGeomShapes.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index 2741a2d9f0..8995d6b45a 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -501,9 +501,17 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape second_operands.push_back(operand2); if (occ_op == BOPAlgo_CUT) { - bool process_as_list = true; + int n_half_space_operands = 0; + bool process_as_list = false; while (true) { auto res1 = operand1->as(); + if (res1 && res1->SecondOperand()->as() && ++n_half_space_operands > 8) { + // There is something peculiar about many half space subtraction operands that OCCT does not like. + // Often these are used to create a semi-curved arch, as is the case in 693. Supplying all these + // operands at once apparently leads to too many edge-edge interference checks. + process_as_list = false; + break; + } if (res1) { if (res1->Operator() == op) { operand1 = res1->FirstOperand();