mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 02:41:58 +08:00
SPE-2486: Reimplement fuzzy skin to be applied only to perimeter parts instead of creating different LayerRegion.
This commit is contained in:
parent
ed2cdfec61
commit
6dadcee6ab
@ -1,5 +1,6 @@
|
||||
#include <random>
|
||||
|
||||
#include "libslic3r/Algorithm/LineSegmentation/LineSegmentation.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionJunction.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionLine.hpp"
|
||||
#include "libslic3r/PerimeterGenerator.hpp"
|
||||
@ -133,4 +134,97 @@ bool should_fuzzify(const PrintRegionConfig &config, const size_t layer_idx, con
|
||||
return is_contour ? fuzzify_contours : fuzzify_holes;
|
||||
}
|
||||
|
||||
Polygon apply_fuzzy_skin(const Polygon &polygon, const PrintRegionConfig &base_config, const PerimeterRegions &perimeter_regions, const size_t layer_idx, const size_t perimeter_idx, const bool is_contour)
|
||||
{
|
||||
using namespace Slic3r::Algorithm::LineSegmentation;
|
||||
|
||||
auto apply_fuzzy_skin_on_polygon = [&layer_idx, &perimeter_idx, &is_contour](const Polygon &polygon, const PrintRegionConfig &config) -> Polygon {
|
||||
if (should_fuzzify(config, layer_idx, perimeter_idx, is_contour)) {
|
||||
Polygon fuzzified_polygon = polygon;
|
||||
fuzzy_polygon(fuzzified_polygon, scaled<double>(config.fuzzy_skin_thickness.value), scaled<double>(config.fuzzy_skin_point_dist.value));
|
||||
|
||||
return fuzzified_polygon;
|
||||
} else {
|
||||
return polygon;
|
||||
}
|
||||
};
|
||||
|
||||
if (perimeter_regions.empty()) {
|
||||
return apply_fuzzy_skin_on_polygon(polygon, base_config);
|
||||
}
|
||||
|
||||
PolylineRegionSegments segments = polygon_segmentation(polygon, base_config, perimeter_regions);
|
||||
if (segments.size() == 1) {
|
||||
const PrintRegionConfig &config = segments.front().config;
|
||||
return apply_fuzzy_skin_on_polygon(polygon, config);
|
||||
}
|
||||
|
||||
Polygon fuzzified_polygon;
|
||||
for (PolylineRegionSegment &segment : segments) {
|
||||
const PrintRegionConfig &config = segment.config;
|
||||
if (should_fuzzify(config, layer_idx, perimeter_idx, is_contour)) {
|
||||
fuzzy_polyline(segment.polyline.points, false, scaled<double>(config.fuzzy_skin_thickness.value), scaled<double>(config.fuzzy_skin_point_dist.value));
|
||||
}
|
||||
|
||||
assert(!segment.polyline.empty());
|
||||
if (segment.polyline.empty()) {
|
||||
continue;
|
||||
} else if (!fuzzified_polygon.empty() && fuzzified_polygon.back() == segment.polyline.front()) {
|
||||
// Remove the last point to avoid duplicate points.
|
||||
fuzzified_polygon.points.pop_back();
|
||||
}
|
||||
|
||||
Slic3r::append(fuzzified_polygon.points, std::move(segment.polyline.points));
|
||||
}
|
||||
|
||||
assert(!fuzzified_polygon.empty());
|
||||
if (fuzzified_polygon.front() == fuzzified_polygon.back()) {
|
||||
// Remove the last point to avoid duplicity between the first and the last point.
|
||||
fuzzified_polygon.points.pop_back();
|
||||
}
|
||||
|
||||
return fuzzified_polygon;
|
||||
}
|
||||
|
||||
Arachne::ExtrusionLine apply_fuzzy_skin(const Arachne::ExtrusionLine &extrusion, const PrintRegionConfig &base_config, const PerimeterRegions &perimeter_regions, const size_t layer_idx, const size_t perimeter_idx, const bool is_contour)
|
||||
{
|
||||
using namespace Slic3r::Algorithm::LineSegmentation;
|
||||
using namespace Slic3r::Arachne;
|
||||
|
||||
if (perimeter_regions.empty()) {
|
||||
if (should_fuzzify(base_config, layer_idx, perimeter_idx, is_contour)) {
|
||||
ExtrusionLine fuzzified_extrusion = extrusion;
|
||||
fuzzy_extrusion_line(fuzzified_extrusion, scaled<double>(base_config.fuzzy_skin_thickness.value), scaled<double>(base_config.fuzzy_skin_point_dist.value));
|
||||
|
||||
return fuzzified_extrusion;
|
||||
} else {
|
||||
return extrusion;
|
||||
}
|
||||
}
|
||||
|
||||
ExtrusionRegionSegments segments = extrusion_segmentation(extrusion, base_config, perimeter_regions);
|
||||
ExtrusionLine fuzzified_extrusion;
|
||||
|
||||
for (ExtrusionRegionSegment &segment : segments) {
|
||||
const PrintRegionConfig &config = segment.config;
|
||||
if (should_fuzzify(config, layer_idx, perimeter_idx, is_contour)) {
|
||||
fuzzy_extrusion_line(segment.extrusion, scaled<double>(config.fuzzy_skin_thickness.value), scaled<double>(config.fuzzy_skin_point_dist.value));
|
||||
}
|
||||
|
||||
assert(!segment.extrusion.empty());
|
||||
if (segment.extrusion.empty()) {
|
||||
continue;
|
||||
} else if (!fuzzified_extrusion.empty() && fuzzified_extrusion.back().p == segment.extrusion.front().p) {
|
||||
// Remove the last point to avoid duplicate points (We don't care if the width of both points is different.).
|
||||
fuzzified_extrusion.junctions.pop_back();
|
||||
}
|
||||
|
||||
Slic3r::append(fuzzified_extrusion.junctions, std::move(segment.extrusion.junctions));
|
||||
}
|
||||
|
||||
assert(!fuzzified_extrusion.empty());
|
||||
|
||||
return fuzzified_extrusion;
|
||||
}
|
||||
|
||||
} // namespace Slic3r::Feature::FuzzySkin
|
||||
|
@ -17,6 +17,10 @@ void fuzzy_extrusion_line(Arachne::ExtrusionLine &ext_lines, double fuzzy_skin_t
|
||||
|
||||
bool should_fuzzify(const PrintRegionConfig &config, size_t layer_idx, size_t perimeter_idx, bool is_contour);
|
||||
|
||||
Polygon apply_fuzzy_skin(const Polygon &polygon, const PrintRegionConfig &base_config, const PerimeterRegions &perimeter_regions, size_t layer_idx, size_t perimeter_idx, bool is_contour);
|
||||
|
||||
Arachne::ExtrusionLine apply_fuzzy_skin(const Arachne::ExtrusionLine &extrusion, const PrintRegionConfig &base_config, const PerimeterRegions &perimeter_regions, size_t layer_idx, size_t perimeter_idx, bool is_contour);
|
||||
|
||||
} // namespace Slic3r::Feature::FuzzySkin
|
||||
|
||||
#endif // libslic3r_FuzzySkin_hpp_
|
||||
|
@ -206,8 +206,7 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
||||
|
||||
// loops is an arrayref of ::Loop objects
|
||||
// turn each one into an ExtrusionLoop object
|
||||
ExtrusionEntityCollection coll;
|
||||
Polygon fuzzified;
|
||||
ExtrusionEntityCollection coll;
|
||||
for (const PerimeterGeneratorLoop &loop : loops) {
|
||||
bool is_external = loop.is_external();
|
||||
|
||||
@ -223,12 +222,8 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
||||
loop_role = elrDefault;
|
||||
}
|
||||
|
||||
const bool fuzzify = should_fuzzify(params.config, params.layer_id, loop.depth, loop.is_contour);
|
||||
const Polygon &polygon = fuzzify ? fuzzified : loop.polygon;
|
||||
if (fuzzify) {
|
||||
fuzzified = loop.polygon;
|
||||
fuzzy_polygon(fuzzified, scaled<float>(params.config.fuzzy_skin_thickness.value), scaled<float>(params.config.fuzzy_skin_point_dist.value));
|
||||
}
|
||||
// Apply fuzzy skin if it is enabled for at least some part of the polygon.
|
||||
const Polygon polygon = apply_fuzzy_skin(loop.polygon, params.config, params.perimeter_regions, params.layer_id, loop.depth, loop.is_contour);
|
||||
|
||||
ExtrusionPaths paths;
|
||||
if (params.config.overhangs && params.layer_id > params.object_config.raft_layers &&
|
||||
@ -425,7 +420,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
||||
|
||||
ExtrusionEntityCollection extrusion_coll;
|
||||
for (Arachne::PerimeterOrder::PerimeterExtrusion &pg_extrusion : pg_extrusions) {
|
||||
Arachne::ExtrusionLine &extrusion = pg_extrusion.extrusion;
|
||||
Arachne::ExtrusionLine extrusion = pg_extrusion.extrusion;
|
||||
if (extrusion.empty())
|
||||
continue;
|
||||
|
||||
@ -433,9 +428,8 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
||||
ExtrusionRole role_normal = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||
ExtrusionRole role_overhang = role_normal | ExtrusionRoleModifier::Bridge;
|
||||
|
||||
const bool fuzzify = should_fuzzify(params.config, params.layer_id, pg_extrusion.extrusion.inset_idx, !pg_extrusion.extrusion.is_closed || pg_extrusion.is_contour());
|
||||
if (fuzzify)
|
||||
fuzzy_extrusion_line(extrusion, scaled<float>(params.config.fuzzy_skin_thickness.value), scaled<float>(params.config.fuzzy_skin_point_dist.value));
|
||||
// Apply fuzzy skin if it is enabled for at least some part of the ExtrusionLine.
|
||||
extrusion = apply_fuzzy_skin(extrusion, params.config, params.perimeter_regions, params.layer_id, pg_extrusion.extrusion.inset_idx, !pg_extrusion.extrusion.is_closed || pg_extrusion.is_contour());
|
||||
|
||||
ExtrusionPaths paths;
|
||||
// detect overhanging/bridging perimeters
|
||||
|
Loading…
x
Reference in New Issue
Block a user