From 1aac99b809f44dab6abaef2414427e1ce9514c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Wed, 5 Jan 2022 11:11:29 +0100 Subject: [PATCH] Fix of #7618 (Crash in the multi-material segmentation when a negative volume was used on painted areas of a model.) --- src/libslic3r/MultiMaterialSegmentation.cpp | 25 ++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index 737514901..75537b6c6 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -1797,19 +1797,28 @@ std::vector> multi_material_segmentation_by_painting(con line_end_f = facet[1] + t2 * (facet[2] - facet[1]); } - Point line_start(scale_(line_start_f.x()), scale_(line_start_f.y())); - Point line_end(scale_(line_end_f.x()), scale_(line_end_f.y())); - line_start -= print_object.center_offset(); - line_end -= print_object.center_offset(); + Line line_to_test(Point(scale_(line_start_f.x()), scale_(line_start_f.y())), + Point(scale_(line_end_f.x()), scale_(line_end_f.y()))); + line_to_test.translate(-print_object.center_offset()); + + // BoundingBoxes for EdgeGrids are computed from printable regions. It is possible that the painted line (line_to_test) could + // be outside EdgeGrid's BoundingBox, for example, when the negative volume is used on the painted area (GH #7618). + // To ensure that the painted line is always inside EdgeGrid's BoundingBox, it is clipped by EdgeGrid's BoundingBox in cases + // when any of the endpoints of the line are outside the EdgeGrid's BoundingBox. + if (const BoundingBox &edge_grid_bbox = edge_grids[layer_idx].bbox(); !edge_grid_bbox.contains(line_to_test.a) || !edge_grid_bbox.contains(line_to_test.b)) { + // If the painted line (line_to_test) is entirely outside EdgeGrid's BoundingBox, skip this painted line. + if (!edge_grid_bbox.overlap(BoundingBox(Points{line_to_test.a, line_to_test.b})) || + !line_to_test.clip_with_bbox(edge_grid_bbox)) + continue; + } size_t mutex_idx = layer_idx & 0x3F; assert(mutex_idx < painted_lines_mutex.size()); PaintedLineVisitor visitor(edge_grids[layer_idx], painted_lines[layer_idx], painted_lines_mutex[mutex_idx], 16); - visitor.line_to_test.a = line_start; - visitor.line_to_test.b = line_end; - visitor.color = int(extruder_idx); - edge_grids[layer_idx].visit_cells_intersecting_line(line_start, line_end, visitor); + visitor.line_to_test = line_to_test; + visitor.color = int(extruder_idx); + edge_grids[layer_idx].visit_cells_intersecting_line(line_to_test.a, line_to_test.b, visitor); } } }); // end of parallel_for