diff --git a/src/libslic3r/Extruder.cpp b/src/libslic3r/Extruder.cpp index a24085eaf..1a5eebb2b 100644 --- a/src/libslic3r/Extruder.cpp +++ b/src/libslic3r/Extruder.cpp @@ -3,8 +3,8 @@ namespace Slic3r { -double Extruder::m_share_E = 0.; -double Extruder::m_share_retracted = 0.; +std::vector Extruder::m_share_E = {0.,0.}; +std::vector Extruder::m_share_retracted = {0.,0.}; Extruder::Extruder(unsigned int id, GCodeConfig *config, bool share_extruder) : m_id(id), @@ -32,11 +32,11 @@ double Extruder::extrude(double dE) // BBS if (m_share_extruder) { if (m_config->use_relative_e_distances) - m_share_E = 0.; - m_share_E += dE; + m_share_E[extruder_id()] = 0.; + m_share_E[extruder_id()] += dE; m_absolute_E += dE; if (dE < 0.) - m_share_retracted -= dE; + m_share_retracted[extruder_id()] -= dE; } else { // in case of relative E distances we always reset to 0 before any output if (m_config->use_relative_e_distances) @@ -61,12 +61,12 @@ double Extruder::retract(double length, double restart_extra) // BBS if (m_share_extruder) { if (m_config->use_relative_e_distances) - m_share_E = 0.; - double to_retract = std::max(0., length - m_share_retracted); + m_share_E[extruder_id()] = 0.; + double to_retract = std::max(0., length - m_share_retracted[extruder_id()]); if (to_retract > 0.) { - m_share_E -= to_retract; + m_share_E[extruder_id()] -= to_retract; m_absolute_E -= to_retract; - m_share_retracted += to_retract; + m_share_retracted[extruder_id()] += to_retract; } return to_retract; } else { @@ -88,9 +88,9 @@ double Extruder::unretract() { // BBS if (m_share_extruder) { - double dE = m_share_retracted; + double dE = m_share_retracted[extruder_id()]; this->extrude(dE); - m_share_retracted = 0.; + m_share_retracted[extruder_id()] = 0.; return dE; } else { double dE = m_retracted + m_restart_extra; diff --git a/src/libslic3r/Extruder.hpp b/src/libslic3r/Extruder.hpp index 123bfc87f..f2542b00b 100644 --- a/src/libslic3r/Extruder.hpp +++ b/src/libslic3r/Extruder.hpp @@ -17,8 +17,8 @@ public: void reset() { // BBS if (m_share_extruder) { - m_share_E = 0.; - m_share_retracted = 0.; + m_share_E = { 0.,0.}; + m_share_retracted = { 0.,0. }; } else { m_E = 0; m_retracted = 0; @@ -34,8 +34,8 @@ public: double extrude(double dE); double retract(double length, double restart_extra); double unretract(); - double E() const { return m_share_extruder ? m_share_E : m_E; } - void reset_E() { m_E = 0.; m_share_E = 0.; } + double E() const { return m_share_extruder ? m_share_E[extruder_id()] : m_E; } + void reset_E() { m_E = 0.; m_share_E[extruder_id()] = 0.; } double e_per_mm(double mm3_per_mm) const { return mm3_per_mm * m_e_per_mm3; } double e_per_mm3() const { return m_e_per_mm3; } // Used filament volume in mm^3. @@ -78,8 +78,8 @@ private: // BBS. // Create shared E and retraction data for single extruder multi-material machine bool m_share_extruder; - static double m_share_E; - static double m_share_retracted; + static std::vector m_share_E; + static std::vector m_share_retracted; }; // Sort Extruder objects by the extruder id by default. diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 9907bbc87..36aa1a0b2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -518,38 +518,41 @@ static std::vector get_path_of_change_filament(const Print& print) //BBS: increase toolchange count gcodegen.m_toolchange_count++; + std::string toolchange_gcode_str; + // BBS: should be placed before toolchange parsing std::string toolchange_retract_str = gcodegen.retract(true, false); check_add_eol(toolchange_retract_str); // Process the custom change_filament_gcode. If it is empty, provide a simple Tn command to change the filament. // Otherwise, leave control to the user completely. - std::string toolchange_gcode_str; std::string change_filament_gcode = gcodegen.config().change_filament_gcode.value; + // add nozzle change gcode into change filament gcode + { + std::string nozzle_change_gcode_trans; + if (!tcr.nozzle_change_result.gcode.empty()) { + // move to start_pos before nozzle change + std::string start_pos_str; + start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(tcr.nozzle_change_result.start_pos) + plate_origin_2d), erMixed, + "Move to nozzle change start pos"); + check_add_eol(start_pos_str); + nozzle_change_gcode_trans += start_pos_str; + nozzle_change_gcode_trans += gcodegen.unretract(); + nozzle_change_gcode_trans += transform_gcode(tcr.nozzle_change_result.gcode, tcr.nozzle_change_result.start_pos, wipe_tower_offset, wipe_tower_rotation); + gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(tcr.nozzle_change_result.end_pos) + plate_origin_2d)); + gcodegen.m_wipe.reset_path(); + for (const Vec2f& wipe_pt : tcr.nozzle_change_result.wipe_path) + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt) + plate_origin_2d)); + nozzle_change_gcode_trans += gcodegen.retract(true, false); + } - std::string nozzle_change_gcode_trans; - if (!tcr.nozzle_change_result.gcode.empty()) { - // move to start_pos before nozzle change - std::string start_pos_str; - start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(tcr.nozzle_change_result.start_pos) + plate_origin_2d), erMixed, - "Move to nozzle change start pos"); - check_add_eol(start_pos_str); - nozzle_change_gcode_trans += start_pos_str; - nozzle_change_gcode_trans += gcodegen.unretract(); - nozzle_change_gcode_trans += transform_gcode(tcr.nozzle_change_result.gcode, tcr.nozzle_change_result.start_pos, wipe_tower_offset, wipe_tower_rotation); - gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(tcr.nozzle_change_result.end_pos) + plate_origin_2d)); - gcodegen.m_wipe.reset_path(); - for (const Vec2f &wipe_pt : tcr.nozzle_change_result.wipe_path) - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt) + plate_origin_2d)); - nozzle_change_gcode_trans += gcodegen.retract(true, false); + std::string prefix_gcode = lift_gcode_after_printing_object; + if (gcodegen.config().nozzle_diameter.size() > 1) { + prefix_gcode += nozzle_change_gcode_trans; + } + change_filament_gcode = prefix_gcode + change_filament_gcode; } - std::string prefix_gcode = lift_gcode_after_printing_object; - if (gcodegen.config().nozzle_diameter.size() > 1) { - prefix_gcode += nozzle_change_gcode_trans; - } - change_filament_gcode = prefix_gcode + change_filament_gcode; - if (! change_filament_gcode.empty()) { DynamicConfig config; int old_filament_id = gcodegen.writer().filament() ? (int)gcodegen.writer().filament()->id() : -1; @@ -637,8 +640,6 @@ static std::vector get_path_of_change_filament(const Print& print) check_add_eol(toolchange_gcode_str); - // retract before toolchange - toolchange_gcode_str = toolchange_retract_str + toolchange_gcode_str; //BBS { //BBS: current position and fan_speed is unclear after interting change_filament_gcode @@ -655,14 +656,9 @@ static std::vector get_path_of_change_filament(const Print& print) } // move to start_pos for wiping after toolchange - std::string start_pos_str; - start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, start_pos + plate_origin_2d), erMixed, "Move to start pos"); + std::string start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, start_pos + plate_origin_2d), erMixed, "Move to start pos"); check_add_eol(start_pos_str); toolchange_gcode_str += start_pos_str; - - // unretract before wiping - toolchange_gcode_str += gcodegen.unretract(); - check_add_eol(toolchange_gcode_str); } std::string toolchange_command; @@ -674,6 +670,12 @@ static std::vector get_path_of_change_filament(const Print& print) // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. } + // do unretract after setting current extruder_id + std::string toolchange_unretract_str = gcodegen.unretract(); + check_add_eol(toolchange_unretract_str); + + toolchange_gcode_str = toolchange_retract_str + toolchange_gcode_str + toolchange_unretract_str; + gcodegen.placeholder_parser().set("current_extruder", new_filament_id); gcodegen.placeholder_parser().set("retraction_distance_when_cut", gcodegen.m_config.retraction_distances_when_cut.get_at(new_filament_id)); gcodegen.placeholder_parser().set("long_retraction_when_cut", gcodegen.m_config.long_retractions_when_cut.get_at(new_filament_id));