Skip to content

Commit

Permalink
Improve overhang slowdown granularity & line segmentation handling (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
igiannakas authored Aug 1, 2024
1 parent cfe21e5 commit c5d417e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
11 changes: 7 additions & 4 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5269,8 +5269,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
Expand Down Expand Up @@ -5727,10 +5726,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
}
}// ORCA: End of adaptive PA code segment


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
Expand Down
52 changes: 44 additions & 8 deletions src/libslic3r/GCode/ExtrusionProcessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
const AABBTreeLines::LinesDistancer<L> &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<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
Expand Down Expand Up @@ -118,7 +119,13 @@ std::vector<ExtendedPoint> 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) {

// 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);
Expand All @@ -131,7 +138,11 @@ std::vector<ExtendedPoint> 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);
}
}
if (t1 > 0.0) {
auto p1 = curr.position + t1 * (next.position - curr.position);
Expand All @@ -140,7 +151,11 @@ std::vector<ExtendedPoint> 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);
}
}
}
}
Expand Down Expand Up @@ -300,9 +315,30 @@ class ExtrusionQualityEstimator
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 =
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width);
// 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;

// 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;
std::vector<ProcessedPoint> processed_points;
processed_points.reserve(extended_points.size());
Expand All @@ -323,7 +359,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());

Expand Down Expand Up @@ -376,7 +412,7 @@ class ExtrusionQualityEstimator
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));
Expand Down

0 comments on commit c5d417e

Please sign in to comment.