mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 10:17:55 -06:00
Detection of curled edges to enhance slowdown for overhangs algorithm (#2056)
* Overhang perimeter handling Updated code to handle overhang perimeters as an overhang and not as a bridge. * Preparing to add curled extrusions identification * Porting curling calculations from Prusa Slier 2.6.1 * Prototype 1 - slowdown extended to detect curled edges and further reduce speed First prototype of the code submitted. * Working prototype - 2 Code is now finally working - external perimeters are slowed down as needed when there is likelyhood of curling up. ToDo: 1. Reslicing the model causes the algorithm not to run - need to find where this fails to trigger the call for this. 2. Slowdown of internal perimeters not working yet. * Updated to use overhang wall speed instead of bridging speed for this algorithm * Fixed bug in speed calculation and tweaked parameters for high speed printer Fixed bug in speed calculation and tweaked parameters for high speed printer * Attempting to fix "set started" not being set * Parameter tweak after print tests * Fixed estimation not running when model is re-sliced. * Removing debug printf statements and fixed threading flag. * Fixed threading * Parameter tweaks following print tests * Made this as an option in the GUI * Reintroduced handling of bridges as per original design * UI line toggling when option makes sense to be visible. * Fixed bug in field visibility & made it default to off * Code optimisation --------- Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
bcedb431ab
commit
61437b2c76
16 changed files with 322 additions and 143 deletions
|
@ -247,6 +247,8 @@ class ExtrusionQualityEstimator
|
|||
{
|
||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<Linef>> prev_layer_boundaries;
|
||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<Linef>> next_layer_boundaries;
|
||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> prev_curled_extrusions;
|
||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> next_curled_extrusions;
|
||||
const PrintObject *current_object;
|
||||
|
||||
public:
|
||||
|
@ -258,16 +260,22 @@ public:
|
|||
const PrintObject *object = obj;
|
||||
prev_layer_boundaries[object] = next_layer_boundaries[object];
|
||||
next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef>{to_unscaled_linesf(layer->lslices)};
|
||||
prev_curled_extrusions[object] = next_curled_extrusions[object];
|
||||
next_curled_extrusions[object] = AABBTreeLines::LinesDistancer<CurledLine>{layer->curled_lines};
|
||||
}
|
||||
|
||||
std::vector<ProcessedPoint> estimate_extrusion_quality(const ExtrusionPath &path,
|
||||
const ConfigOptionPercents &overlaps,
|
||||
const ConfigOptionFloatsOrPercents &speeds,
|
||||
float ext_perimeter_speed,
|
||||
float original_speed)
|
||||
float original_speed,
|
||||
bool slowdown_for_curled_edges)
|
||||
{
|
||||
size_t speed_sections_count = std::min(overlaps.values.size(), speeds.values.size());
|
||||
std::vector<std::pair<float, float>> speed_sections;
|
||||
|
||||
|
||||
|
||||
for (size_t i = 0; i < speed_sections_count; i++) {
|
||||
float distance = path.width * (1.0 - (overlaps.get_at(i) / 100.0));
|
||||
float speed = speeds.get_at(i).percent ? (ext_perimeter_speed * speeds.get_at(i).value / 100.0) : speeds.get_at(i).value;
|
||||
|
@ -297,6 +305,56 @@ public:
|
|||
for (size_t i = 0; i < extended_points.size(); i++) {
|
||||
const ExtendedPoint &curr = extended_points[i];
|
||||
const ExtendedPoint &next = extended_points[i + 1 < extended_points.size() ? i + 1 : i];
|
||||
|
||||
float artificial_distance_to_curled_lines = 0.0;
|
||||
if(slowdown_for_curled_edges) {
|
||||
// The following code artifically increases the distance to provide slowdown for extrusions that are over curled lines
|
||||
const double dist_limit = 10.0 * path.width;
|
||||
{
|
||||
Vec2d middle = 0.5 * (curr.position + next.position);
|
||||
auto line_indices = prev_curled_extrusions[current_object].all_lines_in_radius(Point::new_scale(middle), scale_(dist_limit));
|
||||
if (!line_indices.empty()) {
|
||||
double len = (next.position - curr.position).norm();
|
||||
// For long lines, there is a problem with the additional slowdown. If by accident, there is small curled line near the middle of this long line
|
||||
// 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) {
|
||||
Vec2d dir = Vec2d(next.position - curr.position) / len;
|
||||
Vec2d right = Vec2d(-dir.y(), dir.x());
|
||||
|
||||
Polygon box_of_influence = {
|
||||
scaled(Vec2d(curr.position + right * dist_limit)),
|
||||
scaled(Vec2d(next.position + right * dist_limit)),
|
||||
scaled(Vec2d(next.position - right * dist_limit)),
|
||||
scaled(Vec2d(curr.position - right * dist_limit)),
|
||||
};
|
||||
|
||||
double projected_lengths_sum = 0;
|
||||
for (size_t idx : line_indices) {
|
||||
const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
|
||||
Lines inside = intersection_ln({{line.a, line.b}}, {box_of_influence});
|
||||
if (inside.empty())
|
||||
continue;
|
||||
double projected_length = abs(dir.dot(unscaled(Vec2d((inside.back().b - inside.back().a).cast<double>()))));
|
||||
projected_lengths_sum += projected_length;
|
||||
}
|
||||
if (projected_lengths_sum < 0.4 * len) {
|
||||
line_indices.clear();
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t idx : line_indices) {
|
||||
const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
|
||||
float distance_from_curled = unscaled(line_alg::distance_to(line, Point::new_scale(middle)));
|
||||
float dist = path.width * (1.0 - (distance_from_curled / dist_limit)) *
|
||||
(1.0 - (distance_from_curled / dist_limit)) *
|
||||
(line.curled_height / (path.height * 10.0f)); // max_curled_height_factor from SupportSpotGenerator
|
||||
artificial_distance_to_curled_lines = std::max(artificial_distance_to_curled_lines, dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto calculate_speed = [&speed_sections, &original_speed](float distance) {
|
||||
float final_speed;
|
||||
|
@ -316,10 +374,15 @@ public:
|
|||
}
|
||||
return final_speed;
|
||||
};
|
||||
|
||||
|
||||
float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance));
|
||||
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
|
||||
}
|
||||
|
||||
float overlap = std::min(1 - curr.distance * width_inv, 1 - next.distance * width_inv);
|
||||
|
||||
|
||||
processed_points.push_back({ scaled(curr.position), extrusion_speed, overlap });
|
||||
}
|
||||
return processed_points;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue