4444#include < gp_Pln.hxx>
4545#include < gp_Circ.hxx>
4646
47+ #include < boost/range/irange.hpp>
48+ #include < boost/range/algorithm_ext/push_back.hpp>
49+
4750#include < TColgp_Array1OfPnt.hxx>
4851#include < TColgp_Array1OfPnt2d.hxx>
4952#include < TColStd_Array1OfReal.hxx>
143146#include " ../ifcparse/IfcSIPrefix.h"
144147#include " ../ifcparse/IfcFile.h"
145148#include " ../ifcgeom/IfcGeom.h"
149+ #include " ../ifcgeom/IfcGeomTree.h"
146150
147151#if OCC_VERSION_HEX < 0x60900
148152#ifdef _MSC_VER
@@ -2876,10 +2880,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
28762880 }
28772881
28782882 int n = count (wire, TopAbs_EDGE);
2879- if (n < 3 || n > 128 ) {
2880- if (n > 128 ) {
2881- Logger::Notice (" Too many segments for detection of self-intersections" );
2882- }
2883+ if (n < 3 ) {
28832884 wires.Append (wire);
28842885 return false ;
28852886 }
@@ -2889,22 +2890,53 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
28892890
28902891 // ... to be sure to get consecutive edges
28912892 BRepTools_WireExplorer exp (wire);
2893+ IfcGeom::impl::tree<int > tree;
2894+
2895+ int edge_idx = 0 ;
28922896 for (; exp.More (); exp.Next ()) {
28932897 wd->Add (exp.Current ());
2898+ if (n > 64 ) {
2899+ // tfk: indices in tree are 0-based vd 1-based in wiredata
2900+ tree.add (edge_idx++, exp.Current ());
2901+ }
28942902 }
28952903
28962904 bool intersected = false ;
28972905
28982906 // tfk: Extrema on infinite curves proved to be more robust.
28992907 // TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face();
29002908 // ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION));
2901-
2909+
2910+ const double eps = getValue (GV_PRECISION) * 10 .;
2911+
29022912 for (int i = 2 ; i < n; ++i) {
2903- for (int j = 0 ; j < i - 1 ; ++j) {
2904- if (i == n - 1 && j == 0 ) continue ;
29052913
2914+ std::vector<int > js;
2915+ if (n > 64 ) {
2916+ Bnd_Box b;
2917+ BRepBndLib::Add (wd->Edge (i + 1 ), b);
2918+ b.Enlarge (eps);
2919+ js = tree.select_box (b, false );
2920+ } else {
2921+ boost::push_back (js, boost::irange (0 , i - 1 ));
2922+ }
2923+
2924+ for (std::vector<int >::const_iterator it = js.begin (); it != js.end (); ++it) {
2925+ int j = *it;
2926+
2927+ if (n > 64 ) {
2928+ if (j > i) {
2929+ continue ;
2930+ }
2931+ if ((std::max)(i, j) - (std::min)(i, j) <= 1 ) {
2932+ continue ;
2933+ }
2934+ }
2935+
2936+ // Only check non-consecutive edges
2937+ if (i == n - 1 && j == 0 ) continue ;
2938+
29062939 bool unbounded_intersects;
2907- const double eps = getValue (GV_PRECISION) * 10 .;
29082940
29092941 double u11, u12, u21, u22, U1, U2;
29102942 GeomAPI_ExtremaCurveCurve ecc (
0 commit comments