From 48368ed472fb885c7dea6a573e2171e6e14e527e Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 7 Feb 2025 17:34:57 +0800 Subject: [PATCH] FIX:Elephant foot compensation simplify expoly leads to contour loss jira: none Change-Id: I4df620e1a0c55803499ec979fa3ea22394f32699 --- src/libslic3r/ElephantFootCompensation.cpp | 41 +++++++++++----------- src/libslic3r/PrintObject.cpp | 13 +++++++ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 0adff1ba4..b452ba84e 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -29,7 +29,7 @@ struct ResampledPoint { // Distance calculated using SDF (Shape Diameter Function). // The distance is calculated by casting a fan of rays and measuring the intersection distance. -// Thus the calculation is relatively slow. For the Elephant foot compensation purpose, this distance metric does not avoid +// Thus the calculation is relatively slow. For the Elephant foot compensation purpose, this distance metric does not avoid // pinching off small pieces of a contour, thus this function has been superseded by contour_distance2(). std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx_contour, const Slic3r::Points &contour, const std::vector &resampled_point_parameters, double search_radius) { @@ -38,7 +38,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx std::vector out; - if (contour.size() > 2) + if (contour.size() > 2) { #ifdef CONTOUR_DISTANCE_DEBUG_SVG static int iRun = 0; @@ -237,7 +237,7 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id std::vector out; - if (contour.size() > 2) + if (contour.size() > 2) { #ifdef CONTOUR_DISTANCE_DEBUG_SVG static int iRun = 0; @@ -302,11 +302,11 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id if (dist_along_contour < dist_same_contour_accept) accept = false; else if (dist < dist_same_contour_reject + SCALED_EPSILON) { - // this->point is close to foot. This point will only be accepted if the path along the contour is significantly + // this->point is close to foot. This point will only be accepted if the path along the contour is significantly // longer than the bisector. That is, the path shall not bulge away from the bisector too much. // Bulge is estimated by 0.6 of the circle circumference drawn around the bisector. // Test whether the contour is convex or concave. - bool inside = + bool inside = (t == 0.) ? this->inside_corner(contour, ipt, this->point) : (t == 1.) ? this->inside_corner(contour, contour.segment_idx_next(ipt), this->point) : this->left_of_segment(contour, ipt, this->point); @@ -472,7 +472,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, for (size_t iter = 0; iter < num_iterations; ++ iter) { for (int i = 0; i < int(compensation.size()); ++ i) { const Vec2f pthis = contour[i].cast(); - + int j = prev_idx_modulo(i, contour); Vec2f pprev = contour[j].cast(); float prev = compensation[j]; @@ -535,14 +535,14 @@ static inline void smooth_compensation_banded(const Points &contour, float band, static bool validate_expoly_orientation(const ExPolygon &expoly) { bool valid = expoly.contour.is_counter_clockwise(); - for (auto &h : expoly.holes) + for (auto &h : expoly.holes) valid &= h.is_clockwise(); return valid; } #endif /* NDEBUG */ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, double min_contour_width, const double compensation) -{ +{ assert(validate_expoly_orientation(input_expoly)); double scaled_compensation = scale_(compensation); @@ -564,17 +564,16 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, double min_c else { EdgeGrid::Grid grid; - ExPolygon simplified = input_expoly.simplify(SCALED_EPSILON).front(); - assert(validate_expoly_orientation(simplified)); - BoundingBox bbox = get_extents(simplified.contour); + assert(validate_expoly_orientation(input_expoly)); + BoundingBox bbox = get_extents(input_expoly.contour); bbox.offset(SCALED_EPSILON); grid.set_bbox(bbox); - grid.create(simplified, coord_t(0.7 * search_radius)); + grid.create(input_expoly, coord_t(0.7 * search_radius)); std::vector> deltas; - deltas.reserve(simplified.holes.size() + 1); - ExPolygon resampled(simplified); + deltas.reserve(input_expoly.holes.size() + 1); + ExPolygon resampled(input_expoly); double resample_interval = scale_(0.5); - for (size_t idx_contour = 0; idx_contour <= simplified.holes.size(); ++ idx_contour) { + for (size_t idx_contour = 0; idx_contour <= input_expoly.holes.size(); ++ idx_contour) { Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1]; std::vector resampled_point_parameters; poly.points = resample_polygon(poly.points, resample_interval, resampled_point_parameters); @@ -613,7 +612,7 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, double min_c assert(out_vec.size() == 1); } } - + assert(validate_expoly_orientation(out)); return out; } @@ -628,8 +627,9 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input, const Flow &exter ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &external_perimeter_flow, const double compensation) { ExPolygons out; - out.reserve(input.size()); - for (const ExPolygon &expoly : input) + ExPolygons simplified_exps = expolygons_simplify(input, SCALED_EPSILON); + out.reserve(simplified_exps.size()); + for (const ExPolygon &expoly : simplified_exps) out.emplace_back(elephant_foot_compensation(expoly, external_perimeter_flow, compensation)); return out; } @@ -637,8 +637,9 @@ ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &exter ExPolygons elephant_foot_compensation(const ExPolygons &input, double min_contour_width, const double compensation) { ExPolygons out; - out.reserve(input.size()); - for (const ExPolygon &expoly : input) + ExPolygons simplified_exps = expolygons_simplify(input, SCALED_EPSILON); + out.reserve(simplified_exps.size()); + for (const ExPolygon &expoly : simplified_exps) out.emplace_back(elephant_foot_compensation(expoly, min_contour_width, compensation)); return out; } diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 6894a03df..40ef136eb 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -407,6 +407,19 @@ void PrintObject::make_perimeters(const AutoContourHolesCompensationParams &auto BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - end"; } +#if 0 + { // for debug + for (size_t layer_idx = 0; layer_idx < m_layers.size(); ++layer_idx) { + auto regions = m_layers[layer_idx]->regions(); + for (size_t region_idx = 0; region_idx < regions.size(); ++region_idx) { + LayerRegion *layer_region = regions[region_idx]; + std::string name = "before_make_perimeter_layer-" + std::to_string(layer_idx) + "-region-" + std::to_string(region_idx) + ".svg"; + layer_region->slices.export_to_svg(debug_out_path(name.c_str()).c_str(), true); + } + } + } +#endif + BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start"; tbb::parallel_for( tbb::blocked_range(0, m_layers.size()),