From 085995b3aa5dbadd7fd274babb99856f0791882d Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 3 Jan 2025 12:12:54 +0800 Subject: [PATCH] FIX: fix error start pos of wipe tower after tool_change jira: none Change-Id: I770030fb624e9c9de3bb0f8fcb4f3c29cab4f347 --- src/libslic3r/GCode.cpp | 12 ++++--- src/libslic3r/GCode/WipeTower.cpp | 57 +++++++++++++++++++++++-------- src/libslic3r/GCode/WipeTower.hpp | 4 +++ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 5e00d1507..d6d0e3d8e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -608,9 +608,13 @@ static std::vector get_path_of_change_filament(const Print& print) Vec2f start_pos = tcr.start_pos; Vec2f end_pos = tcr.end_pos; + Vec2f tool_change_start_pos = start_pos; + if (tcr.is_tool_change) + tool_change_start_pos = tcr.tool_change_start_pos; if (! tcr.priming) { start_pos = transform_wt_pt(start_pos); end_pos = transform_wt_pt(end_pos); + tool_change_start_pos = transform_wt_pt(tool_change_start_pos); } Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos; @@ -746,8 +750,8 @@ static std::vector get_path_of_change_filament(const Print& print) config.set_key_value("new_retract_length_toolchange", new ConfigOptionFloat(new_retract_length_toolchange)); config.set_key_value("old_filament_temp", new ConfigOptionInt(old_filament_temp)); config.set_key_value("new_filament_temp", new ConfigOptionInt(new_filament_temp)); - config.set_key_value("x_after_toolchange", new ConfigOptionFloat(start_pos(0))); - config.set_key_value("y_after_toolchange", new ConfigOptionFloat(start_pos(1))); + config.set_key_value("x_after_toolchange", new ConfigOptionFloat(tool_change_start_pos(0))); + config.set_key_value("y_after_toolchange", new ConfigOptionFloat(tool_change_start_pos(1))); config.set_key_value("z_after_toolchange", new ConfigOptionFloat(nozzle_pos(2))); config.set_key_value("first_flush_volume", new ConfigOptionFloat(purge_length / 2.f)); config.set_key_value("second_flush_volume", new ConfigOptionFloat(purge_length / 2.f)); @@ -803,7 +807,7 @@ static std::vector get_path_of_change_filament(const Print& print) // move to start_pos for wiping after toolchange if (!is_used_travel_avoid_perimeter) { - 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"); + std::string start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d), erMixed, "Move to start pos"); check_add_eol(start_pos_str); toolchange_gcode_str += start_pos_str; } else { @@ -812,7 +816,7 @@ static std::vector get_path_of_change_filament(const Print& print) GCodeProcessor::get_last_position_from_gcode(toolchange_gcode_str, gcode_last_pos); Vec2f gcode_last_pos2d{gcode_last_pos[0], gcode_last_pos[1]}; Point gcode_last_pos2d_object = gcodegen.gcode_to_point(gcode_last_pos2d.cast() + plate_origin_2d.cast()); - Point start_wipe_pos = wipe_tower_point_to_object_point(gcodegen, start_pos + plate_origin_2d); + Point start_wipe_pos = wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d); std::string travel_to_wipe_tower_gcode = generate_path_to_wipe_tower(gcodegen, wipe_tower_point_to_object_point(gcodegen, m_wipe_tower_pos + plate_origin_2d), gcode_last_pos2d_object, start_wipe_pos, scaled(gcodegen.m_config.prime_tower_width.value), scaled(m_wipe_tower_depth), scaled(gcodegen.m_config.prime_tower_brim_width.value)); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 12d853aa6..5d3e417c7 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -604,6 +604,7 @@ WipeTower::ToolChangeResult WipeTower::construct_tcr(WipeTowerWriter& writer, bool priming, size_t old_tool, bool is_finish, + bool is_tool_change, float purge_volume) const { ToolChangeResult result; @@ -620,6 +621,9 @@ WipeTower::ToolChangeResult WipeTower::construct_tcr(WipeTowerWriter& writer, result.wipe_path = std::move(writer.wipe_path()); result.is_finish_first = is_finish; result.nozzle_change_result = m_nozzle_change_result; + result.is_tool_change = is_tool_change; + result.tool_change_start_pos = is_tool_change ? result.start_pos : Vec2f(0, 0); + // BBS result.purge_volume = purge_volume; return result; @@ -983,7 +987,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_per if (m_current_tool < m_used_filament_length.size()) m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); - return construct_tcr(writer, false, old_tool, false, purge_volume); + return construct_tcr(writer, false, old_tool, false, true, purge_volume); } WipeTower::NozzleChangeResult WipeTower::nozzle_change(int old_filament_id, int new_filament_id) @@ -1620,7 +1624,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer(bool extrude_perimeter, bool if (m_current_tool < m_used_filament_length.size()) m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); - return construct_tcr(writer, false, old_tool, true, 0.f); + return construct_tcr(writer, false, old_tool, true, false, 0.f); } // Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box @@ -1856,10 +1860,23 @@ static WipeTower::ToolChangeResult merge_tcr(WipeTower::ToolChangeResult& first, { assert(first.new_tool == second.initial_tool); WipeTower::ToolChangeResult out = first; - if ((first.end_pos - second.start_pos).norm()> (float)EPSILON) - out.gcode += "G1 X" + Slic3r::float_to_string_decimal_point(second.start_pos.x(), 3) - + " Y" + Slic3r::float_to_string_decimal_point(second.start_pos.y(), 3) - + "\n"; + if ((first.end_pos - second.start_pos).norm() > (float)EPSILON) { + std::string travel_gcode = "G1 X" + Slic3r::float_to_string_decimal_point(second.start_pos.x(), 3) + + " Y" + Slic3r::float_to_string_decimal_point(second.start_pos.y(), 3) + "\n"; + bool has_inserted = false; + if (second.is_tool_change + && is_approx(second.start_pos.x(), second.tool_change_start_pos.x()) + && is_approx(second.start_pos.y(), second.tool_change_start_pos.y())) { + size_t insert_pos = second.gcode.find("; CP TOOLCHANGE WIPE"); + if (insert_pos != std::string::npos) { + second.gcode.insert(insert_pos, travel_gcode); + has_inserted = true; + } + } + + if (!has_inserted) + out.gcode += travel_gcode; + } out.gcode += second.gcode; out.extrusions.insert(out.extrusions.end(), second.extrusions.begin(), second.extrusions.end()); out.end_pos = second.end_pos; @@ -1872,6 +1889,18 @@ static WipeTower::ToolChangeResult merge_tcr(WipeTower::ToolChangeResult& first, else if (!second.nozzle_change_result.gcode.empty()) out.nozzle_change_result = second.nozzle_change_result; + if (first.is_tool_change) { + out.is_tool_change = true; + out.tool_change_start_pos = first.tool_change_start_pos; + } + else if (second.is_tool_change) { + out.is_tool_change = true; + out.tool_change_start_pos = second.tool_change_start_pos; + } + else { + out.is_tool_change = false; + } + // BBS out.purge_volume += second.purge_volume; return out; @@ -1964,6 +1993,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) writer.speed_override_backup(); writer.speed_override(100); + Vec2f initial_position = get_next_pos(cleaning_box, wipe_length); // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool. if (new_tool != (unsigned int) -1) { // This is not the last change. writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Tower_Start) + "\n"); @@ -1992,6 +2022,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) int tpu_line_count = length / (m_wipe_tower_width - 2 * m_perimeter_width) + 1; writer.travel(start_pos); + writer.set_initial_position(start_pos); for (int i = 0; true; ++i) { if (left_to_right) @@ -2004,12 +2035,10 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) writer.travel(writer.x(), writer.y() + dy); left_to_right = !left_to_right; } + writer.travel(initial_position); } - - Vec2f initial_position = get_next_pos(cleaning_box, wipe_length); - //Vec2f initial_position = cleaning_box.ld; - writer.set_initial_position(initial_position + Vec2f(m_perimeter_width, m_perimeter_width), m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation); - writer.travel(initial_position); + else + writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation); toolchange_wipe_new(writer, cleaning_box, wipe_length); @@ -2034,7 +2063,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) if (m_current_tool < m_used_filament_length.size()) m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); - return construct_tcr(writer, false, old_tool, false, purge_volume); + return construct_tcr(writer, false, old_tool, false, true, purge_volume); } WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id, int new_filament_id) @@ -2304,7 +2333,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter, m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); m_nozzle_change_result.gcode.clear(); - return construct_tcr(writer, false, m_current_tool, true, 0.f); + return construct_tcr(writer, false, m_current_tool, true, false, 0.f); } WipeTower::ToolChangeResult WipeTower::finish_block(const WipeTowerBlock &block, int filament_id, bool extrude_fill) @@ -3230,7 +3259,7 @@ WipeTower::ToolChangeResult WipeTower::only_generate_out_wall(bool is_new_mode) if (!m_no_sparse_layers || toolchanges_on_layer) if (m_current_tool < m_used_filament_length.size()) m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); - return construct_tcr(writer, false, old_tool, true, 0.f); + return construct_tcr(writer, false, old_tool, true, false, 0.f); } Polygon WipeTower::generate_support_wall(WipeTowerWriter &writer, const box_coordinates &wt_box, double feedrate, bool first_layer) diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 51697affc..76e488d8c 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -72,6 +72,9 @@ public: // Is this a priming extrusion? (If so, the wipe tower rotation & translation will not be applied later) bool priming; + bool is_tool_change; + Vec2f tool_change_start_pos; + // Pass a polyline so that normal G-code generator can do a wipe for us. // The wipe cannot be done by the wipe tower because it has to pass back // a loaded extruder, so it would have to either do a wipe with no retraction @@ -146,6 +149,7 @@ public: bool priming, size_t old_tool, bool is_finish, + bool is_tool_change, float purge_volume) const; ToolChangeResult construct_block_tcr(WipeTowerWriter& writer,