diff --git a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp index 11e2d081d2..97f8f743fb 100644 --- a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp +++ b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp @@ -682,7 +682,7 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim return fuzzified; } -void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerator& perimeter_generator, const bool is_contour) +void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerator& perimeter_generator, const bool is_contour, const bool closed) { const auto slice_z = perimeter_generator.slice_z; const auto& regions = perimeter_generator.regions_by_fuzzify; @@ -690,7 +690,7 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato const auto& config = regions.begin()->first; const bool fuzzify = should_fuzzify(config, perimeter_generator.layer_id, extrusion->inset_idx, is_contour); if (fuzzify) - fuzzy_extrusion_line(extrusion->junctions, slice_z, config); + fuzzy_extrusion_line(extrusion->junctions, slice_z, config, closed); } else { // Merge regions that produce identical fuzzy effects (differ only in type). // When the style (e.g. External) and a painted region (All) both fuzzify this loop @@ -701,10 +701,19 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato // Fast path: single merged region — apply directly without splitting if (merged_regions.size() == 1 && merged_regions.front().expolygons.empty()) { - fuzzy_extrusion_line(extrusion->junctions, slice_z, *merged_regions.front().config); + fuzzy_extrusion_line(extrusion->junctions, slice_z, *merged_regions.front().config, closed); return; } + // Open path means this is a thin wall that collapsed into a single thick line, in this case the path will go exactly + // between the middle two sides of the object. And since the paint segmentation never goes beyond the middle line because + // it uses voronoi diagram, we need to expand the segmentation a little bit to make sure it covers the path. + if (!closed) { + for (auto& r : merged_regions) { + r.expolygons = offset_ex(r.expolygons, perimeter_generator.ext_perimeter_flow.scaled_width() / 10); + } + } + #ifdef DEBUG_FUZZY { int i = 0; @@ -752,7 +761,7 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato // Fuzzy splitted extrusion if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) { // The entire polygon is fuzzified - fuzzy_extrusion_line(extrusion->junctions, slice_z, *r.config); + fuzzy_extrusion_line(extrusion->junctions, slice_z, *r.config, closed); continue; } else { const auto current_ext = extrusion->junctions; @@ -803,7 +812,7 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato } //Orca: ensure the loop is closed after fuzzy - if (!extrusion->junctions.empty() && extrusion->junctions.front().p != extrusion->junctions.back().p) { + if (closed && !extrusion->junctions.empty() && extrusion->junctions.front().p != extrusion->junctions.back().p) { extrusion->junctions.back().p = extrusion->junctions.front().p; extrusion->junctions.back().w = extrusion->junctions.front().w; } diff --git a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.hpp b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.hpp index e099139c90..51d503a3c9 100644 --- a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.hpp +++ b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.hpp @@ -16,7 +16,7 @@ void group_region_by_fuzzify(PerimeterGenerator& g); bool should_fuzzify(const FuzzySkinConfig& config, int layer_id, size_t loop_idx, bool is_contour); Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perimeter_generator, size_t loop_idx, bool is_contour); -void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerator& perimeter_generator, bool is_contour); +void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerator& perimeter_generator, bool is_contour, bool closed = true); } // namespace Slic3r::Feature::FuzzySkin diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 2d6c993d78..659a3a7038 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -229,6 +229,22 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime // Append thin walls to the nearest-neighbor search (only for first iteration) if (! thin_walls.empty()) { + // Orca: apply fuzzy skin to thin walls as well + for (auto& thin_wall : thin_walls) { + // First, we convert the ThickPolyline into Arachne::ExtrusionLine so we could reuse our existing fuzzy code + Arachne::ExtrusionLine el(0, true); + el.junctions.reserve(thin_wall.points.size()); + for (int i = 0; i < thin_wall.points.size(); i++) { + el.junctions.emplace_back(thin_wall.points[i], thin_wall.width[i], 0); + } + + // Then we fuzzy it + apply_fuzzy_skin(&el, perimeter_generator, true, thin_wall.is_closed()); + + // Then convert the result back to ThickPolyline + thin_wall = Arachne::to_thick_polyline(el); + } + variable_width(thin_walls, erExternalPerimeter, perimeter_generator.ext_perimeter_flow, coll.entities); thin_walls.clear(); }