Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Hejl <hejl.lukas@gmail.com>2022-08-11 17:21:57 +0300
committerLukáš Hejl <hejl.lukas@gmail.com>2022-08-12 10:48:34 +0300
commitf60b88ba3edd40144ae8c7f564394ce191f1f467 (patch)
tree31ecda985f9dffd2db5dcef22bb436f05e74d3a6
parente838acdcd18e3d6ce889f73b75548a986018dfdc (diff)
Fix of #8597 - Assert on Windows about decrementing of std::vector::begin() in a specific case.
-rw-r--r--src/libslic3r/Arachne/WallToolPaths.cpp54
-rw-r--r--tests/libslic3r/test_arachne.cpp35
2 files changed, 55 insertions, 34 deletions
diff --git a/src/libslic3r/Arachne/WallToolPaths.cpp b/src/libslic3r/Arachne/WallToolPaths.cpp
index 3552f6680..8399ae06e 100644
--- a/src/libslic3r/Arachne/WallToolPaths.cpp
+++ b/src/libslic3r/Arachne/WallToolPaths.cpp
@@ -329,60 +329,46 @@ void removeSmallAreas(Polygons &thiss, const double min_area_size, const bool re
};
auto new_end = thiss.end();
- if(remove_holes)
- {
- for(auto it = thiss.begin(); it < new_end; it++)
- {
- // All polygons smaller than target are removed by replacing them with a polygon from the back of the vector
- if(fabs(ClipperLib::Area(to_path(*it))) < min_area_size)
- {
- new_end--;
+ if (remove_holes) {
+ for (auto it = thiss.begin(); it < new_end;) {
+ // All polygons smaller than target are removed by replacing them with a polygon from the back of the vector.
+ if (fabs(ClipperLib::Area(to_path(*it))) < min_area_size) {
+ --new_end;
*it = std::move(*new_end);
- it--; // wind back the iterator such that the polygon just swaped in is checked next
+ continue; // Don't increment the iterator such that the polygon just swapped in is checked next.
}
+ ++it;
}
- }
- else
- {
+ } else {
// For each polygon, computes the signed area, move small outlines at the end of the vector and keep pointer on small holes
std::vector<Polygon> small_holes;
- for(auto it = thiss.begin(); it < new_end; it++) {
- double area = ClipperLib::Area(to_path(*it));
- if (fabs(area) < min_area_size)
- {
- if(area >= 0)
- {
- new_end--;
- if(it < new_end) {
+ for (auto it = thiss.begin(); it < new_end;) {
+ if (double area = ClipperLib::Area(to_path(*it)); fabs(area) < min_area_size) {
+ if (area >= 0) {
+ --new_end;
+ if (it < new_end) {
std::swap(*new_end, *it);
- it--;
- }
- else
- { // Don't self-swap the last Path
+ continue;
+ } else { // Don't self-swap the last Path
break;
}
- }
- else
- {
+ } else {
small_holes.push_back(*it);
}
}
+ ++it;
}
// Removes small holes that have their first point inside one of the removed outlines
// Iterating in reverse ensures that unprocessed small holes won't be moved
const auto removed_outlines_start = new_end;
- for(auto hole_it = small_holes.rbegin(); hole_it < small_holes.rend(); hole_it++)
- {
- for(auto outline_it = removed_outlines_start; outline_it < thiss.end() ; outline_it++)
- {
- if(Polygon(*outline_it).contains(*hole_it->begin())) {
+ for (auto hole_it = small_holes.rbegin(); hole_it < small_holes.rend(); hole_it++)
+ for (auto outline_it = removed_outlines_start; outline_it < thiss.end(); outline_it++)
+ if (Polygon(*outline_it).contains(*hole_it->begin())) {
new_end--;
*hole_it = std::move(*new_end);
break;
}
- }
- }
}
thiss.resize(new_end-thiss.begin());
}
diff --git a/tests/libslic3r/test_arachne.cpp b/tests/libslic3r/test_arachne.cpp
index c309fe6c8..b8af0fdcc 100644
--- a/tests/libslic3r/test_arachne.cpp
+++ b/tests/libslic3r/test_arachne.cpp
@@ -388,4 +388,39 @@ TEST_CASE("Arachne - #8633 - Shorter open perimeter", "[ArachneShorterOpenPerime
export_perimeters_to_svg(debug_out_path("arachne-shorter-open-perimeter-8633-%d.svg", poly_idx), input_polygons, perimeters, union_ex(wallToolPaths.getInnerContour()));
#endif
}
+}
+
+// This test case was distilled from GitHub issue #8597.
+// There was just an issue with decrementing std::vector::begin() in a specific case.
+TEST_CASE("Arachne - #8597 - removeSmallAreas", "[ArachneRemoveSmallAreas8597]") {
+ const Polygon poly_0 = {
+ Point(-38768167, -3636556),
+ Point(-38763631, -3617883),
+ Point(-38763925, -3617820),
+ Point(-38990169, -3919539),
+ Point(-38928506, -3919539),
+ };
+
+ const Polygon poly_1 = {
+ Point(-39521732, -4480560),
+ Point(-39383333, -4398498),
+ Point(-39119825, -3925307),
+ Point(-39165608, -3926212),
+ Point(-39302205, -3959445),
+ Point(-39578719, -4537002),
+ };
+
+ Polygons polygons = {poly_0, poly_1};
+ coord_t spacing = 407079;
+ coord_t inset_count = 2;
+
+ Arachne::WallToolPaths wallToolPaths(polygons, spacing, spacing, inset_count, 0, 0.2, PrintObjectConfig::defaults(), PrintConfig::defaults());
+ wallToolPaths.generate();
+ std::vector<Arachne::VariableWidthLines> perimeters = wallToolPaths.getToolPaths();
+
+#ifdef ARACHNE_DEBUG_OUT
+ export_perimeters_to_svg(debug_out_path("arachne-remove-small-areas-8597.svg"), polygons, perimeters, union_ex(wallToolPaths.getInnerContour()));
+#endif
+
+ REQUIRE(perimeters.size() == 1);
} \ No newline at end of file