diff --git a/src/libslic3r/BranchingTree/BranchingTree.cpp b/src/libslic3r/BranchingTree/BranchingTree.cpp index b101f38aa2..d690b2cc4d 100644 --- a/src/libslic3r/BranchingTree/BranchingTree.cpp +++ b/src/libslic3r/BranchingTree/BranchingTree.cpp @@ -11,14 +11,15 @@ namespace Slic3r { namespace branchingtree { void build_tree(PointCloud &nodes, Builder &builder) { - constexpr size_t ReachablesToExamine = 5; + constexpr size_t initK = 5; auto ptsqueue = nodes.start_queue(); auto &properties = nodes.properties(); struct NodeDistance { size_t node_id = Node::ID_NONE; float distance = NaNf; }; - auto distances = reserve_vector(ReachablesToExamine); + auto distances = reserve_vector(initK); double prev_dist_max = 0.; + size_t K = initK; while (!ptsqueue.empty() && builder.is_valid()) { size_t node_id = ptsqueue.top(); @@ -27,13 +28,13 @@ void build_tree(PointCloud &nodes, Builder &builder) nodes.mark_unreachable(node_id); distances.clear(); + distances.reserve(K); - nodes.foreach_reachable( + nodes.foreach_reachable( node.pos, [&distances](size_t id, float distance) { distances.emplace_back(NodeDistance{id, distance}); - }, - prev_dist_max); + }, K, prev_dist_max); std::sort(distances.begin(), distances.end(), [](auto &a, auto &b) { return a.distance < b.distance; }); @@ -41,11 +42,13 @@ void build_tree(PointCloud &nodes, Builder &builder) if (distances.empty()) { builder.report_unroutable(node); ptsqueue.pop(); + K = initK; prev_dist_max = 0.; continue; } prev_dist_max = distances.back().distance; + K *= 2; auto closest_it = distances.begin(); bool routed = false; @@ -146,6 +149,7 @@ void build_tree(PointCloud &nodes, Builder &builder) if (routed) { ptsqueue.pop(); prev_dist_max = 0.; + K = initK; } } diff --git a/src/libslic3r/BranchingTree/PointCloud.hpp b/src/libslic3r/BranchingTree/PointCloud.hpp index de4afc2a10..e781aad010 100644 --- a/src/libslic3r/BranchingTree/PointCloud.hpp +++ b/src/libslic3r/BranchingTree/PointCloud.hpp @@ -185,8 +185,11 @@ public: size_t reachable_count() const { return m_reachable_cnt; } - template - void foreach_reachable(const Vec3f &pos, Fn &&visitor, double min_dist = 0.) + template + void foreach_reachable(const Vec3f &pos, + Fn &&visitor, + size_t k, + double min_dist = 0.) { // Fake output iterator struct Output { @@ -203,14 +206,15 @@ public: namespace bgi = boost::geometry::index; - size_t cnt = 0; - auto filter = bgi::satisfies([this, &pos, min_dist, &cnt](const PointIndexEl &e) { - double d = get_distance(pos, e.second); - cnt++; - return m_searchable_indices[e.second] && !isinf(d) && d > min_dist; - }); + size_t cnt = 0; + auto filter = bgi::satisfies( + [this, &pos, min_dist, &cnt](const PointIndexEl &e) { + cnt++; + double d = get_distance(pos, e.second); + return m_searchable_indices[e.second] && !isinf(d) && d > min_dist; + }); - m_ktree.query(bgi::nearest(pos, K) && filter, Output{this, pos, visitor}); + m_ktree.query(bgi::nearest(pos, k) && filter, Output{this, pos, visitor}); } auto start_queue()