From a5d2fa1aed96b2d2d069ea3682c513480d3f579b Mon Sep 17 00:00:00 2001 From: SoftFever Date: Tue, 1 Oct 2024 23:28:24 +0800 Subject: [PATCH 1/6] Fix an issue that wrong z value was used if a new layer is started with wipe tower extrusions. --- src/libslic3r/GCode.cpp | 16 ++++++++-------- src/libslic3r/GCode.hpp | 4 +--- src/libslic3r/GCodeWriter.hpp | 3 ++- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 572bbcc55b..167a7987a7 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -767,10 +767,10 @@ static std::vector get_path_of_change_filament(const Print& print) toolchange_gcode_str = gcodegen.set_extruder(new_extruder_id, tcr.print_z); // TODO: toolchange_z vs print_z if (gcodegen.config().enable_prime_tower) { deretraction_str += gcodegen.writer().travel_to_z(z, "restore layer Z"); - Vec3d position{gcodegen.writer().get_position()}; - position.z() = z; - gcodegen.writer().set_position(position); - deretraction_str += gcodegen.unretract(); + Vec3d position{gcodegen.writer().get_position()}; + position.z() = z; + gcodegen.writer().set_position(position); + deretraction_str += gcodegen.unretract(); } } @@ -4521,7 +4521,7 @@ std::string GCode::change_layer(coordf_t print_z) m_need_change_layer_lift_z = true; } - m_nominal_z = z; + m_writer.get_position().z() = z; // forget last wiping path as wiping after raising Z is pointless // BBS. Dont forget wiping path to reduce stringing. @@ -5095,7 +5095,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, const auto get_sloped_z = [&sloped, this](double z_ratio) { const auto height = sloped->height; - return lerp(m_nominal_z - height, m_nominal_z, z_ratio); + return lerp(m_writer.get_position().z() - height, m_writer.get_position().z(), z_ratio); }; // go to first point of extrusion path @@ -6011,7 +6011,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (travel.size() == 2) { // No extra movements emitted by avoid_crossing_perimeters, simply move to the end point with z change const auto& dest2d = this->point_to_gcode(travel.points.back()); - Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_nominal_z : z); + Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_writer.get_position().z() : z); gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz"); } else { // Extra movements emitted by avoid_crossing_perimeters, lift the z to normal height at the beginning, then apply the z @@ -6020,7 +6020,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (i == 1) { // Lift to normal z at beginning Vec2d dest2d = this->point_to_gcode(travel.points[i]); - Vec3d dest3d(dest2d(0), dest2d(1), m_nominal_z); + Vec3d dest3d(dest2d(0), dest2d(1), m_writer.get_position().z()); gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz"); } else if (z != DBL_MAX && i == travel.size() - 1) { // Apply z_ratio for the very last point diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 843b4a39da..eaf2c81b64 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -184,8 +184,7 @@ public: m_silent_time_estimator_enabled(false), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())), // BBS - m_toolchange_count(0), - m_nominal_z(0.) + m_toolchange_count(0) {} ~GCode() = default; @@ -591,7 +590,6 @@ private: // BBS Print* m_curr_print = nullptr; unsigned int m_toolchange_count; - coordf_t m_nominal_z; bool m_need_change_layer_lift_z = false; int m_start_gcode_filament = -1; diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 28569e909d..5e5182014e 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -81,7 +81,8 @@ public: std::string unretract(); std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false); std::string unlift(); - Vec3d get_position() const { return m_pos; } + const Vec3d& get_position() const { return m_pos; } + Vec3d& get_position() { return m_pos; } void set_position(const Vec3d& in) { m_pos = in; } double get_zhop() const { return m_lifted; } From 6f3c701a32cad5896f6afa93611f55f28325ea8f Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 6 Oct 2024 10:49:58 +0800 Subject: [PATCH 2/6] wip --- src/libslic3r/GCode.cpp | 14 ++++++++++---- src/libslic3r/GCodeWriter.hpp | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 167a7987a7..e91a8e46d0 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -729,6 +729,9 @@ static std::vector get_path_of_change_filament(const Print& print) gcode += gcodegen.writer().unlift(); // Make sure there is no z-hop (in most cases, there isn't). double current_z = gcodegen.writer().get_position().z(); + gcode += gcodegen.writer().travel_to_z(current_z); + + if (z == -1.) // in case no specific z was provided, print at current_z pos z = current_z; @@ -4516,10 +4519,8 @@ std::string GCode::change_layer(coordf_t print_z) comment << "move to next layer (" << m_layer_index << ")"; gcode += m_writer.travel_to_z(z, comment.str()); } - else { - //BBS: set m_need_change_layer_lift_z to be true so that z lift can be done in travel_to() function - m_need_change_layer_lift_z = true; - } + + m_need_change_layer_lift_z = true; m_writer.get_position().z() = z; @@ -6036,6 +6037,11 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string } this->set_last_pos(travel.points.back()); } + if (m_need_change_layer_lift_z) { + gcode += m_writer._travel_to_z(m_writer.get_position().z(), comment + " travel_to_z"); + m_need_change_layer_lift_z = false; + } + return gcode; } diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 5e5182014e..78c93cb92e 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -119,6 +119,7 @@ public: // Returns whether this flavor supports separate print and travel acceleration. static bool supports_separate_travel_acceleration(GCodeFlavor flavor); + std::string _travel_to_z(double z, const std::string &comment); private: // Extruders are sorted by their ID, so that binary search is possible. std::vector m_extruders; @@ -172,7 +173,6 @@ public: Print }; - std::string _travel_to_z(double z, const std::string &comment); std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment); std::string _retract(double length, double restart_extra, const std::string &comment); std::string set_acceleration_internal(Acceleration type, unsigned int acceleration); From 608e6375e6ae2b859d521537cf20761ae28720f3 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 6 Oct 2024 19:16:15 +0800 Subject: [PATCH 3/6] Fix wrong z when zhop is diabled. --- src/libslic3r/GCode.cpp | 17 +++++++---------- src/libslic3r/GCodeWriter.cpp | 4 ++-- src/libslic3r/GCodeWriter.hpp | 4 ++-- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index e91a8e46d0..6df9b993fa 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -729,7 +729,6 @@ static std::vector get_path_of_change_filament(const Print& print) gcode += gcodegen.writer().unlift(); // Make sure there is no z-hop (in most cases, there isn't). double current_z = gcodegen.writer().get_position().z(); - gcode += gcodegen.writer().travel_to_z(current_z); if (z == -1.) // in case no specific z was provided, print at current_z pos @@ -6006,14 +6005,15 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (m_spiral_vase) { // No lazy z lift for spiral vase mode for (size_t i = 1; i < travel.size(); ++i) { - gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment + " travel_to_xy"); + gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment); } } else { if (travel.size() == 2) { // No extra movements emitted by avoid_crossing_perimeters, simply move to the end point with z change const auto& dest2d = this->point_to_gcode(travel.points.back()); Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_writer.get_position().z() : z); - gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz"); + gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); + m_need_change_layer_lift_z = false; } else { // Extra movements emitted by avoid_crossing_perimeters, lift the z to normal height at the beginning, then apply the z // ratio at the last point @@ -6022,25 +6022,22 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string // Lift to normal z at beginning Vec2d dest2d = this->point_to_gcode(travel.points[i]); Vec3d dest3d(dest2d(0), dest2d(1), m_writer.get_position().z()); - gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz"); + gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); + m_need_change_layer_lift_z = false; } else if (z != DBL_MAX && i == travel.size() - 1) { // Apply z_ratio for the very last point Vec2d dest2d = this->point_to_gcode(travel.points[i]); Vec3d dest3d(dest2d(0), dest2d(1), z); - gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz"); + gcode += m_writer.travel_to_xyz(dest3d, comment); } else { // For all points in between, no z change - gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment + " travel_to_xy"); + gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment); } } } } this->set_last_pos(travel.points.back()); } - if (m_need_change_layer_lift_z) { - gcode += m_writer._travel_to_z(m_writer.get_position().z(), comment + " travel_to_z"); - m_need_change_layer_lift_z = false; - } return gcode; } diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index ad3ad640c0..d17527d115 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -440,7 +440,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com return w.string(); } -std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment) +std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment, bool force_z) { // FIXME: This function was not being used when travel_speed_z was separated (bd6badf). // Calculation of feedrate was not updated accordingly. If you want to use @@ -526,7 +526,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co this->set_current_position_clear(true); return slop_move + xy_z_move; } - else if (!this->will_move_z(point(2))) { + else if (!force_z && !this->will_move_z(point(2))) { double nominal_z = m_pos(2) - m_lifted; m_lifted -= (point(2) - nominal_z); // In case that z_hop == layer_height we could end up with almost zero in_m_lifted diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 78c93cb92e..038325b446 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -69,7 +69,7 @@ public: // SoftFever NOTE: the returned speed is mm/minute double get_current_speed() const { return m_current_speed;} std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string()); - std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string()); + std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string(), bool force_z = false); std::string travel_to_z(double z, const std::string &comment = std::string()); bool will_move_z(double z) const; std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); @@ -119,7 +119,6 @@ public: // Returns whether this flavor supports separate print and travel acceleration. static bool supports_separate_travel_acceleration(GCodeFlavor flavor); - std::string _travel_to_z(double z, const std::string &comment); private: // Extruders are sorted by their ID, so that binary search is possible. std::vector m_extruders; @@ -173,6 +172,7 @@ public: Print }; + std::string _travel_to_z(double z, const std::string &comment); std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment); std::string _retract(double length, double restart_extra, const std::string &comment); std::string set_acceleration_internal(Acceleration type, unsigned int acceleration); From 7736cd1b3923769127975ac2964f8fd3498e608f Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 6 Oct 2024 20:36:00 +0800 Subject: [PATCH 4/6] fixed #6755 --- src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6df9b993fa..ad0e236a4d 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -743,7 +743,7 @@ static std::vector get_path_of_change_filament(const Print& print) || !needs_toolchange // this is just finishing the tower with no toolchange || is_ramming); - if (should_travel_to_tower) { + if (should_travel_to_tower || gcodegen.m_need_change_layer_lift_z) { // FIXME: It would be better if the wipe tower set the force_travel flag for all toolchanges, // then we could simplify the condition and make it more readable. gcode += gcodegen.retract(); From cc90d79190a757c23e2e0c2170ee181b634cc7ad Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 6 Oct 2024 23:39:22 +0800 Subject: [PATCH 5/6] Add back m_nominal_z to store main print_z as GcodeWriter::m_pos will be changed after parsing get_last_z_from_gcode --- src/libslic3r/GCode.cpp | 7 ++++--- src/libslic3r/GCode.hpp | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ad0e236a4d..a5c1a66b08 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4521,6 +4521,7 @@ std::string GCode::change_layer(coordf_t print_z) m_need_change_layer_lift_z = true; + m_nominal_z = z; m_writer.get_position().z() = z; // forget last wiping path as wiping after raising Z is pointless @@ -5095,7 +5096,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, const auto get_sloped_z = [&sloped, this](double z_ratio) { const auto height = sloped->height; - return lerp(m_writer.get_position().z() - height, m_writer.get_position().z(), z_ratio); + return lerp(m_nominal_z - height, m_nominal_z, z_ratio); }; // go to first point of extrusion path @@ -6011,7 +6012,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (travel.size() == 2) { // No extra movements emitted by avoid_crossing_perimeters, simply move to the end point with z change const auto& dest2d = this->point_to_gcode(travel.points.back()); - Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_writer.get_position().z() : z); + Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_nominal_z : z); gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); m_need_change_layer_lift_z = false; } else { @@ -6021,7 +6022,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (i == 1) { // Lift to normal z at beginning Vec2d dest2d = this->point_to_gcode(travel.points[i]); - Vec3d dest3d(dest2d(0), dest2d(1), m_writer.get_position().z()); + Vec3d dest3d(dest2d(0), dest2d(1), m_nominal_z); gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); m_need_change_layer_lift_z = false; } else if (z != DBL_MAX && i == travel.size() - 1) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index eaf2c81b64..843b4a39da 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -184,7 +184,8 @@ public: m_silent_time_estimator_enabled(false), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())), // BBS - m_toolchange_count(0) + m_toolchange_count(0), + m_nominal_z(0.) {} ~GCode() = default; @@ -590,6 +591,7 @@ private: // BBS Print* m_curr_print = nullptr; unsigned int m_toolchange_count; + coordf_t m_nominal_z; bool m_need_change_layer_lift_z = false; int m_start_gcode_filament = -1; From 0bf2b9dcff69fd3e60dcf3fa28d83cd16d508175 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 7 Oct 2024 14:34:08 +0800 Subject: [PATCH 6/6] respect "Enable Filament ramming" option --- src/libslic3r/GCode/WipeTower2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/WipeTower2.cpp b/src/libslic3r/GCode/WipeTower2.cpp index 67ffb9eb51..9e9e8ea22e 100644 --- a/src/libslic3r/GCode/WipeTower2.cpp +++ b/src/libslic3r/GCode/WipeTower2.cpp @@ -1127,7 +1127,7 @@ void WipeTower2::toolchange_Load( WipeTowerWriter2 &writer, const WipeTower::box_coordinates &cleaning_box) { - if (m_semm && (m_parking_pos_retraction != 0 || m_extra_loading_move != 0)) { + if (m_semm && m_enable_filament_ramming && (m_parking_pos_retraction != 0 || m_extra_loading_move != 0)) { float xl = cleaning_box.ld.x() + m_perimeter_width * 0.75f; float xr = cleaning_box.rd.x() - m_perimeter_width * 0.75f; float oldx = writer.x(); // the nozzle is in place to do the first wiping moves, we will remember the position