mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-27 20:08:24 +00:00
Fix thin wall fuzzy (#14309)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
This commit is contained in:
@@ -682,7 +682,7 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim
|
|||||||
return fuzzified;
|
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 slice_z = perimeter_generator.slice_z;
|
||||||
const auto& regions = perimeter_generator.regions_by_fuzzify;
|
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 auto& config = regions.begin()->first;
|
||||||
const bool fuzzify = should_fuzzify(config, perimeter_generator.layer_id, extrusion->inset_idx, is_contour);
|
const bool fuzzify = should_fuzzify(config, perimeter_generator.layer_id, extrusion->inset_idx, is_contour);
|
||||||
if (fuzzify)
|
if (fuzzify)
|
||||||
fuzzy_extrusion_line(extrusion->junctions, slice_z, config);
|
fuzzy_extrusion_line(extrusion->junctions, slice_z, config, closed);
|
||||||
} else {
|
} else {
|
||||||
// Merge regions that produce identical fuzzy effects (differ only in type).
|
// 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
|
// 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
|
// Fast path: single merged region — apply directly without splitting
|
||||||
if (merged_regions.size() == 1 && merged_regions.front().expolygons.empty()) {
|
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;
|
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
|
#ifdef DEBUG_FUZZY
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -752,7 +761,7 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato
|
|||||||
// Fuzzy splitted extrusion
|
// Fuzzy splitted extrusion
|
||||||
if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) {
|
if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) {
|
||||||
// The entire polygon is fuzzified
|
// 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;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
const auto current_ext = extrusion->junctions;
|
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
|
//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().p = extrusion->junctions.front().p;
|
||||||
extrusion->junctions.back().w = extrusion->junctions.front().w;
|
extrusion->junctions.back().w = extrusion->junctions.front().w;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
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);
|
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
|
} // namespace Slic3r::Feature::FuzzySkin
|
||||||
|
|
||||||
|
|||||||
@@ -229,6 +229,22 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
|||||||
|
|
||||||
// Append thin walls to the nearest-neighbor search (only for first iteration)
|
// Append thin walls to the nearest-neighbor search (only for first iteration)
|
||||||
if (! thin_walls.empty()) {
|
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);
|
variable_width(thin_walls, erExternalPerimeter, perimeter_generator.ext_perimeter_flow, coll.entities);
|
||||||
thin_walls.clear();
|
thin_walls.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user