Fix various issues with fuzzy skin (#6716)

* Fix issue that `fuzzy_skin_first_layer` not respected by classic wall generator

* Fix issue that Contour / Contour and hole mode not working properly (SoftFever/OrcaSlicer#6414)

* We have `is_contour`, so need for complicated hole detection
This commit is contained in:
Noisyfox 2024-09-10 23:28:39 +08:00 committed by GitHub
parent 3927f5adf8
commit d87734ebfa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1845,7 +1845,8 @@ void PerimeterGenerator::process_classic()
break; break;
} }
{ {
const bool fuzzify_contours = this->config->fuzzy_skin != FuzzySkinType::None && ((i == 0 && this->layer_id > 0) || this->config->fuzzy_skin == FuzzySkinType::AllWalls); const bool fuzzify_layer = (this->config->fuzzy_skin_first_layer || this->layer_id>0) && this->config->fuzzy_skin != FuzzySkinType::None;
const bool fuzzify_contours = fuzzify_layer && (i == 0 || this->config->fuzzy_skin == FuzzySkinType::AllWalls);
const bool fuzzify_holes = fuzzify_contours && (this->config->fuzzy_skin == FuzzySkinType::All || this->config->fuzzy_skin == FuzzySkinType::AllWalls); const bool fuzzify_holes = fuzzify_contours && (this->config->fuzzy_skin == FuzzySkinType::All || this->config->fuzzy_skin == FuzzySkinType::AllWalls);
for (const ExPolygon& expolygon : offsets) { for (const ExPolygon& expolygon : offsets) {
// Outer contour may overlap with an inner contour, // Outer contour may overlap with an inner contour,
@ -2856,44 +2857,19 @@ void PerimeterGenerator::process_arachne()
current_position = best_path->junctions.back().p; //Pick the other end from where we started. current_position = best_path->junctions.back().p; //Pick the other end from where we started.
} }
} }
if ((this->config->fuzzy_skin_first_layer || this->layer_id>0) && this->config->fuzzy_skin != FuzzySkinType::None) { const bool fuzzify_layer = (this->config->fuzzy_skin_first_layer || this->layer_id>0) && this->config->fuzzy_skin != FuzzySkinType::None;
std::vector<PerimeterGeneratorArachneExtrusion*> closed_loop_extrusions; if (fuzzify_layer) {
for (PerimeterGeneratorArachneExtrusion& extrusion : ordered_extrusions) for (PerimeterGeneratorArachneExtrusion& extrusion : ordered_extrusions) {
if (extrusion.extrusion->inset_idx == 0) { if (this->config->fuzzy_skin == FuzzySkinType::AllWalls) {
extrusion.fuzzify = true;
} else if (extrusion.extrusion->inset_idx == 0) {
if (extrusion.extrusion->is_closed && this->config->fuzzy_skin == FuzzySkinType::External) { if (extrusion.extrusion->is_closed && this->config->fuzzy_skin == FuzzySkinType::External) {
closed_loop_extrusions.emplace_back(&extrusion); extrusion.fuzzify = extrusion.is_contour;
} }
else { else {
extrusion.fuzzify = true; extrusion.fuzzify = true;
} }
} }
if (this->config->fuzzy_skin == FuzzySkinType::External) {
ClipperLib_Z::Paths loops_paths;
loops_paths.reserve(closed_loop_extrusions.size());
for (const auto& cl_extrusion : closed_loop_extrusions) {
assert(cl_extrusion->extrusion->junctions.front() == cl_extrusion->extrusion->junctions.back());
size_t loop_idx = &cl_extrusion - &closed_loop_extrusions.front();
ClipperLib_Z::Path loop_path;
loop_path.reserve(cl_extrusion->extrusion->junctions.size() - 1);
for (auto junction_it = cl_extrusion->extrusion->junctions.begin(); junction_it != std::prev(cl_extrusion->extrusion->junctions.end()); ++junction_it)
loop_path.emplace_back(junction_it->p.x(), junction_it->p.y(), loop_idx);
loops_paths.emplace_back(loop_path);
}
ClipperLib_Z::Clipper clipper;
clipper.AddPaths(loops_paths, ClipperLib_Z::ptSubject, true);
ClipperLib_Z::PolyTree loops_polytree;
clipper.Execute(ClipperLib_Z::ctUnion, loops_polytree, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd);
for (const ClipperLib_Z::PolyNode* child_node : loops_polytree.Childs) {
// The whole contour must have the same index.
coord_t polygon_idx = child_node->Contour.front().z();
bool has_same_idx = std::all_of(child_node->Contour.begin(), child_node->Contour.end(),
[&polygon_idx](const ClipperLib_Z::IntPoint& point) -> bool { return polygon_idx == point.z(); });
if (has_same_idx)
closed_loop_extrusions[polygon_idx]->fuzzify = true;
}
} }
} }