diff options
author | tamasmeszaros <meszaros.q@gmail.com> | 2019-03-04 20:32:28 +0300 |
---|---|---|
committer | tamasmeszaros <meszaros.q@gmail.com> | 2019-03-04 20:32:28 +0300 |
commit | c2d5a8d03b4974fe2793eb666f296b7d318347db (patch) | |
tree | 773d197187ac51a9b69a6623b2f8ceab1d3c89b1 /src/libslic3r/SLA/SLASupportTreeIGL.cpp | |
parent | f2f513dd3e1077c8b36c0a3f5c083ff2e4ea7eb8 (diff) |
Working on improved interconnection strategy
Diffstat (limited to 'src/libslic3r/SLA/SLASupportTreeIGL.cpp')
-rw-r--r-- | src/libslic3r/SLA/SLASupportTreeIGL.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/libslic3r/SLA/SLASupportTreeIGL.cpp b/src/libslic3r/SLA/SLASupportTreeIGL.cpp index da2bb1b79..bd2d16215 100644 --- a/src/libslic3r/SLA/SLASupportTreeIGL.cpp +++ b/src/libslic3r/SLA/SLASupportTreeIGL.cpp @@ -347,6 +347,95 @@ PointSet normals(const PointSet& points, return ret; } +//template<class Vec> double distance(const Vec& p) { +// return std::sqrt(p.transpose() * p); +//} + +//template<class Vec> double distance(const Vec& pp1, const Vec& pp2) { +// auto p = pp2 - pp1; +// return distance(p); +//} + +// Clustering a set of points by the given criteria +ClusteredPoints cluster_nearest2d( + const sla::PointSet& points, const std::vector<unsigned>& indices, + double dist, + unsigned max_points = 0) +{ + + namespace bgi = boost::geometry::index; + using Index3D = bgi::rtree< SpatElement, bgi::rstar<16, 4> /* ? */ >; + + // A spatial index for querying the nearest points + Index3D sindex; + + // Build the index + for(unsigned idx : indices) { + Vec3d p = points.row(idx); p(Z) = 0; + sindex.insert( std::make_pair(points.row(idx), idx)); + } + + using Elems = std::vector<SpatElement>; + + // Recursive function for visiting all the points in a given distance to + // each other + std::function<void(Elems&, Elems&)> group = + [&sindex, &group, max_points, dist](Elems& pts, Elems& cluster) + { + for(auto& p : pts) { + std::vector<SpatElement> tmp; + + sindex.query( + bgi::nearest(p.first, max_points), + std::back_inserter(tmp) + ); + + for(auto it = tmp.begin(); it < tmp.end(); ++it) + if(distance(p.first, it->first) > dist) it = tmp.erase(it); + + auto cmp = [](const SpatElement& e1, const SpatElement& e2){ + return e1.second < e2.second; + }; + + std::sort(tmp.begin(), tmp.end(), cmp); + + Elems newpts; + std::set_difference(tmp.begin(), tmp.end(), + cluster.begin(), cluster.end(), + std::back_inserter(newpts), cmp); + + int c = max_points && newpts.size() + cluster.size() > max_points? + int(max_points - cluster.size()) : int(newpts.size()); + + cluster.insert(cluster.end(), newpts.begin(), newpts.begin() + c); + std::sort(cluster.begin(), cluster.end(), cmp); + + if(!newpts.empty() && (!max_points || cluster.size() < max_points)) + group(newpts, cluster); + } + }; + + std::vector<Elems> clusters; + for(auto it = sindex.begin(); it != sindex.end();) { + Elems cluster = {}; + Elems pts = {*it}; + group(pts, cluster); + + for(auto& c : cluster) sindex.remove(c); + it = sindex.begin(); + + clusters.emplace_back(cluster); + } + + ClusteredPoints result; + for(auto& cluster : clusters) { + result.emplace_back(); + for(auto c : cluster) result.back().emplace_back(c.second); + } + + return result; +} + // Clustering a set of points by the given criteria ClusteredPoints cluster( const sla::PointSet& points, const std::vector<unsigned>& indices, |