From 5ac295a83f196d35a79a08d38a0c0dd35c44696b Mon Sep 17 00:00:00 2001 From: supermerill Date: Thu, 23 Dec 2021 14:48:42 +0100 Subject: fix quirky gapfill (u-turn at the tip of it) supermerill/SuperSlicer#2102 --- src/libslic3r/MedialAxis.cpp | 55 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libslic3r/MedialAxis.cpp b/src/libslic3r/MedialAxis.cpp index 02b4816e2..e9fc6ee4f 100644 --- a/src/libslic3r/MedialAxis.cpp +++ b/src/libslic3r/MedialAxis.cpp @@ -651,6 +651,8 @@ MedialAxis::remove_bits(ThickPolylines &pp) ///reorder, in case of change std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { return a.length() < b.length(); }); } + + //TODO: check if there is a U-turn (almost 180° direction change) : remove it. } void @@ -1492,6 +1494,40 @@ MedialAxis::remove_too_short_polylines(ThickPolylines& pp, const coord_t min_siz } if (changes) concatThickPolylines(pp); } + + //remove points too near each other + changes = true; + while (changes) { + changes = false; + + coordf_t shortest_size = (coordf_t)min_size; + size_t shortest_idx = -1; + for (size_t polyidx = 0; polyidx < pp.size(); ++polyidx) { + ThickPolyline& tp = pp[polyidx]; + for (size_t pt_idx = 1; pt_idx < tp.points.size() - 1; pt_idx++) { + if (tp.points[pt_idx - 1].coincides_with_epsilon(tp.points[pt_idx])) { + tp.points.erase(tp.points.begin() + pt_idx); + tp.width.erase(tp.width.begin() + pt_idx); + pt_idx--; + changes = true; + } + } + //check last segment + if (tp.points.size() > 2 && tp.points[tp.points.size() - 2].coincides_with_epsilon(tp.points.back())) { + tp.points.erase(tp.points.end() - 2); + tp.width.erase(tp.width.end() - 2); + changes = true; + } + //delete null-length polylines + if (tp.length() < SCALED_EPSILON && tp.first_point().coincides_with_epsilon(tp.last_point())) { + pp.erase(pp.begin() + polyidx); + --polyidx; + changes = true; + } + } + if (changes) concatThickPolylines(pp); + } + } void @@ -2037,7 +2073,7 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl // variable extrusion within a single move; this value shall only affect the amount // of segments, and any pruning shall be performed before we apply this tolerance const coord_t tolerance = flow.scaled_width() / 10;//scale_(0.05); - + ExtrusionEntityCollection coll; for (const ThickPolyline &p : polylines) { ExtrusionPaths paths; @@ -2052,8 +2088,8 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl const coordf_t prev_line_len = saved_line_len; saved_line_len = line_len; - assert(line.a_width >= 0); - assert(line.b_width >= 0); + assert(line.a_width >= 0 && !std::isnan(line.a_width)); + assert(line.b_width >= 0 && !std::isnan(line.b_width)); coord_t thickness_delta = std::abs(line.a_width - line.b_width); // split lines ? @@ -2108,7 +2144,16 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl coordf_t width = prev_line_len * (prev_line.a_width + prev_line.b_width) / 2; width += line_len * (line.a_width + line.b_width) / 2; prev_line.b = line.b; - coordf_t new_length = prev_line.length(); + const coordf_t new_length = prev_line.length(); + if (new_length < SCALED_EPSILON) { + // too short, remove it and restart + if (i > 1) { + line.a = lines[i - 2].b; + } + lines.erase(lines.begin() + i-1); + i-=2; + continue; + } width /= new_length; prev_line.a_width = width; prev_line.b_width = width; @@ -2131,7 +2176,7 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl // but we can't extrude with a negative spacing, so we have to gradually fall back to spacing if the width is too small. // default: extrude a thin wall that doesn't go outside of the specified width. - double wanted_width = unscaled(line.a_width); + coordf_t wanted_width = unscaled(line.a_width); if (role == erGapFill) { // Convert from spacing to extrusion width based on the extrusion model // of a square extrusion ended with semi circles. -- cgit v1.2.3