From 38ce4b94f47fb80d8a88c98aac80c4c3dd4dcd2b Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 26 Dec 2022 16:59:30 +0800 Subject: [PATCH] ENH: improve sharp tail detection 1. When sharp tail region suddenly grows a lot, it means it connects to a well supported region and is no longer a sharp tail. Jira: STUDIO-1862 2. First layer of sharp tail can not be reducible (must have extrusion, i.e. won't disappear after slicing), otherwise thin spikes at the top of the object are also treated as sharp tails. Model: knight_seadra 3. Increase sharp_tail_max_support_height to 16mm Model: Crane_reversed Jira: STUDIO-1859 (for this issue I don't what is the exact cause, but adding these three improvements solves the problem) Change-Id: I3cd57b184d78dba8862ab3c214057ae78fe49d1f (cherry picked from commit 9242c6a6d1f23f11ebc43a9049ce10229a15c60e) --- src/libslic3r/Point.hpp | 15 +++++++++++++++ src/libslic3r/SupportMaterial.cpp | 7 ++++--- src/libslic3r/TreeSupport.cpp | 8 ++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index 82ad753be..c72bedafb 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -149,6 +149,21 @@ public: Point& operator-=(const Point& rhs) { this->x() -= rhs.x(); this->y() -= rhs.y(); return *this; } Point& operator*=(const double &rhs) { this->x() = coord_t(this->x() * rhs); this->y() = coord_t(this->y() * rhs); return *this; } Point operator*(const double &rhs) { return Point(this->x() * rhs, this->y() * rhs); } + bool both_comp(const Point &rhs, const std::string& op) { + if (op == ">") + return this->x() > rhs.x() && this->y() > rhs.y(); + else if (op == "<") + return this->x() < rhs.x() && this->y() < rhs.y(); + return false; + } + bool any_comp(const Point &rhs, const std::string &op) + { + if (op == ">") + return this->x() > rhs.x() || this->y() > rhs.y(); + else if (op == "<") + return this->x() < rhs.x() || this->y() < rhs.y(); + return false; + } void rotate(double angle) { this->rotate(std::cos(angle), std::sin(angle)); } void rotate(double cos_a, double sin_a) { diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index e40040fa0..dc86831d6 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -1482,7 +1482,7 @@ static const double length_thresh_well_supported = scale_(6); // min: 6mm static const double area_thresh_well_supported = SQ(length_thresh_well_supported); // min: 6x6=36mm^2 static const double sharp_tail_xy_gap = 0.2f; static const double no_overlap_xy_gap = 0.2f; -static const double sharp_tail_max_support_height = 8.f; +static const double sharp_tail_max_support_height = 16.f; // Tuple: overhang_polygons, contact_polygons, enforcer_polygons, no_interface_offset // no_interface_offset: minimum of external perimeter widths @@ -1598,7 +1598,7 @@ static inline Polygons detect_overhangs( // Check whether this is a sharp tail region. // Should use lower_layer_expolys without any offset. Otherwise, it may missing sharp tails near the main body. if (intersection_ex({ expoly }, lower_layer_expolys).empty()) { - is_sharp_tail = expoly.area() < area_thresh_well_supported; + is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly,-0.5*fw).empty(); break; } @@ -1646,7 +1646,8 @@ static inline Polygons detect_overhangs( // 2.4 if the area grows fast than threshold, it get connected to other part or // it has a sharp slop and will be auto supported. ExPolygons new_overhang_expolys = diff_ex({ expoly }, lower_layer_sharptails); - if (!offset_ex(new_overhang_expolys, -5.0 * fw).empty()) { + Point size_diff = get_extents(new_overhang_expolys).size() - get_extents(lower_layer_sharptails).size(); + if (size_diff.both_comp(Point(scale_(5),scale_(5)),">") || !offset_ex(new_overhang_expolys, -5.0 * fw).empty()) { is_sharp_tail = false; break; } diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 7c51520cf..617f8f4bf 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -733,7 +733,7 @@ void TreeSupport::detect_object_overhangs() const int enforce_support_layers = config.enforce_support_layers.value; const double area_thresh_well_supported = SQ(scale_(6)); const double length_thresh_well_supported = scale_(6); - static const double sharp_tail_max_support_height = 8.f; + static const double sharp_tail_max_support_height = 16.f; // a region is considered well supported if the number of layers below it exceeds this threshold const int thresh_layers_below = 10 / config.layer_height; double obj_height = m_object->size().z(); @@ -923,9 +923,9 @@ void TreeSupport::detect_object_overhangs() float accum_height = layer->height; do { // 1. nothing below - // check whether this is a sharp tail region + // this is a sharp tail region if it's small but non-ignorable if (intersection_ex({expoly}, lower_polys).empty()) { - is_sharp_tail = expoly.area() < area_thresh_well_supported; + is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly,-0.5*extrusion_width_scaled).empty(); break; } @@ -969,7 +969,7 @@ void TreeSupport::detect_object_overhangs() // 2.4 if the area grows fast than threshold, it get connected to other part or // it has a sharp slop and will be auto supported. ExPolygons new_overhang_expolys = diff_ex({expoly}, lower_layer_sharptails); - if (!offset_ex(new_overhang_expolys, -5.0 * extrusion_width_scaled).empty()) { + if ((get_extents(new_overhang_expolys).size()-get_extents(lower_layer_sharptails).size()).both_comp(Point(scale_(5),scale_(5)),">") || !offset_ex(new_overhang_expolys, -5.0 * extrusion_width_scaled).empty()) { is_sharp_tail = false; break; }