From 7f81c319363e9ff33cc98cea8e4931ca0a8dc0a2 Mon Sep 17 00:00:00 2001 From: "songwei.li" Date: Thu, 25 Sep 2025 11:25:01 +0800 Subject: [PATCH] FIX: The retract error generated by the travel When the retraction setting is larger than the retraction during the material change, the travel triggered during the material change will make up for the retraction interpolation, but the retracted extruder head will be the wrong one. By moving the travel part in the extruder switch Gcode to after the traditional head change (where m_curr_extruder_id in writer() is updated), the old ID is avoided during travel. jira: STUDIO-14764 Change-Id: I8af8f66af180f01de2fef5760601ee54e73548c4 (cherry picked from commit 008c436803cdf48d3bdcf6fcd85596fc91b3fc70) --- src/libslic3r/GCode.cpp | 42 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index cf1f748cff..ad1094d40c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -815,6 +815,7 @@ static std::vector get_path_of_change_filament(const Print& print) end_filament_gcode_str = toolchange_retract_str + end_filament_gcode_str; + bool need_travel_after_change_filament_gcode = false; // travel need be after the filament changed to get the correct "m_curr_extruder_id" if (! change_filament_gcode.empty()) { DynamicConfig config; int old_filament_id = gcodegen.writer().filament() ? (int)gcodegen.writer().filament()->id() : -1; @@ -934,7 +935,19 @@ static std::vector get_path_of_change_filament(const Print& print) gcodegen.writer().set_position(pos); } } + need_travel_after_change_filament_gcode = true; + } + std::string toolchange_command; + if (tcr.priming || (new_filament_id >= 0 && gcodegen.writer().need_toolchange(new_filament_id))) + toolchange_command = gcodegen.writer().toolchange(new_filament_id); + if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_filament_id)) + toolchange_gcode_str += toolchange_command; + else { + // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. + } + + if (need_travel_after_change_filament_gcode) { // 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, tool_change_start_pos + plate_origin_2d), erMixed, "Move to start pos"); @@ -945,30 +958,28 @@ static std::vector get_path_of_change_filament(const Print& print) Vec3f gcode_last_pos; 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, tool_change_start_pos + plate_origin_2d); + 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, tool_change_start_pos + plate_origin_2d); BoundingBox avoid_bbx, printer_bbx; { - //set printer_bbx + // set printer_bbx Pointfs bed_pointsf = gcodegen.m_config.printable_area.values; Points bed_points; - for (auto p : bed_pointsf) { - bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast() + plate_origin_2d)); - } + for (auto p : bed_pointsf) { bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast() + plate_origin_2d)); } printer_bbx = BoundingBox(bed_points); } { - //set avoid_bbx - avoid_bbx = scaled(m_wipe_tower_bbx); + // set avoid_bbx + avoid_bbx = scaled(m_wipe_tower_bbx); Polygon avoid_points = avoid_bbx.polygon(); - for (auto& p : avoid_points.points) { + for (auto &p : avoid_points.points) { Vec2f pp = transform_wt_pt(unscale(p).cast()); - p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d); + p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d); } avoid_bbx = BoundingBox(avoid_points.points); } std::string travel_to_wipe_tower_gcode; - Polyline travel_polyline = generate_path_to_wipe_tower(gcode_last_pos2d_object, start_wipe_pos, avoid_bbx, printer_bbx); + Polyline travel_polyline = generate_path_to_wipe_tower(gcode_last_pos2d_object, start_wipe_pos, avoid_bbx, printer_bbx); for (const auto &p : travel_polyline.points) { travel_to_wipe_tower_gcode += gcodegen.travel_to(p, erMixed, "Move to start pos"); check_add_eol(travel_to_wipe_tower_gcode); @@ -978,15 +989,6 @@ static std::vector get_path_of_change_filament(const Print& print) } } - std::string toolchange_command; - if (tcr.priming || (new_filament_id >= 0 && gcodegen.writer().need_toolchange(new_filament_id))) - toolchange_command = gcodegen.writer().toolchange(new_filament_id); - if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_filament_id)) - toolchange_gcode_str += toolchange_command; - else { - // 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);