From 9e88954fbc3a2af1d424749e8069227a857c3c7e Mon Sep 17 00:00:00 2001 From: PavelMikus Date: Wed, 24 Aug 2022 11:36:41 +0200 Subject: [PATCH] Fix of issue 8695 - seam enforced areas were not respected with arachne generator. The real issue was with T-Junctions created by Arachne - seam placer then sometimes choose the wrong perimeter to split. The fix cases the seam placer to look for two consecutive points that point to the same perimeter, which enusres that the correct loop is split --- src/libslic3r/GCode/SeamPlacer.cpp | 38 ++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 6096d6075..613973875 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -1551,16 +1551,40 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern const size_t layer_index = layer->id() - po->slicing_parameters().raft_layers(); const double unscaled_z = layer->slice_z; + auto get_next_loop_point = [loop](ExtrusionLoop::ClosestPathPoint current) { + current.segment_idx += 1; + if (current.segment_idx >= loop.paths[current.path_idx].polyline.points.size()) { + current.path_idx = next_idx_modulo(current.path_idx, loop.paths.size()); + current.segment_idx = 0; + } + current.foot_pt = loop.paths[current.path_idx].polyline.points[current.segment_idx]; + return current; + }; + const PrintObjectSeamData::LayerSeams &layer_perimeters = m_seam_per_object.find(layer->object())->second.layers[layer_index]; - // Find the closest perimeter in the SeamPlacer to the first point of this loop. - size_t closest_perimeter_point_index; - { - const Point &fp = loop.first_point(); - Vec2f unscaled_p = unscaled(fp); - closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(), - to_3d(unscaled_p, float(unscaled_z))); + // Find the closest perimeter in the SeamPlacer to this loop. + // Repeat search until two consecutive points of the loop are found, that result in the same closest_perimeter + // This is beacuse with arachne, T-Junctions may exist and sometimes the wrong perimeter was chosen + size_t closest_perimeter_point_index = 0; + { // local space for the closest_perimeter_point_index + Perimeter *closest_perimeter = nullptr; + ExtrusionLoop::ClosestPathPoint closest_point{0,0,loop.paths[0].polyline.points[0]}; + size_t points_count = std::accumulate(loop.paths.begin(), loop.paths.end(), 0, [](size_t acc,const ExtrusionPath& p) { + return acc + p.polyline.points.size(); + }); + for (size_t _ = 0; _ < points_count; ++_) { + Vec2f unscaled_p = unscaled(closest_point.foot_pt); + closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(), + to_3d(unscaled_p, float(unscaled_z))); + if (closest_perimeter != &layer_perimeters.points[closest_perimeter_point_index].perimeter) { + closest_perimeter = &layer_perimeters.points[closest_perimeter_point_index].perimeter; + closest_point = get_next_loop_point(closest_point); + } else { + break; + } + } } Vec3f seam_position;