Skip to content

Commit 2eaae2b

Browse files
committed
Use BVH tree for wire intersections
1 parent 229a708 commit 2eaae2b

2 files changed

Lines changed: 45 additions & 9 deletions

File tree

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
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>
@@ -143,6 +146,7 @@
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(

src/ifcparse/IfcLogger.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ namespace {
4242
}
4343
os << message << std::endl;
4444
if (entity) {
45-
os << entity->toString() << std::endl;
45+
std::string instance_string = entity->toString();
46+
if (instance_string.size() > 259) {
47+
instance_string = instance_string.substr(0, 256) + "...";
48+
}
49+
os << instance_string << std::endl;
4650
}
4751
}
4852

0 commit comments

Comments
 (0)