diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3ebf75c2e..2210e40b2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -313,8 +313,11 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T double current_z = gcodegen.writer().get_position().z(); if (z == -1.) // in case no specific z was provided, print at current_z pos z = current_z; - if (! is_approx(z, current_z)) + if (! is_approx(z, current_z)) { + gcode += gcodegen.writer().retract(); gcode += gcodegen.writer().travel_to_z(z, "Travel down to the last wipe tower layer."); + gcode += gcodegen.writer().unretract(); + } // Process the end filament gcode. @@ -526,13 +529,18 @@ std::string WipeTowerIntegration::tool_change(GCode &gcodegen, int extruder_id, throw std::runtime_error("Wipe tower generation failed, possibly due to empty first layer."); - double wipe_tower_z = m_last_wipe_tower_print_z; - bool is_sparse_layer = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool); + // Calculate where the wipe tower layer will be printed. -1 means that print z will not change, + // resulting in a wipe tower with sparse layers. + double wipe_tower_z = -1; + bool ignore_sparse = false; + if (gcodegen.config().wipe_tower_no_sparse_layers.value) { + wipe_tower_z = m_last_wipe_tower_print_z; + ignore_sparse = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool); + if (m_tool_change_idx == 0 && ! ignore_sparse) + wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height; + } - if (m_tool_change_idx == 0 && ! is_sparse_layer) - wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height; - - if (! is_sparse_layer) { + if (! ignore_sparse) { gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z); m_last_wipe_tower_print_z = wipe_tower_z; } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 4d8482743..8a5282b4b 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -143,6 +143,7 @@ bool Print::invalidate_state_by_config_options(const std::vectormode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); + def = this->add("wipe_tower_no_sparse_layers", coBool); + def->label = L("No sparse layers"); + def->tooltip = L("If enabled, the wipe tower will not be printed on layers with no toolchanges. " + "On layers with a toolchange, extruder will travel downward to print the wipe tower. " + "User is responsible for ensuring there is no collision with the print."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("support_material", coBool); def->label = L("Generate support material"); def->category = L("Support material"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 6a19edf84..20ab60e9a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -648,6 +648,7 @@ public: ConfigOptionStrings start_filament_gcode; ConfigOptionBool single_extruder_multi_material; ConfigOptionBool single_extruder_multi_material_priming; + ConfigOptionBool wipe_tower_no_sparse_layers; ConfigOptionString toolchange_gcode; ConfigOptionFloat travel_speed; ConfigOptionBool use_firmware_retraction; @@ -718,6 +719,7 @@ protected: OPT_PTR(retract_speed); OPT_PTR(single_extruder_multi_material); OPT_PTR(single_extruder_multi_material_priming); + OPT_PTR(wipe_tower_no_sparse_layers); OPT_PTR(start_gcode); OPT_PTR(start_filament_gcode); OPT_PTR(toolchange_gcode); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index d2503d349..853a803b7 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -385,7 +385,7 @@ const std::vector& Preset::print_options() "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming", - "compatible_printers", "compatible_printers_condition", "inherits" + "wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits" }; return s_opts; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index c87626a48..5ecfb9a77 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1170,6 +1170,7 @@ void TabPrint::build() optgroup->append_single_option_line("wipe_tower_width"); optgroup->append_single_option_line("wipe_tower_rotation_angle"); optgroup->append_single_option_line("wipe_tower_bridging"); + optgroup->append_single_option_line("wipe_tower_no_sparse_layers"); optgroup->append_single_option_line("single_extruder_multi_material_priming"); optgroup = page->new_optgroup(_(L("Advanced")));