From 20b3a8af3ebc6d120506f59d5fdcef47f12e44a7 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 10 Dec 2018 10:45:58 +0100 Subject: [PATCH] Faceset_helper: no recursive clustering, epsilon relative to bounds --- src/ifcgeom/IfcGeomFunctions.cpp | 48 +++++++++++++++++++------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 81141fdb6c..0bd94f8124 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -149,6 +149,8 @@ #include "../ifcgeom/IfcGeom.h" #include "../ifcgeom/IfcGeomTree.h" +#include + #if OCC_VERSION_HEX < 0x60900 #ifdef _MSC_VER #pragma message("warning: You are linking against Open CASCADE version " OCC_VERSION_COMPLETE ". Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade.") @@ -3496,20 +3498,23 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopoDS_Shap #endif namespace { - void find_neighbours(IfcGeom::impl::tree& tree, std::vector& pnts, std::set& visited, int p, double eps) { + void find_neighbours(IfcGeom::impl::tree& tree, std::vector>& pnts, std::set& visited, int p, double eps) { visited.insert(p); Bnd_Box b; - b.Set(pnts[p]); + b.Set(*pnts[p].get()); b.Enlarge(eps); std::vector js = tree.select_box(b, false); for (int j : js) { + visited.insert(j); +#ifdef FACESET_HELPER_RECURSIVE if (visited.find(j) == visited.end()) { // @todo, making this recursive removes the dependence on the initial ordering, but will // likely result in empty results when all vertices are within 1 eps from another point. find_neighbours(tree, pnts, visited, j, eps); } +#endif } } } @@ -3524,34 +3529,39 @@ IfcGeom::Kernel::faceset_helper::faceset_helper(Kernel* kernel, const IfcSchema: kernel->faceset_helper_ = this; IfcSchema::IfcCartesianPoint::list::ptr points = IfcParse::traverse((IfcUtil::IfcBaseClass*) l)->as(); - std::vector pnts(std::distance(points->begin(), points->end())); + std::vector> pnts(std::distance(points->begin(), points->end())); std::vector vertices(pnts.size()); + IfcGeom::impl::tree tree; + BRep_Builder B; - const double eps = kernel->getValue(GV_PRECISION) * 10.; - IfcGeom::impl::tree tree; - { - int i = 0; - for (auto& pt : *points) { - if (kernel->convert(pt, pnts[i])) { - B.MakeVertex(vertices[i], pnts[i], Precision::Confusion()); - tree.add(i, vertices[i]); - i++; - } - } + Bnd_Box box; + for (size_t i = 0; i < points->size(); ++i) { + gp_Pnt* p = new gp_Pnt(); + if (kernel->convert(*(points->begin() + i), *p)) { + pnts[i].reset(p); + B.MakeVertex(vertices[i], *p, Precision::Confusion()); + tree.add(i, vertices[i]); + box.Add(*p); + } else { + delete p; + } } + const double eps = kernel->getValue(GV_PRECISION) * 10. * std::sqrt(box.SquareExtent()); + std::map, int> edge_use; for (int i = 0; i < pnts.size(); ++i) { - std::set vs; - find_neighbours(tree, pnts, vs, i, eps); + if (pnts[i]) { + std::set vs; + find_neighbours(tree, pnts, vs, i, eps); - for (int v : vs) { - if (v <= i) { + for (int v : vs) { auto pt = *(points->begin() + v); - vertex_mapping_[pt->data().id()] = i; + // NB: insert() ignores duplicate keys + vertex_mapping_.insert({ pt->data().id() , i }); } } }