diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 07031d7e4..e3eafaafd 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -140,7 +140,7 @@ namespace Slic3r { int OozePrevention::_get_temp(const GCode& gcodegen) const { - return (gcodegen.layer() != nullptr && gcodegen.layer()->id() == 0) + return (gcodegen.layer() == nullptr || gcodegen.layer()->id() == 0) ? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id()) : gcodegen.config().temperature.get_at(gcodegen.writer().extruder()->id()); } @@ -236,10 +236,11 @@ namespace Slic3r { const bool needs_toolchange = gcodegen.writer().need_toolchange(new_extruder_id); const bool will_go_down = ! is_approx(z, current_z); - - if (! needs_toolchange || (gcodegen.config().single_extruder_multi_material && ! tcr.priming)) { + if (tcr.force_travel || ! needs_toolchange || (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 (if there is a toolchange). + // FIXME: It would be better if the wipe tower set the force_travel flag for all toolchanges, + // then we could simplify the condition and make it more readable. gcode += gcodegen.retract(); gcodegen.m_avoid_crossing_perimeters.use_external_mp_once(); gcode += gcodegen.travel_to( @@ -265,7 +266,6 @@ namespace Slic3r { deretraction_str = gcodegen.unretract(); } - @@ -1196,6 +1196,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato is_extruder_used[extruder_id] = true; m_placeholder_parser.set("is_extruder_used", new ConfigOptionBools(is_extruder_used)); } + + // Enable ooze prevention if configured so. + DoExport::init_ooze_prevention(print, m_ooze_prevention); + std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id); // Set bed temperature if the start G-code does not contain any bed temp control G-codes. this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true); @@ -1214,9 +1218,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Set other general things. file.write(this->preamble()); - // Enable ooze prevention if configured so. - DoExport::init_ooze_prevention(print, m_ooze_prevention); - print.throw_if_canceled(); // Collect custom seam data from all objects. @@ -1747,7 +1748,7 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr m_writer.set_temperature(temp, wait, first_printing_extruder_id); } else { // Custom G-code does not set the extruder temperature. Do it now. - if (print.config().single_extruder_multi_material.value || m_ooze_prevention.enable) { + if (print.config().single_extruder_multi_material.value) { // Set temperature of the first printing extruder only. int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id); if (temp > 0) @@ -1756,8 +1757,14 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr // Set temperatures of all the printing extruders. for (unsigned int tool_id : print.extruders()) { int temp = print.config().first_layer_temperature.get_at(tool_id); - if (print.config().ooze_prevention.value) - temp += print.config().standby_temperature_delta.value; + + if (print.config().ooze_prevention.value && tool_id != first_printing_extruder_id) { + if (print.config().idle_temperature.is_nil(tool_id)) + temp += print.config().standby_temperature_delta.value; + else + temp = print.config().idle_temperature.get_at(tool_id); + } + if (temp > 0) file.write(m_writer.set_temperature(temp, wait, tool_id)); } diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 04fab3fcd..639739967 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -1387,8 +1387,10 @@ void WipeTower::generate(std::vector> & layer_result.emplace_back(std::move(finish_layer_tcr)); } else { - if (idx == -1) + if (idx == -1) { layer_result[0] = merge_tcr(finish_layer_tcr, layer_result[0]); + layer_result[0].force_travel = true; + } else layer_result[idx] = merge_tcr(layer_result[idx], finish_layer_tcr); } diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index ab3af507d..7f4a6bf9a 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -82,6 +82,8 @@ public: } return e_length; } + + bool force_travel = false; }; struct box_coordinates diff --git a/tests/fff_print/test_multi.cpp b/tests/fff_print/test_multi.cpp index 90f311c39..3e69c6822 100644 --- a/tests/fff_print/test_multi.cpp +++ b/tests/fff_print/test_multi.cpp @@ -98,8 +98,11 @@ SCENARIO("Ooze prevention", "[Multi]") int s; if (! line.has_value('S', s)) throw std::runtime_error("M104 or M109 without S"); - if (tool_temp[t] == 0 && s != print_config.first_layer_temperature.get_at(t) + print_config.standby_temperature_delta) - throw std::runtime_error("initial temperature is not equal to first layer temperature + standby delta"); + + // Following is obsolete. The first printing extruder is newly set to its first layer temperature immediately, not to the standby. + //if (tool_temp[t] == 0 && s != print_config.first_layer_temperature.get_at(t) + print_config.standby_temperature_delta) + // throw std::runtime_error("initial temperature is not equal to first layer temperature + standby delta"); + tool_temp[t] = s; } else if (line.cmd_is("G1") && line.extruding(self) && line.dist_XY(self) > 0) { extrusion_points.emplace_back(line.new_XY_scaled(self) + scaled(print_config.extruder_offset.get_at(tool)));