diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4da8af567..47bd6df40 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -238,8 +238,9 @@ namespace Slic3r { std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation); - if (! tcr.priming) { - // Move over the wipe tower. + if (gcodegen.config().single_extruder_multi_material && ! tcr.priming) { + // Move over the wipe tower. If this is not single-extruder MM, the first wipe tower move following the + // toolchange will travel there anyway. gcode += gcodegen.retract(); gcodegen.m_avoid_crossing_perimeters.use_external_mp_once(); gcode += gcodegen.travel_to( diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index f24311a13..87f04f08c 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -71,6 +71,8 @@ public: return *this; } + WipeTowerWriter& set_position(const Vec2f &pos) { m_current_pos = pos; return *this; } + WipeTowerWriter& set_initial_tool(size_t tool) { m_current_tool = tool; return *this; } WipeTowerWriter& set_z(float z) @@ -802,19 +804,24 @@ void WipeTower::toolchange_Unload( { float xl = cleaning_box.ld.x() + 1.f * m_perimeter_width; float xr = cleaning_box.rd.x() - 1.f * m_perimeter_width; - - const float line_width = m_perimeter_width * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness + + const float line_width = m_perimeter_width * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness const float y_step = line_width * m_filpar[m_current_tool].ramming_step_multiplicator * m_extra_spacing; // spacing between lines in mm + const Vec2f ramming_start_pos = Vec2f(xl, cleaning_box.ld.y() + m_depth_traversed + y_step/2.f); + writer.append("; CP TOOLCHANGE UNLOAD\n") .change_analyzer_line_width(line_width); unsigned i = 0; // iterates through ramming_speed m_left_to_right = true; // current direction of ramming float remaining = xr - xl ; // keeps track of distance to the next turnaround - float e_done = 0; // measures E move done from each segment + float e_done = 0; // measures E move done from each segment - writer.travel(xl, cleaning_box.ld.y() + m_depth_traversed + y_step/2.f ); // move to starting position + if (m_semm) + writer.travel(ramming_start_pos); // move to starting position + else + writer.set_position(ramming_start_pos); // if the ending point of the ram would end up in mid air, align it with the end of the wipe tower: if (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion )) { @@ -849,7 +856,7 @@ void WipeTower::toolchange_Unload( writer.disable_linear_advance(); // now the ramming itself: - while (i < m_filpar[m_current_tool].ramming_speed.size()) + while (m_semm && i < m_filpar[m_current_tool].ramming_speed.size()) { const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * 0.25f, line_width, m_layer_height); const float e = m_filpar[m_current_tool].ramming_speed[i] * 0.25f / filament_area(); // transform volume per sec to E move; @@ -898,7 +905,7 @@ void WipeTower::toolchange_Unload( // Cooling: const int& number_of_moves = m_filpar[m_current_tool].cooling_moves; - if (number_of_moves > 0) { + if (m_semm && number_of_moves > 0) { const float& initial_speed = m_filpar[m_current_tool].cooling_initial_speed; const float& final_speed = m_filpar[m_current_tool].cooling_final_speed; @@ -916,14 +923,20 @@ void WipeTower::toolchange_Unload( } } - // let's wait is necessary: - writer.wait(m_filpar[m_current_tool].delay); - // we should be at the beginning of the cooling tube again - let's move to parking position: - writer.retract(-m_cooling_tube_length/2.f+m_parking_pos_retraction-m_cooling_tube_retraction, 2000); + if (m_semm) { + // let's wait is necessary: + writer.wait(m_filpar[m_current_tool].delay); + // we should be at the beginning of the cooling tube again - let's move to parking position: + writer.retract(-m_cooling_tube_length/2.f+m_parking_pos_retraction-m_cooling_tube_retraction, 2000); + } // this is to align ramming and future wiping extrusions, so the future y-steps can be uniform from the start: // the perimeter_width will later be subtracted, it is there to not load while moving over just extruded material - writer.travel(end_of_ramming.x(), end_of_ramming.y() + (y_step/m_extra_spacing-m_perimeter_width) / 2.f + m_perimeter_width, 2400.f); + Vec2f pos = Vec2f(end_of_ramming.x(), end_of_ramming.y() + (y_step/m_extra_spacing-m_perimeter_width) / 2.f + m_perimeter_width); + if (m_semm) + writer.travel(pos, 2400.f); + else + writer.set_position(pos); writer.resume_preview() .flush_planner_queue(); diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 397b5ab7d..ab3af507d 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -290,7 +290,6 @@ private: // Extruder specific parameters. std::vector m_filpar; - // State of the wipe tower generator. unsigned int m_num_layer_changes = 0; // Layer change counter for the output statistics. unsigned int m_num_tool_changes = 0; // Tool change change counter for the output statistics.