mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 01:07:57 -06:00
Working on improved interconnection strategy
This commit is contained in:
parent
f2f513dd3e
commit
c2d5a8d03b
2 changed files with 277 additions and 108 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue