Improve overhang slowdown granularity & line segmentation handling (#5996)

* Increase granularity of extrusion move splitting for small line segments ending in an overhang

* Parameter tweak

* Increase granularity of estimation for curled perimeters

* Adjust parameters following experimentation with overhang prints

* Updated overhang segmentation logic

* Cleanup code comments
This commit is contained in:
Ioannis Giannakas 2024-08-01 17:38:08 +03:00 committed by GitHub
parent cfe21e5e34
commit c5d417ed89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 51 additions and 12 deletions

View file

@ -5269,8 +5269,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
ref_speed, speed, m_config.slowdown_for_curled_perimeters); ref_speed, speed, m_config.slowdown_for_curled_perimeters);
} }
variable_speed = std::any_of(new_points.begin(), new_points.end(), 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 double F = speed * 60; // convert mm/sec to mm/min
@ -5727,10 +5726,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
} }
}// ORCA: End of adaptive PA code segment }// ORCA: End of adaptive PA code segment
// Ignore small speed variations - emit speed change if the delta between current and new is greater than 60mm/min / 1mm/sec
if (last_set_speed != new_speed) { // 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); gcode += m_writer.set_speed(new_speed, "", comment);
last_set_speed = new_speed; 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; auto dE = e_per_mm * line_length;
if (!this->on_first_layer() && m_small_area_infill_flow_compensator if (!this->on_first_layer() && m_small_area_infill_flow_compensator

View file

@ -38,7 +38,8 @@ template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFF
std::vector<ExtendedPoint> estimate_points_properties(const POINTS &input_points, std::vector<ExtendedPoint> estimate_points_properties(const POINTS &input_points,
const AABBTreeLines::LinesDistancer<L> &unscaled_prev_layer, const AABBTreeLines::LinesDistancer<L> &unscaled_prev_layer,
float flow_width, 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(); bool looped = input_points.front() == input_points.back();
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) { std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
@ -118,7 +119,13 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) || if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) ||
(next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) { (next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) {
double line_len = (next.position - curr.position).norm(); double line_len = (next.position - curr.position).norm();
if (line_len > 4.0f) {
// 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 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 a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0);
double t0 = std::min(a0, a1); double t0 = std::min(a0, a1);
@ -131,7 +138,11 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
ExtendedPoint new_p{}; ExtendedPoint new_p{};
new_p.position = p0; new_p.position = p0;
new_p.distance = float(p0_dist + boundary_offset); 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);
}
} }
if (t1 > 0.0) { if (t1 > 0.0) {
auto p1 = curr.position + t1 * (next.position - curr.position); auto p1 = curr.position + t1 * (next.position - curr.position);
@ -140,7 +151,11 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
ExtendedPoint new_p{}; ExtendedPoint new_p{};
new_p.position = p1; new_p.position = p1;
new_p.distance = float(p1_dist + boundary_offset); 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);
}
} }
} }
} }
@ -300,9 +315,30 @@ public:
last_section = section; last_section = section;
} }
} }
// Orca: Find the smallest overhang distance where speed adjustments begin
float smallest_distance_with_lower_speed = std::numeric_limits<float>::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<ExtendedPoint> extended_points = // If a meaningful (i.e. needing slowdown) overhang distance was not found, then we shouldn't split the lines
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width); if (!found)
smallest_distance_with_lower_speed=-1.f;
// Orca: Pass to the point properties estimator the smallest ovehang distance that triggers a slowdown (smallest_distance_with_lower_speed)
std::vector<ExtendedPoint> extended_points = estimate_points_properties<true, true, true, true>
(path.polyline.points,
prev_layer_boundaries[current_object],
path.width,
-1,
smallest_distance_with_lower_speed);
const auto width_inv = 1.0f / path.width; const auto width_inv = 1.0f / path.width;
std::vector<ProcessedPoint> processed_points; std::vector<ProcessedPoint> processed_points;
processed_points.reserve(extended_points.size()); processed_points.reserve(extended_points.size());
@ -323,7 +359,7 @@ public:
// The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down. // 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 // 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 // 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 dir = Vec2d(next.position - curr.position) / len;
Vec2d right = Vec2d(-dir.y(), dir.x()); Vec2d right = Vec2d(-dir.y(), dir.x());
@ -376,7 +412,7 @@ public:
t = std::clamp(t, 0.0f, 1.0f); 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; 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)); float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance));