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
This commit is contained in:
PavelMikus 2022-08-24 11:36:41 +02:00
parent 106bf141af
commit 9e88954fbc

View File

@ -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 size_t layer_index = layer->id() - po->slicing_parameters().raft_layers();
const double unscaled_z = layer->slice_z; 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 = const PrintObjectSeamData::LayerSeams &layer_perimeters =
m_seam_per_object.find(layer->object())->second.layers[layer_index]; 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. // Find the closest perimeter in the SeamPlacer to this loop.
size_t closest_perimeter_point_index; // 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
const Point &fp = loop.first_point(); size_t closest_perimeter_point_index = 0;
Vec2f unscaled_p = unscaled<float>(fp); { // local space for the closest_perimeter_point_index
closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(), Perimeter *closest_perimeter = nullptr;
to_3d(unscaled_p, float(unscaled_z))); 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<float>(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; Vec3f seam_position;