diff --git a/src/libslic3r/AABBTreeLines.hpp b/src/libslic3r/AABBTreeLines.hpp index 2136e8edbd..ae5569b517 100644 --- a/src/libslic3r/AABBTreeLines.hpp +++ b/src/libslic3r/AABBTreeLines.hpp @@ -347,7 +347,7 @@ public: std::vector all_lines_in_radius(const Vec<2, typename LineType::Scalar> &point, Floating radius) { - return all_lines_in_radius(this->lines, this->tree, point, radius * radius); + return AABBTreeLines::all_lines_in_radius(this->lines, this->tree, point, radius * radius); } template std::vector, size_t>> intersections_with_line(const LineType &line) const diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 29316a9de5..357071a615 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3036,7 +3036,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de EXTRUDER_CONFIG(filament_max_volumetric_speed) / path.mm3_per_mm); } - new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhangs_with_speeds, overhang_w_fan_speeds, + new_points = m_extrusion_quality_estimator.estimate_speed_from_extrusion_quality(path, overhangs_with_speeds, overhang_w_fan_speeds, m_writer.extruder()->id(), external_perim_reference_speed, speed); variable_speed_or_fan_speed = std::any_of(new_points.begin(), new_points.end(), diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index ffa351c27e..81a1c018ab 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -101,13 +101,10 @@ public: struct ExtendedPoint { - ExtendedPoint(Vec2d position, float distance = 0.0, size_t nearest_prev_layer_line = size_t(-1), float curvature = 0.0) - : position(position), distance(distance), nearest_prev_layer_line(nearest_prev_layer_line), curvature(curvature) - {} - Vec2d position; float distance; size_t nearest_prev_layer_line; + Vec2d nearest_prev_layer_point; float curvature; }; @@ -132,6 +129,7 @@ std::vector estimate_points_properties(const std::vector

auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra(start_point.position.cast()); start_point.distance = distance + boundary_offset; start_point.nearest_prev_layer_line = nearest_line; + start_point.nearest_prev_layer_point = x.template cast(); points.push_back(start_point); } for (size_t i = 1; i < input_points.size(); i++) { @@ -139,13 +137,19 @@ std::vector estimate_points_properties(const std::vector

auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra(next_point.position.cast()); next_point.distance = distance + boundary_offset; next_point.nearest_prev_layer_line = nearest_line; + next_point.nearest_prev_layer_point = x.template cast(); if (ADD_INTERSECTIONS && ((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) { const ExtendedPoint &prev_point = points.back(); auto intersections = unscaled_prev_layer.template intersections_with_line(L{prev_point.position.cast(), next_point.position.cast()}); for (const auto &intersection : intersections) { - points.emplace_back(intersection.first.template cast(), boundary_offset, intersection.second); + ExtendedPoint p{}; + p.position = intersection.first.template cast(); + p.distance = boundary_offset; + p.nearest_prev_layer_line = intersection.second; + p.nearest_prev_layer_point = p.position; + points.push_back(p); } } points.push_back(next_point); @@ -171,12 +175,22 @@ std::vector estimate_points_properties(const std::vector

if (t0 < 1.0) { auto p0 = curr.position + t0 * (next.position - curr.position); auto [p0_dist, p0_near_l, p0_x] = unscaled_prev_layer.template distance_from_lines_extra(p0.cast()); - new_points.push_back(ExtendedPoint{p0, float(p0_dist + boundary_offset), p0_near_l}); + ExtendedPoint new_p{}; + new_p.position = p0; + new_p.distance = float(p0_dist + boundary_offset); + new_p.nearest_prev_layer_line = p0_near_l; + new_p.nearest_prev_layer_point = p0_x.template cast(); + 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, p1_x] = unscaled_prev_layer.template distance_from_lines_extra(p1.cast()); - new_points.push_back(ExtendedPoint{p1, float(p1_dist + boundary_offset), p1_near_l}); + ExtendedPoint new_p{}; + new_p.position = p1; + new_p.distance = float(p1_dist + boundary_offset); + new_p.nearest_prev_layer_line = p1_near_l; + new_p.nearest_prev_layer_point = p1_x.template cast(); + new_points.push_back(new_p); } } } @@ -200,7 +214,12 @@ std::vector estimate_points_properties(const std::vector

Vec2d pos = curr.position * (1.0 - j * t) + next.position * (j * t); auto [p_dist, p_near_l, p_x] = unscaled_prev_layer.template distance_from_lines_extra(pos.cast()); - new_points.push_back(ExtendedPoint{pos, float(p_dist + boundary_offset), p_near_l}); + ExtendedPoint new_p{}; + new_p.position = pos; + new_p.distance = float(p_dist + boundary_offset); + new_p.nearest_prev_layer_line = p_near_l; + new_p.nearest_prev_layer_point = p_x.template cast(); + new_points.push_back(new_p); } } new_points.push_back(points.back()); @@ -301,10 +320,12 @@ public: auto [distance_from_curled, line_idx, p] = prev_curled_extrusions[current_object].distance_from_lines_extra(Point::new_scale(ep.position)); if (distance_from_curled < scale_(2.0 * path.width)) { - float articifally_increased_distance = path.width * - prev_curled_extrusions[current_object].get_line(line_idx).curled_height / - (path.height * 10.0f); // max_curled_height_factor from SupportSpotGenerator - ep.distance = std::max(ep.distance, articifally_increased_distance); + float artificially_increased_distance = path.width * + (1.0 - (unscaled(distance_from_curled) / (2.0 * path.width)) * + (unscaled(distance_from_curled) / (2.0 * path.width))) * + (prev_curled_extrusions[current_object].get_line(line_idx).curled_height / + (path.height * 10.0f)); // max_curled_height_factor from SupportSpotGenerator + ep.distance = std::max(ep.distance, artificially_increased_distance); } } diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index 71ea7264d0..15a4aa535f 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -13,6 +13,7 @@ #include "PrintBase.hpp" #include "PrintConfig.hpp" #include "Tesselate.hpp" +#include "Utils.hpp" #include "libslic3r.h" #include "tbb/parallel_for.h" #include "tbb/blocked_range.h" @@ -247,6 +248,32 @@ float estimate_curled_up_height( return curled_up_height; } +std::tuple get_bottom_extrusions_quality_and_curling(const LD &prev_layer_lines, const ExtendedPoint &curr_point) +{ + if (prev_layer_lines.get_lines().empty()) { + return {1.0,0.0}; + } + const ExtrusionLine nearest_prev_layer_line = prev_layer_lines.get_line(curr_point.nearest_prev_layer_line); + float quality = nearest_prev_layer_line.form_quality; + float curling = nearest_prev_layer_line.curled_up_height; + if ((curr_point.nearest_prev_layer_point.cast() - nearest_prev_layer_line.a).squaredNorm() < 0.1) { + const auto& prev_line = prev_layer_lines.get_line(prev_idx_modulo(curr_point.nearest_prev_layer_line, prev_layer_lines.get_lines().size())); + if ((curr_point.nearest_prev_layer_point.cast() - prev_line.b).squaredNorm() < 0.1) { + quality = 0.5 * (quality + prev_line.form_quality); + curling = 0.5 * (curling + prev_line.curled_up_height); + } + } else if ((curr_point.nearest_prev_layer_point.cast() - nearest_prev_layer_line.b).squaredNorm() < 0.1) { + const auto &next_line = prev_layer_lines.get_line( + next_idx_modulo(curr_point.nearest_prev_layer_line, prev_layer_lines.get_lines().size())); + if ((curr_point.nearest_prev_layer_point.cast() - next_line.a).squaredNorm() < 0.1) { + quality = 0.5 * (quality + next_line.form_quality); + curling = 0.5 * (curling + next_line.curled_up_height); + } + } + + return {quality, curling}; +} + std::vector check_extrusion_entity_stability(const ExtrusionEntity *entity, const LayerRegion *layer_region, const LD &prev_layer_lines, @@ -335,9 +362,7 @@ std::vector check_extrusion_entity_stability(const ExtrusionEntit float line_len = (prev_point.position - curr_point.position).norm(); ExtrusionLine line_out{prev_point.position.cast(), curr_point.position.cast(), line_len, entity}; - const ExtrusionLine nearest_prev_layer_line = prev_layer_lines.get_lines().size() > 0 ? - prev_layer_lines.get_line(curr_point.nearest_prev_layer_line) : - ExtrusionLine{}; + auto [prev_layer_quality, prev_layer_curling] = get_bottom_extrusions_quality_and_curling(prev_layer_lines, curr_point); // correctify the distance sign using slice polygons float sign = (prev_layer_boundary.distance_from_lines(curr_point.position) + 0.5f * flow_width) < 0.0f ? -1.0f : 1.0f; @@ -362,7 +387,7 @@ std::vector check_extrusion_entity_stability(const ExtrusionEntit } } else if (curr_point.distance > flow_width * 0.8f) { bridged_distance += line_len; - line_out.form_quality = nearest_prev_layer_line.form_quality - 0.3f; + line_out.form_quality = prev_layer_quality - 0.3f; if (line_out.form_quality < 0 && bridged_distance > max_bridge_len) { line_out.support_point_generated = potential_cause; line_out.form_quality = 0.5f; @@ -373,7 +398,7 @@ std::vector check_extrusion_entity_stability(const ExtrusionEntit } line_out.curled_up_height = estimate_curled_up_height(curr_point, layer_region->layer()->height, flow_width, - nearest_prev_layer_line.curled_up_height, params); + prev_layer_curling, params); lines_out.push_back(line_out); } @@ -1082,6 +1107,7 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width, ExtrusionLine line_out{i > 0 ? annotated_points[i - 1].position.cast() : curr_point.position.cast(), curr_point.position.cast(), line_len, extrusion}; + auto [prev_layer_quality, prev_layer_curling] = get_bottom_extrusions_quality_and_curling(prev_layer_lines, curr_point); const ExtrusionLine nearest_prev_layer_line = prev_layer_lines.get_lines().size() > 0 ? prev_layer_lines.get_line(curr_point.nearest_prev_layer_line) : ExtrusionLine{}; @@ -1094,7 +1120,7 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width, } line_out.curled_up_height = estimate_curled_up_height(curr_point, l->height, flow_width, - nearest_prev_layer_line.curled_up_height, params); + prev_layer_curling, params); current_layer_lines.push_back(line_out); } @@ -1158,16 +1184,14 @@ void estimate_malformations(LayerPtrs &layers, const Params ¶ms) ExtrusionLine line_out{i > 0 ? annotated_points[i - 1].position.cast() : curr_point.position.cast(), curr_point.position.cast(), line_len, extrusion}; - const ExtrusionLine nearest_prev_layer_line = prev_layer_lines.get_lines().size() > 0 ? - prev_layer_lines.get_line(curr_point.nearest_prev_layer_line) : - ExtrusionLine{}; + auto [prev_layer_quality, prev_layer_curling] = get_bottom_extrusions_quality_and_curling(prev_layer_lines, curr_point); float sign = (prev_layer_boundary.distance_from_lines(curr_point.position) + 0.5f * flow_width) < 0.0f ? -1.0f : 1.0f; curr_point.distance *= sign; line_out.curled_up_height = estimate_curled_up_height(curr_point, layer_region->layer()->height, flow_width, - nearest_prev_layer_line.curled_up_height, params); + prev_layer_curling, params); current_layer_lines.push_back(line_out); }