diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index 8b5cbf483..56b12e56e 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -20,29 +20,48 @@ namespace Slic3r { template std::vector> chain_segments_closest_point(std::vector &end_points, KDTreeType &kdtree, CouldReverseFunc &could_reverse_func, EndPointType &first_point) { + //check pair assert((end_points.size() & 1) == 0); size_t num_segments = end_points.size() / 2; assert(num_segments >= 2); + //set all points to "ungrabbed" for (EndPointType &ep : end_points) ep.chain_id = 0; + //create output struct idx_seg, reversed std::vector> out; out.reserve(num_segments); + //put first point (idx/2 = segment_id ; first_point_idx & 1 => 0 if seg_start, !0 if seg_end) size_t first_point_idx = &first_point - end_points.data(); out.emplace_back(first_point_idx / 2, (first_point_idx & 1) != 0); + //set the fisrt point as taken first_point.chain_id = 1; + //now switch to the other end of the segment size_t this_idx = first_point_idx ^ 1; + //add all other segments for (int iter = (int)num_segments - 2; iter >= 0; -- iter) { EndPointType &this_point = end_points[this_idx]; - this_point.chain_id = 1; - // Find the closest point to this end_point, which lies on a different extrusion path (filtered by the lambda). - // Ignore the starting point as the starting point is considered to be occupied, no end point coud connect to it. + //set the current point as taken + this_point.chain_id = 1; + // Find the closest point to this end_point, which lies on a different extrusion path (filtered by the lambda). + // Ignore the starting point as the starting point is considered to be occupied, no end point coud connect to it. size_t next_idx = find_closest_point(kdtree, this_point.pos, [this_idx, &end_points, &could_reverse_func](size_t idx) { - return (idx ^ this_idx) > 1 && end_points[idx].chain_id == 0 && ((idx ^ 1) == 0 || could_reverse_func(idx >> 1)); + return + // ???? + //(idx ^ this_idx) > 1 && + // only consider untaken points + end_points[idx].chain_id == 0 + // only consider seg_start if can't be reversed + && ((idx & 1) == 0 || could_reverse_func(idx >> 1) + //don't consider erased segments + && this_idx < end_points.size()); }); assert(next_idx < end_points.size()); EndPointType &end_point = end_points[next_idx]; + //set the new entry point as taken end_point.chain_id = 1; + out.emplace_back(next_idx / 2, (next_idx & 1) != 0); + //now switch to the other end of the segment this_idx = next_idx ^ 1; } #ifndef NDEBUG @@ -72,8 +91,11 @@ std::vector> chain_segments_greedy_constrained_reversals else if (num_segments == 1) { // Just sort the end points so that the first point visited is closest to start_near. - out.emplace_back(0, start_near != nullptr && - (end_point_func(0, true) - *start_near).template cast().squaredNorm() < (end_point_func(0, false) - *start_near).template cast().squaredNorm()); + if (could_reverse_func(0)) + out.emplace_back(0, start_near != nullptr && + (end_point_func(0, true) - *start_near).template cast().squaredNorm() < (end_point_func(0, false) - *start_near).template cast().squaredNorm()); + else + out.emplace_back(0, false); } else {