mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
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:
parent
cfe21e5e34
commit
c5d417ed89
2 changed files with 51 additions and 12 deletions
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -131,8 +138,12 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||
ExtendedPoint new_p{};
|
||||
new_p.position = p0;
|
||||
new_p.distance = float(p0_dist + boundary_offset);
|
||||
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);
|
||||
auto [p1_dist, p1_near_l,
|
||||
|
@ -140,10 +151,14 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||
ExtendedPoint new_p{};
|
||||
new_p.position = p1;
|
||||
new_p.distance = float(p1_dist + boundary_offset);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
new_points.push_back(next);
|
||||
}
|
||||
points = std::move(new_points);
|
||||
|
@ -301,8 +316,29 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<ExtendedPoint> extended_points =
|
||||
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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());
|
||||
|
@ -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.
|
||||
// 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());
|
||||
|
||||
|
@ -376,7 +412,7 @@ public:
|
|||
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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue