From 6cea772d4f3b2f7e2a43c35a2271e4bdbba9eadd Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Fri, 24 Jan 2025 15:56:53 +0800 Subject: [PATCH] ENH: add eager lift function 1.Immediate do lift in eager_lift function jira:NONE Signed-off-by: xun.zhang Change-Id: I931d22e901e2123bb886c31d8d1a5788fddeed42 --- src/libslic3r/GCode.cpp | 39 ++++++++------ src/libslic3r/GCode.hpp | 2 +- src/libslic3r/GCodeWriter.cpp | 98 ++++++++++++++++++++++++----------- src/libslic3r/GCodeWriter.hpp | 7 ++- 4 files changed, 96 insertions(+), 50 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c96a30043..377060432 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3589,13 +3589,16 @@ GCode::LayerResult GCode::process_layer( } PrinterStructure printer_structure = m_config.printer_structure.value; + PrintSequence print_sequence = m_config.print_sequence; + bool sequence_by_layer = print_sequence == PrintSequence::ByLayer; + bool is_i3_printer = printer_structure == PrinterStructure::psI3; + bool is_multi_extruder = m_config.nozzle_diameter.size() > 1; + bool need_insert_timelapse_gcode_for_traditional = false; if (!m_spiral_vase && (!m_wipe_tower || !m_wipe_tower->enable_timelapse_print())) { - if (printer_structure == PrinterStructure::psI3 && print.config().print_sequence == PrintSequence::ByLayer) - need_insert_timelapse_gcode_for_traditional = true; - else if (m_config.nozzle_diameter.values.size() == 2 && print.config().print_sequence == PrintSequence::ByLayer) - need_insert_timelapse_gcode_for_traditional = true; + need_insert_timelapse_gcode_for_traditional = (is_i3_printer || is_multi_extruder); } + bool has_insert_timelapse_gcode = false; bool has_wipe_tower = (layer_tools.has_wipe_tower && m_wipe_tower); @@ -3990,7 +3993,7 @@ GCode::LayerResult GCode::process_layer( } if (should_insert) { - gcode += this->retract(false, false, LiftType::NormalLift); + gcode += this->retract(false, false, LiftType::SpiralLift,true); m_writer.add_object_change_labels(gcode); std::string timepals_gcode = insert_timelapse_gcode(); @@ -4219,7 +4222,7 @@ GCode::LayerResult GCode::process_layer( if (is_infill_first && !first_layer) { if (!has_wipe_tower && need_insert_timelapse_gcode_for_traditional && printer_structure == PrinterStructure::psI3 && !has_insert_timelapse_gcode && has_infill(by_region_specific)) { - gcode += this->retract(false, false, LiftType::NormalLift); + gcode += this->retract(false, false, LiftType::SpiralLift,true); if (!temp_start_str.empty() && m_writer.empty_object_start_str()) { std::string end_str = std::string("; stop printing object, unique label id: ") + std::to_string(instance_to_print.label_object_id) + "\n"; if (print.is_BBL_Printer()) @@ -4249,7 +4252,7 @@ GCode::LayerResult GCode::process_layer( gcode += this->extrude_perimeters(print, by_region_specific); if (!has_wipe_tower && need_insert_timelapse_gcode_for_traditional && printer_structure == PrinterStructure::psI3 && !has_insert_timelapse_gcode && has_infill(by_region_specific)) { - gcode += this->retract(false, false, LiftType::NormalLift); + gcode += this->retract(false, false, LiftType::SpiralLift,true); if (!temp_start_str.empty() && m_writer.empty_object_start_str()) { std::string end_str = std::string("; stop printing object, unique label id: ") + std::to_string(instance_to_print.label_object_id) + "\n"; if (print.is_BBL_Printer()) @@ -4348,13 +4351,13 @@ GCode::LayerResult GCode::process_layer( && (writer().filament() && get_extruder_id(writer().filament()->id()) != most_used_extruder)) { m_support_traditional_timelapse = false; } - - gcode += this->retract(false, false, LiftType::SpiralLift); + int layer_id = m_layer->id(); + gcode += this->retract(false, false, LiftType::SpiralLift,true); m_writer.add_object_change_labels(gcode); std::string timepals_gcode = insert_timelapse_gcode(); gcode += timepals_gcode; - m_writer.set_current_position_clear(true); + m_writer.set_current_position_clear(false); //BBS: check whether custom gcode changes the z position. Update if changed double temp_z_after_timepals_gcode; if (GCodeProcessor::get_last_z_from_gcode(timepals_gcode, temp_z_after_timepals_gcode)) { @@ -5742,7 +5745,7 @@ LiftType GCode::to_lift_type(ZHopType z_hop_types) { case ZHopType::zhtNormal: return LiftType::NormalLift; case ZHopType::zhtSlope: - return LiftType::LazyLift; + return LiftType::SlopeLift; case ZHopType::zhtSpiral: return LiftType::SpiralLift; default: @@ -5833,7 +5836,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp //Better way is judging whether the travel move direction is same with last extrusion move. if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) { if (ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto) { - lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift; + lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::SlopeLift; } else { lift_type = to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types))); @@ -5862,7 +5865,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp // retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter if (ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto) { - lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift; + lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::SlopeLift; } else { lift_type = to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types))); @@ -5870,7 +5873,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp return true; } -std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type) +std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type,bool apply_instantly) { std::string gcode; @@ -5891,9 +5894,13 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li gcode += m_writer.reset_e(); //BBS - if (m_writer.filament()->retraction_length() > 0||m_config.use_firmware_retraction) { + if (m_writer.filament()->retraction_length() > 0 || m_config.use_firmware_retraction) { // BBS: force to use normal lift for spiral vase mode - gcode += m_writer.lift(lift_type, m_spiral_vase != nullptr); + if (apply_instantly) + gcode += m_writer.eager_lift(lift_type); + else + gcode += m_writer.lazy_lift(lift_type, m_spiral_vase != nullptr); + } return gcode; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 4b0bdfd58..a655e1752 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -221,7 +221,7 @@ public: // BBS: detect lift type in needs_retraction bool needs_retraction(const Polyline &travel, ExtrusionRole role, LiftType &lift_type); - std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift); + std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift, bool apply_instantly = false); std::string unretract() { return m_writer.unlift() + m_writer.unretract(); } //BBS bool is_BBL_Printer(); diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 59eb6546a..65ef8e879 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -350,6 +350,71 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com return w.string(); } +/* If this method is called more than once before calling unlift(), +it will not perform subsequent lifts, even if Z was raised manually +(i.e. with travel_to_z()) and thus _lifted was reduced. */ +std::string GCodeWriter::lazy_lift(LiftType lift_type, bool spiral_vase) +{ + // check whether the above/below conditions are met + double target_lift = 0; + { + //BBS + int extruder_id = filament()->extruder_id(); + int filament_id = filament()->id(); + double above = this->config.retract_lift_above.get_at(extruder_id); + double below = this->config.retract_lift_below.get_at(extruder_id); + if (m_pos.z() >= above && m_pos.z() <= below) + target_lift = this->config.z_hop.get_at(filament_id); + } + // BBS + if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) { + if (spiral_vase) { + m_lifted = target_lift; + return this->_travel_to_z(m_pos(2) + target_lift, "lift Z"); + } + else { + m_to_lift = target_lift; + m_to_lift_type = lift_type; + } + } + return ""; +} + +// BBS: immediately execute an undelayed lift move with a spiral lift pattern +// designed specifically for subsequent gcode injection (e.g. timelapse) +std::string GCodeWriter::eager_lift(const LiftType type) { + std::string lift_move; + double target_lift = 0; + { + //BBS + int extruder_id = filament()->extruder_id(); + int filament_id = filament()->id(); + double above = this->config.retract_lift_above.get_at(extruder_id); + double below = this->config.retract_lift_below.get_at(extruder_id); + if (m_pos.z() >= above && m_pos.z() <= below) + target_lift = this->config.z_hop.get_at(filament_id); + } + + // BBS: spiral lift only safe with known position + // TODO: check the arc will move within bed area + if (type == LiftType::SpiralLift && this->is_current_position_clear()) { + double radius = target_lift / (2 * PI * atan(GCodeWriter::slope_threshold)); + // static spiral alignment when no move in x,y plane. + // spiral centra is a radius distance to the right (y=0) + Vec2d ij_offset = { radius, 0 }; + if (target_lift > 0) { + lift_move = this->_spiral_travel_to_z(m_pos(2) + target_lift, ij_offset, "spiral lift Z"); + } + } + //BBS: if position is unknown use normal lift + else if (target_lift > 0) { + lift_move = _travel_to_z(m_pos(2) + target_lift, "normal lift Z"); + } + m_lifted = target_lift; + m_to_lift = 0; + return lift_move; +} + std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment) { // FIXME: This function was not being used when travel_speed_z was separated (bd6badf). @@ -393,8 +458,8 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co ij_offset = { -ij_offset(1), ij_offset(0) }; slop_move = this->_spiral_travel_to_z(target(2), ij_offset, "spiral lift Z"); } - //BBS: LazyLift - else if (m_to_lift_type == LiftType::LazyLift && + //BBS: SlopeLift + else if (m_to_lift_type == LiftType::SlopeLift && this->is_current_position_clear() && atan2(delta(2), delta_no_z.norm()) < GCodeWriter::slope_threshold) { //BBS: check whether we can make a travel like @@ -682,35 +747,6 @@ std::string GCodeWriter::unretract() return gcode; } -/* If this method is called more than once before calling unlift(), - it will not perform subsequent lifts, even if Z was raised manually - (i.e. with travel_to_z()) and thus _lifted was reduced. */ -std::string GCodeWriter::lift(LiftType lift_type, bool spiral_vase) -{ - // check whether the above/below conditions are met - double target_lift = 0; - { - //BBS - int extruder_id = filament()->extruder_id(); - int filament_id = filament()->id(); - double above = this->config.retract_lift_above.get_at(extruder_id); - double below = this->config.retract_lift_below.get_at(extruder_id); - if (m_pos.z() >= above && m_pos.z() <= below) - target_lift = this->config.z_hop.get_at(filament_id); - } - // BBS - if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) { - if (spiral_vase) { - m_lifted = target_lift; - return this->_travel_to_z(m_pos(2) + target_lift, "lift Z"); - } - else { - m_to_lift = target_lift; - m_to_lift_type = lift_type; - } - } - return ""; -} std::string GCodeWriter::unlift() { diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index dc975a25c..f26c04a1b 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -13,7 +13,7 @@ namespace Slic3r { enum class LiftType { NormalLift, - LazyLift, + SlopeLift, SpiralLift }; @@ -80,7 +80,10 @@ public: std::string retract(bool before_wipe = false); std::string retract_for_toolchange(bool before_wipe = false); std::string unretract(); - std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false); + // do lift instantly + std::string eager_lift(const LiftType type); + // record a lift request, do realy lift in next travel + std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false); std::string unlift(); Vec3d get_position() const { return m_pos; } void set_position(Vec3d& in) { m_pos = in; }