From 1d41dd24577b94e553b74d66b9f133f29cef37d1 Mon Sep 17 00:00:00 2001 From: igiannakas Date: Tue, 2 Jul 2024 23:58:39 +0100 Subject: [PATCH 1/6] Increase granularity of extrusion move splitting for small line segments ending in an overhang --- src/libslic3r/GCode/ExtrusionProcessor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index c6c1c102dea..d75d338b084 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -118,7 +118,7 @@ std::vector estimate_points_properties(const POINTS if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) || (next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) { double line_len = (next.position - curr.position).norm(); - if (line_len > 4.0f) { + if (line_len > 1.0f) { double a0 = std::clamp((curr.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double t0 = std::min(a0, a1); From 0e26652b0c63256fe13adbef918034e7c4a95bd4 Mon Sep 17 00:00:00 2001 From: igiannakas Date: Wed, 3 Jul 2024 00:11:59 +0100 Subject: [PATCH 2/6] Parameter tweak --- src/libslic3r/GCode/ExtrusionProcessor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index d75d338b084..9e100e82a8e 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -118,7 +118,7 @@ std::vector estimate_points_properties(const POINTS if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) || (next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) { double line_len = (next.position - curr.position).norm(); - if (line_len > 1.0f) { + if (line_len > 0.8f) { double a0 = std::clamp((curr.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double t0 = std::min(a0, a1); From d5c24c68c197f54ddd2a04a97ba480a508e5ec7f Mon Sep 17 00:00:00 2001 From: igiannakas Date: Wed, 3 Jul 2024 10:26:38 +0100 Subject: [PATCH 3/6] Increase granularity of estimation for curled perimeters --- src/libslic3r/GCode/ExtrusionProcessor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index 9e100e82a8e..2eefe86824c 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -323,7 +323,7 @@ class ExtrusionQualityEstimator // The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down. // NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point // TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge - if (len > 8) { + if (len > 2) { Vec2d dir = Vec2d(next.position - curr.position) / len; Vec2d right = Vec2d(-dir.y(), dir.x()); From 218252d808ef90ddd6887298894a518eb1b3a9ef Mon Sep 17 00:00:00 2001 From: igiannakas Date: Tue, 9 Jul 2024 22:12:55 +0100 Subject: [PATCH 4/6] Adjust parameters following experimentation with overhang prints --- src/libslic3r/GCode/ExtrusionProcessor.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index 2eefe86824c..2818e3b2f77 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -118,7 +118,7 @@ std::vector estimate_points_properties(const POINTS if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) || (next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) { double line_len = (next.position - curr.position).norm(); - if (line_len > 0.8f) { + if (line_len > 2.0f) { double a0 = std::clamp((curr.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double t0 = std::min(a0, a1); @@ -323,7 +323,7 @@ class ExtrusionQualityEstimator // The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down. // NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point // TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge - if (len > 2) { + if (len > 4) { Vec2d dir = Vec2d(next.position - curr.position) / len; Vec2d right = Vec2d(-dir.y(), dir.x()); From d2547b88d1c24ab7d18c00205925a421e223e917 Mon Sep 17 00:00:00 2001 From: igiannakas Date: Thu, 11 Jul 2024 14:56:46 +0100 Subject: [PATCH 5/6] Updated overhang segmentation logic --- src/libslic3r/GCode.cpp | 11 +++- src/libslic3r/GCode/ExtrusionProcessor.hpp | 66 +++++++++++++++++++--- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index cdeaa1f159a..2497f6ea30b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5225,6 +5225,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, bool variable_speed = false; std::vector new_points {}; + //IG Debug: printf("Layer: %d\n", m_layer_index + 1); if (m_config.enable_overhang_speed && !m_config.overhang_speed_classic && !this->on_first_layer() && (is_bridge(path.role()) || is_perimeter(path.role()))) { @@ -5286,8 +5287,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, ref_speed, speed, m_config.slowdown_for_curled_perimeters); } variable_speed = std::any_of(new_points.begin(), new_points.end(), - [speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > EPSILON; }); - + [speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec) } double F = speed * 60; // convert mm/sec to mm/min @@ -5591,9 +5591,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, continue; path_length += line_length; double new_speed = pre_processed_point.speed * 60.0; - if (last_set_speed != new_speed) { + // Ignore small speed variations - emit speed change if the delta between current and new is greater than 60mm/min / 1mm/sec + // Reset speed to F if delta to F is less than 1mm/sec + if ((std::abs(last_set_speed - new_speed) > 60)) { gcode += m_writer.set_speed(new_speed, "", comment); last_set_speed = new_speed; + } else if ((std::abs(F - new_speed) <= 60)) { + gcode += m_writer.set_speed(F, "", comment); + last_set_speed = F; } auto dE = e_per_mm * line_length; if (!this->on_first_layer() && m_small_area_infill_flow_compensator diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index 2818e3b2f77..41caf93edc9 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -38,7 +38,8 @@ template estimate_points_properties(const POINTS &input_points, const AABBTreeLines::LinesDistancer &unscaled_prev_layer, float flow_width, - float max_line_length = -1.0f) + float max_line_length = -1.0f, + float min_distance = -1.0f) { bool looped = input_points.front() == input_points.back(); std::function get_prev_index = [](size_t idx, size_t count) { @@ -118,7 +119,14 @@ std::vector estimate_points_properties(const POINTS if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) || (next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) { double line_len = (next.position - curr.position).norm(); - if (line_len > 2.0f) { + //IG Debug: printf("Line. Length: %f, curr dist %f, next dist %f\n",line_len,curr.distance,next.distance); + + // ORCA: Segment path to smaller lines by adding additional points only if the path has an overhang that + // will trigger a slowdown and the path is also reasonably large, i.e. 2mm in length or more + // If there is no overhang in the start/end point, dont segment it. + // Ignore this check if the control of segmentation for overhangs is disabled (min_distance=-1) + if ((min_distance > 0 && ((std::abs(curr.distance) > min_distance) || (std::abs(next.distance) > min_distance)) && line_len >= 2.f) || + (min_distance <= 0 && line_len > 4.0f)) { double a0 = std::clamp((curr.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0); double t0 = std::min(a0, a1); @@ -131,7 +139,13 @@ std::vector estimate_points_properties(const POINTS ExtendedPoint new_p{}; new_p.position = p0; new_p.distance = float(p0_dist + boundary_offset); - new_points.push_back(new_p); + if( (std::abs(p0_dist) > min_distance) || (min_distance<=0)){ + // ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change + // or if this option is disabled (min_distance<=0) + new_points.push_back(new_p); + //IG Debug: double LEN_IG = (new_p.position - curr.position).norm(); + //IG Debug: printf("New segment length 1: %f Distance %f\n",LEN_IG,new_p.distance); + } } if (t1 > 0.0) { auto p1 = curr.position + t1 * (next.position - curr.position); @@ -140,7 +154,13 @@ std::vector estimate_points_properties(const POINTS ExtendedPoint new_p{}; new_p.position = p1; new_p.distance = float(p1_dist + boundary_offset); - new_points.push_back(new_p); + if( (std::abs(p1_dist) > min_distance) || (min_distance<=0)){ + // ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change + // or if this option is disabled (min_distance<=0) + new_points.push_back(new_p); + //IG Debug: double LEN_IG = (new_p.position - curr.position).norm(); + //IG Debug: printf("New segment length 2: %f Distance %f\n",LEN_IG, new_p.distance); + } } } } @@ -300,9 +320,37 @@ class ExtrusionQualityEstimator last_section = section; } } + + // Orca: Find the smallest overhang distance where speed adjustments begin + float smallest_distance_with_lower_speed = std::numeric_limits::infinity(); // Initialize to a large value + bool found = false; + for (const auto& section : speed_sections) { + if (section.second <= original_speed) { + if (section.first < smallest_distance_with_lower_speed) { + smallest_distance_with_lower_speed = section.first; + found = true; + } + } + } - std::vector extended_points = - estimate_points_properties(path.polyline.points, prev_layer_boundaries[current_object], path.width); + // If overhang distance was found, then we shouldn't split the lines + if (!found)// IG Debug: { + smallest_distance_with_lower_speed=-1.f; + // No distance found where speed < original_speed + // Handle as needed, e.g., log a message, set a default value, etc. + // IG Debug:printf("No speed section found with speed less than original_speed.\n"); + + // IG Debug:} else { + // IG Debug: printf("Smallest distance with speed less than original_speed: %f\n", smallest_distance_with_lower_speed); + // IG Debug:} + + // Orca: Pass to the point properties estimator the smallest ovehang distance that triggers a slowdown (smallest_distance_with_lower_speed) + std::vector extended_points = estimate_points_properties + (path.polyline.points, + prev_layer_boundaries[current_object], + path.width, + -1, + smallest_distance_with_lower_speed); const auto width_inv = 1.0f / path.width; std::vector processed_points; processed_points.reserve(extended_points.size()); @@ -323,7 +371,7 @@ class ExtrusionQualityEstimator // The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down. // NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point // TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge - if (len > 4) { + if (len > 2) { Vec2d dir = Vec2d(next.position - curr.position) / len; Vec2d right = Vec2d(-dir.y(), dir.x()); @@ -371,15 +419,17 @@ class ExtrusionQualityEstimator while (distance > speed_sections[section_idx + 1].first) { section_idx++; } + // IG Debug: printf("Speed section index: %d, width:%f, original speed: %f, new speed:%f, distance:%f\n",section_idx, speed_sections[section_idx].first, original_speed,speed_sections[section_idx].second,distance ); float t = (distance - speed_sections[section_idx].first) / (speed_sections[section_idx + 1].first - speed_sections[section_idx].first); t = std::clamp(t, 0.0f, 1.0f); final_speed = (1.0f - t) * speed_sections[section_idx].second + t * speed_sections[section_idx + 1].second; } - return final_speed; + return round(final_speed); }; float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance)); + // IG Debug: printf("ext_perimeter_speed %f, original_speed %f \n", ext_perimeter_speed, original_speed ); if(slowdown_for_curled_edges) { float curled_speed = calculate_speed(artificial_distance_to_curled_lines); extrusion_speed = std::min(curled_speed, extrusion_speed); // adjust extrusion speed based on what is smallest - the calculated overhang speed or the artificial curled speed From c726bda3cca6e5faee2de8a9e7ac3c0bc2237e48 Mon Sep 17 00:00:00 2001 From: igiannakas Date: Sun, 28 Jul 2024 09:50:26 +0100 Subject: [PATCH 6/6] Cleanup code comments --- src/libslic3r/GCode.cpp | 1 - src/libslic3r/GCode/ExtrusionProcessor.hpp | 18 ++---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2497f6ea30b..55efc54384b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5225,7 +5225,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, bool variable_speed = false; std::vector new_points {}; - //IG Debug: printf("Layer: %d\n", m_layer_index + 1); if (m_config.enable_overhang_speed && !m_config.overhang_speed_classic && !this->on_first_layer() && (is_bridge(path.role()) || is_perimeter(path.role()))) { diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index 41caf93edc9..64f7a718a21 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -119,7 +119,6 @@ std::vector estimate_points_properties(const POINTS if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) || (next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) { double line_len = (next.position - curr.position).norm(); - //IG Debug: printf("Line. Length: %f, curr dist %f, next dist %f\n",line_len,curr.distance,next.distance); // ORCA: Segment path to smaller lines by adding additional points only if the path has an overhang that // will trigger a slowdown and the path is also reasonably large, i.e. 2mm in length or more @@ -143,8 +142,6 @@ std::vector estimate_points_properties(const POINTS // ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change // or if this option is disabled (min_distance<=0) new_points.push_back(new_p); - //IG Debug: double LEN_IG = (new_p.position - curr.position).norm(); - //IG Debug: printf("New segment length 1: %f Distance %f\n",LEN_IG,new_p.distance); } } if (t1 > 0.0) { @@ -158,8 +155,6 @@ std::vector estimate_points_properties(const POINTS // ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change // or if this option is disabled (min_distance<=0) new_points.push_back(new_p); - //IG Debug: double LEN_IG = (new_p.position - curr.position).norm(); - //IG Debug: printf("New segment length 2: %f Distance %f\n",LEN_IG, new_p.distance); } } } @@ -333,16 +328,9 @@ class ExtrusionQualityEstimator } } - // If overhang distance was found, then we shouldn't split the lines - if (!found)// IG Debug: { + // If a meaningful (i.e. needing slowdown) overhang distance was not found, then we shouldn't split the lines + if (!found) smallest_distance_with_lower_speed=-1.f; - // No distance found where speed < original_speed - // Handle as needed, e.g., log a message, set a default value, etc. - // IG Debug:printf("No speed section found with speed less than original_speed.\n"); - - // IG Debug:} else { - // IG Debug: printf("Smallest distance with speed less than original_speed: %f\n", smallest_distance_with_lower_speed); - // IG Debug:} // Orca: Pass to the point properties estimator the smallest ovehang distance that triggers a slowdown (smallest_distance_with_lower_speed) std::vector extended_points = estimate_points_properties @@ -419,7 +407,6 @@ class ExtrusionQualityEstimator while (distance > speed_sections[section_idx + 1].first) { section_idx++; } - // IG Debug: printf("Speed section index: %d, width:%f, original speed: %f, new speed:%f, distance:%f\n",section_idx, speed_sections[section_idx].first, original_speed,speed_sections[section_idx].second,distance ); float t = (distance - speed_sections[section_idx].first) / (speed_sections[section_idx + 1].first - speed_sections[section_idx].first); t = std::clamp(t, 0.0f, 1.0f); @@ -429,7 +416,6 @@ class ExtrusionQualityEstimator }; float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance)); - // IG Debug: printf("ext_perimeter_speed %f, original_speed %f \n", ext_perimeter_speed, original_speed ); if(slowdown_for_curled_edges) { float curled_speed = calculate_speed(artificial_distance_to_curled_lines); extrusion_speed = std::min(curled_speed, extrusion_speed); // adjust extrusion speed based on what is smallest - the calculated overhang speed or the artificial curled speed