From bf6a8dc0b08c679cfd7faeb49170cf60f62474f6 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 20 Jul 2023 10:59:14 +0200 Subject: [PATCH] updating the gcode extrude to support new overhang attributes --- src/libslic3r/GCode.cpp | 65 +++++++++++++++++----- src/libslic3r/GCode.hpp | 2 - src/libslic3r/GCode/ExtrusionProcessor.cpp | 7 ++- src/libslic3r/GCode/ExtrusionProcessor.hpp | 65 ++++++++++++---------- 4 files changed, 90 insertions(+), 49 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index eff430fdb0..d4a663c60c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2047,10 +2047,6 @@ LayerResult GCodeGenerator::process_layer( } } - for (const ObjectLayerToPrint &layer_to_print : layers) { - m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.object_layer); - } - // Extrude the skirt, brim, support, perimeters, infill ordered by the extruders. for (unsigned int extruder_id : layer_tools.extruders) { @@ -2182,8 +2178,6 @@ void GCodeGenerator::process_layer_single_object( const PrintObject &print_object = print_instance.print_object; const Print &print = *print_object.print(); - m_extrusion_quality_estimator.set_current_object(&print_object); - if (! print_wipe_extrusions && layer_to_print.support_layer != nullptr) if (const SupportLayer &support_layer = *layer_to_print.support_layer; ! support_layer.support_fills.entities.empty()) { ExtrusionRole role = support_layer.support_fills.role(); @@ -2781,10 +2775,7 @@ std::string GCodeGenerator::_extrude( ); } - bool variable_speed_or_fan_speed = false; - std::vector new_points{}; - if ((this->m_config.enable_dynamic_overhang_speeds || this->config().enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())) && - !this->on_first_layer() && path_attr.role.is_perimeter()) { + if (path_attr.overhang_attributes.has_value()) { std::vector> overhangs_with_speeds = {{100, ConfigOptionFloatOrPercent{speed, false}}}; if (this->m_config.enable_dynamic_overhang_speeds) { overhangs_with_speeds = {{0, m_config.overhang_speed_0}, @@ -2807,22 +2798,66 @@ std::string GCodeGenerator::_extrude( if (external_perim_reference_speed == 0) external_perim_reference_speed = m_volumetric_speed / path_attr.mm3_per_mm; if (m_config.max_volumetric_speed.value > 0) - external_perim_reference_speed = std::min(external_perim_reference_speed, m_config.max_volumetric_speed.value / path_attr.mm3_per_mm); + external_perim_reference_speed = std::min(external_perim_reference_speed, + m_config.max_volumetric_speed.value / path_attr.mm3_per_mm); if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) { external_perim_reference_speed = std::min(external_perim_reference_speed, EXTRUDER_CONFIG(filament_max_volumetric_speed) / path_attr.mm3_per_mm); } + ExtrusionProcessor::calculate_overhang_speed(); + + new_points = m_extrusion_quality_estimator.estimate_speed_from_extrusion_quality( - //FIXME convert estimate_speed_from_extrusion_quality() to smooth paths or move it before smooth path interpolation. - Points{}, - path_attr, overhangs_with_speeds, overhang_w_fan_speeds, - m_writer.extruder()->id(), external_perim_reference_speed, + // FIXME convert estimate_speed_from_extrusion_quality() to smooth paths or move it before smooth path interpolation. + Points{}, path_attr, 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(), [speed](const ProcessedPoint &p) { return p.speed != speed || p.fan_speed != 0; }); } + // bool variable_speed_or_fan_speed = false; + // std::vector new_points{}; + // if ((this->m_config.enable_dynamic_overhang_speeds || this->config().enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())) && + // !this->on_first_layer() && path_attr.role.is_perimeter()) { + // std::vector> overhangs_with_speeds = {{100, ConfigOptionFloatOrPercent{speed, false}}}; + // if (this->m_config.enable_dynamic_overhang_speeds) { + // overhangs_with_speeds = {{0, m_config.overhang_speed_0}, + // {25, m_config.overhang_speed_1}, + // {50, m_config.overhang_speed_2}, + // {75, m_config.overhang_speed_3}, + // {100, ConfigOptionFloatOrPercent{speed, false}}}; + // } + + // std::vector> overhang_w_fan_speeds = {{100, ConfigOptionInts{0}}}; + // if (this->m_config.enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())) { + // overhang_w_fan_speeds = {{0, m_config.overhang_fan_speed_0}, + // {25, m_config.overhang_fan_speed_1}, + // {50, m_config.overhang_fan_speed_2}, + // {75, m_config.overhang_fan_speed_3}, + // {100, ConfigOptionInts{0}}}; + // } + + // double external_perim_reference_speed = m_config.get_abs_value("external_perimeter_speed"); + // if (external_perim_reference_speed == 0) + // external_perim_reference_speed = m_volumetric_speed / path_attr.mm3_per_mm; + // if (m_config.max_volumetric_speed.value > 0) + // external_perim_reference_speed = std::min(external_perim_reference_speed, m_config.max_volumetric_speed.value / path_attr.mm3_per_mm); + // if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) { + // external_perim_reference_speed = std::min(external_perim_reference_speed, + // EXTRUDER_CONFIG(filament_max_volumetric_speed) / path_attr.mm3_per_mm); + // } + + // new_points = m_extrusion_quality_estimator.estimate_speed_from_extrusion_quality( + // //FIXME convert estimate_speed_from_extrusion_quality() to smooth paths or move it before smooth path interpolation. + // Points{}, + // path_attr, 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(), + // [speed](const ProcessedPoint &p) { return p.speed != speed || p.fan_speed != 0; }); + // } + double F = speed * 60; // convert mm/sec to mm/min // extrude arc or line diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 73e1a793fa..1c92874922 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -293,8 +293,6 @@ private: // Cache for custom seam enforcers/blockers for each layer. SeamPlacer m_seam_placer; - ExtrusionQualityEstimator m_extrusion_quality_estimator; - /* Origin of print coordinates expressed in unscaled G-code coordinates. This affects the input arguments supplied to the extrude*() and travel_to() methods. */ diff --git a/src/libslic3r/GCode/ExtrusionProcessor.cpp b/src/libslic3r/GCode/ExtrusionProcessor.cpp index c7d56c3dbd..2481efb1e2 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.cpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.cpp @@ -1,6 +1,7 @@ #include "ExtrusionProcessor.hpp" +#include -namespace Slic3r { +namespace Slic3r { namespace ExtrusionProcessor { ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath &path, const AABBTreeLines::LinesDistancer &unscaled_prev_layer, @@ -83,6 +84,8 @@ ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath result.back().polyline.append(Point::new_scale(extended_points[i].position)); } + std::cout << "ExtrusionPath " << std::to_string(size_t(&path)) << " split to " << result.size() << " paths"; + return result; }; @@ -126,4 +129,4 @@ ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const Extru return result; }; -} // namespace Slic3r \ No newline at end of file +}} // namespace Slic3r::ExtrusionProcessor \ No newline at end of file diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index c303618e46..a9787f212f 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -28,13 +28,13 @@ #include #include -namespace Slic3r { +namespace Slic3r { namespace ExtrusionProcessor { struct ExtendedPoint { - Vec2d position; - float distance; - float curvature; + Vec2d position; + float distance; + float curvature; }; template @@ -48,27 +48,30 @@ std::vector estimate_points_properties(const POINTS using AABBScalar = typename AABBTreeLines::LinesDistancer::Scalar; if (input_points.empty()) return {}; - float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f; - auto maybe_unscale = [](const P &p) { return SCALED_INPUT ? unscaled(p) : p.template cast(); }; + float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f; + auto maybe_unscale = [](const P &p) { return SCALED_INPUT ? unscaled(p) : p.template cast(); }; std::vector points; points.reserve(input_points.size() * (ADD_INTERSECTIONS ? 1.5 : 1)); { ExtendedPoint start_point{maybe_unscale(input_points.front())}; - auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra(start_point.position.cast()); - start_point.distance = distance + boundary_offset; + auto [distance, nearest_line, + x] = unscaled_prev_layer.template distance_from_lines_extra(start_point.position.cast()); + start_point.distance = distance + boundary_offset; points.push_back(start_point); } for (size_t i = 1; i < input_points.size(); i++) { ExtendedPoint next_point{maybe_unscale(input_points[i])}; - auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra(next_point.position.cast()); - next_point.distance = distance + boundary_offset; + auto [distance, nearest_line, + x] = unscaled_prev_layer.template distance_from_lines_extra(next_point.position.cast()); + next_point.distance = distance + boundary_offset; 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()}); + 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) { ExtendedPoint p{}; p.position = intersection.first.template cast(); @@ -81,7 +84,7 @@ std::vector estimate_points_properties(const POINTS if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS) { std::vector new_points; - new_points.reserve(points.size()*2); + new_points.reserve(points.size() * 2); new_points.push_back(points.front()); for (int point_idx = 0; point_idx < int(points.size()) - 1; ++point_idx) { const ExtendedPoint &curr = points[point_idx]; @@ -97,19 +100,21 @@ std::vector estimate_points_properties(const POINTS double t1 = std::max(a0, a1); 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()); + 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()); ExtendedPoint new_p{}; - new_p.position = p0; - new_p.distance = float(p0_dist + boundary_offset); + new_p.position = p0; + new_p.distance = float(p0_dist + boundary_offset); 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()); + 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()); ExtendedPoint new_p{}; - new_p.position = p1; - new_p.distance = float(p1_dist + boundary_offset); + new_p.position = p1; + new_p.distance = float(p1_dist + boundary_offset); new_points.push_back(new_p); } } @@ -121,7 +126,7 @@ std::vector estimate_points_properties(const POINTS if (max_line_length > 0) { std::vector new_points; - new_points.reserve(points.size()*2); + new_points.reserve(points.size() * 2); { for (size_t i = 0; i + 1 < points.size(); i++) { const ExtendedPoint &curr = points[i]; @@ -135,8 +140,8 @@ std::vector estimate_points_properties(const POINTS auto [p_dist, p_near_l, p_x] = unscaled_prev_layer.template distance_from_lines_extra(pos.cast()); ExtendedPoint new_p{}; - new_p.position = pos; - new_p.distance = float(p_dist + boundary_offset); + new_p.position = pos; + new_p.distance = float(p_dist + boundary_offset); new_points.push_back(new_p); } } @@ -213,14 +218,14 @@ std::vector estimate_points_properties(const POINTS return points; } - ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath &path, - const AABBTreeLines::LinesDistancer &unscaled_prev_layer, + const AABBTreeLines::LinesDistancer &unscaled_prev_layer, const AABBTreeLines::LinesDistancer &prev_layer_curled_lines); -ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const ExtrusionEntityCollection *ecc, - const AABBTreeLines::LinesDistancer &unscaled_prev_layer, - const AABBTreeLines::LinesDistancer &prev_layer_curled_lines); +ExtrusionEntityCollection calculate_and_split_overhanging_extrusions( + const ExtrusionEntityCollection *ecc, + const AABBTreeLines::LinesDistancer &unscaled_prev_layer, + const AABBTreeLines::LinesDistancer &prev_layer_curled_lines); struct ProcessedPoint { @@ -364,6 +369,6 @@ public: } }; -} // namespace Slic3r +}} // namespace Slic3r::ExtrusionProcessor #endif // slic3r_ExtrusionProcessor_hpp_