From 0cc953ad41cccaf8c513dc5229b66a83cb6d9f98 Mon Sep 17 00:00:00 2001 From: "qing.zhang" Date: Wed, 8 Mar 2023 15:10:57 +0800 Subject: [PATCH] ENH: speed up one wall top generate Signed-off-by: qing.zhang Change-Id: I141565bea3ca4d3fbcc9569b175af5d4f5cdd40e --- src/libslic3r/ClipperUtils.cpp | 12 ++++++++++++ src/libslic3r/ClipperUtils.hpp | 1 + src/libslic3r/PerimeterGenerator.cpp | 19 +++++++++++++++---- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 19bd2850e..2619247c3 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -147,6 +147,18 @@ void clip_clipper_polygon_with_subject_bbox(const Polygon &src, const BoundingBo out.erase(std::remove_if(out.begin(), out.end(), [](const Polygon &polygon) { return polygon.empty(); }), out.end()); return out; } +[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygons &src, const BoundingBox &bbox) +{ + Polygons out; + out.reserve(number_polygons(src)); + for (const ExPolygon &p : src) { + Polygons temp = clip_clipper_polygons_with_subject_bbox(p, bbox); + out.insert(out.end(), temp.begin(), temp.end()); + } + + out.erase(std::remove_if(out.begin(), out.end(), [](const Polygon &polygon) {return polygon.empty(); }), out.end()); + return out; +} } static ExPolygons PolyTreeToExPolygons(ClipperLib::PolyTree &&polytree) diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index d7e0fcc4c..18a8ebb11 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -313,6 +313,7 @@ namespace ClipperUtils { [[nodiscard]] Polygon clip_clipper_polygon_with_subject_bbox(const Polygon &src, const BoundingBox &bbox); [[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const Polygons &src, const BoundingBox &bbox); [[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygon &src, const BoundingBox &bbox); + [[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygons &src, const BoundingBox &bbox); } diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index ff7d94a6e..31b505379 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -846,7 +846,16 @@ void PerimeterGenerator::process_classic() offset_top_surface = 0; //don't takes into account too thin areas double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), 1.0 * (double(perimeter_width))); - ExPolygons grown_upper_slices = offset_ex(*this->upper_slices, min_width_top_surface); + + Polygons grown_upper_slices = offset(*this->upper_slices, min_width_top_surface); + + //BBS: get boungding box of last + BoundingBox last_box = get_extents(last); + last_box.offset(SCALED_EPSILON); + + // BBS: get the Polygons upper the polygon this layer + Polygons upper_polygons_series_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(grown_upper_slices, last_box); + //set the clip to a virtual "second perimeter" fill_clip = offset_ex(last, -double(ext_perimeter_spacing)); // get the real top surface @@ -854,13 +863,15 @@ void PerimeterGenerator::process_classic() ExPolygons bridge_checker; // BBS: check whether surface be bridge or not if (this->lower_slices != NULL) { - grown_lower_slices =*this->lower_slices; + // BBS: get the Polygons below the polygon this layer + Polygons lower_polygons_series_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*this->lower_slices, last_box); + double bridge_offset = std::max(double(ext_perimeter_spacing), (double(perimeter_width))); - bridge_checker = offset_ex(diff_ex(last, grown_lower_slices, ApplySafetyOffset::Yes), 1.5 * bridge_offset); + bridge_checker = offset_ex(diff_ex(last, lower_polygons_series_clipped, ApplySafetyOffset::Yes), 1.5 * bridge_offset); } ExPolygons delete_bridge = diff_ex(last, bridge_checker, ApplySafetyOffset::Yes); - ExPolygons top_polygons = diff_ex(delete_bridge, grown_upper_slices, ApplySafetyOffset::Yes); + ExPolygons top_polygons = diff_ex(delete_bridge, upper_polygons_series_clipped, ApplySafetyOffset::Yes); //get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the min_width_top_surface we removed a bit before) ExPolygons temp_gap = diff_ex(top_polygons, fill_clip); ExPolygons inner_polygons = diff_ex(last,