diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6a7f825815..365689a777 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1211,9 +1211,9 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail 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_chamber_temperature(file, print, start_gcode, config().chamber_temperature.get_at(initial_extruder_id), false, false); this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true); - // Set extruder(s) temperature before and after start G-code. this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false); // adds tag for processor @@ -1223,6 +1223,8 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail file.writeln(start_gcode); this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true); + this->_print_first_layer_chamber_temperature(file, print, start_gcode, config().chamber_minimal_temperature.get_at(initial_extruder_id), true, false); + this->_print_first_layer_chamber_temperature(file, print, start_gcode, config().chamber_temperature.get_at(initial_extruder_id), false, false); print.throw_if_canceled(); // Set other general things. @@ -1889,6 +1891,31 @@ void GCodeGenerator::_print_first_layer_bed_temperature(GCodeOutputStream &file, file.write(set_temp_gcode); } + + +// Write chamber temperatures into the G-code. +// Only do that if the start G-code does not already contain any M-code controlling chamber temperature. +// M141 - Set chamber Temperature +// M191 - Set chamber Temperature and Wait +void GCodeGenerator::_print_first_layer_chamber_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, int temp, bool wait, bool accurate) +{ + if (temp == 0) + return; + bool autoemit = print.config().autoemit_temperature_commands; + // Is the bed temperature set by the provided custom G-code? + int temp_by_gcode = -1; + bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 141, 191, false, temp_by_gcode); + if (autoemit && temp_set_by_gcode && temp_by_gcode >= 0 && temp_by_gcode < 1000) + temp = temp_by_gcode; + // Always call m_writer.set_bed_temperature() so it will set the internal "current" state of the bed temp as if + // the custom start G-code emited these. + std::string set_temp_gcode = m_writer.set_chamber_temperature(temp, wait, accurate); + if (autoemit && ! temp_set_by_gcode) + file.write(set_temp_gcode); +} + + + // Write 1st layer extruder temperatures into the G-code. // Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. // M104 - Set Extruder Temperature diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 3aa59fb286..e25a2421e6 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -468,6 +468,7 @@ private: std::string _extrude( const ExtrusionAttributes &attribs, const Geometry::ArcWelder::Path &path, const std::string_view description, double speed = -1); void print_machine_envelope(GCodeOutputStream &file, const Print &print); + void _print_first_layer_chamber_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, int temp, bool wait, bool accurate); void _print_first_layer_bed_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); // On the first printing layer. This flag triggers first layer speeds. diff --git a/src/libslic3r/GCode/GCodeWriter.cpp b/src/libslic3r/GCode/GCodeWriter.cpp index 2d3b3f798e..270b576454 100644 --- a/src/libslic3r/GCode/GCodeWriter.cpp +++ b/src/libslic3r/GCode/GCodeWriter.cpp @@ -181,6 +181,27 @@ std::string GCodeWriter::set_bed_temperature(unsigned int temperature, bool wait return gcode.str(); } + + +std::string GCodeWriter::set_chamber_temperature(unsigned int temperature, bool wait, bool accurate) const +{ + std::string_view code, comment; + if (wait) { + code = "M191"sv; + comment = "set chamber temperature and wait for it to be reached"sv; + } else { + code = "M141"sv; + comment = "set chamber temperature"sv; + } + + std::ostringstream gcode; + gcode << code << (accurate ? " R" : " S") << temperature << " ; " << comment << "\n"; + + return gcode.str(); +} + + + std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration) { // Clamp the acceleration to the allowed maximum. diff --git a/src/libslic3r/GCode/GCodeWriter.hpp b/src/libslic3r/GCode/GCodeWriter.hpp index e0b18c4f8e..42b0da4537 100644 --- a/src/libslic3r/GCode/GCodeWriter.hpp +++ b/src/libslic3r/GCode/GCodeWriter.hpp @@ -52,6 +52,7 @@ public: std::string postamble() const; std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const; std::string set_bed_temperature(unsigned int temperature, bool wait = false); + std::string set_chamber_temperature(unsigned int temperature, bool wait, bool accurate) const; std::string set_print_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Print, acceleration); } std::string set_travel_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Travel, acceleration); } std::string reset_e(bool force = false); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index a7361c0130..046334058e 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -483,7 +483,7 @@ static std::vector s_Preset_filament_options { "filament_multitool_ramming", "filament_multitool_ramming_volume", "filament_multitool_ramming_flow", "temperature", "idle_temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", - "start_filament_gcode", "end_filament_gcode", "enable_dynamic_fan_speeds", + "start_filament_gcode", "end_filament_gcode", "enable_dynamic_fan_speeds", "chamber_temperature", "chamber_minimal_temperature", "overhang_fan_speed_0", "overhang_fan_speed_1", "overhang_fan_speed_2", "overhang_fan_speed_3", // Retract overrides "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 146994c201..e7d223cbd0 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -94,6 +94,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "overhang_fan_speed_1", "overhang_fan_speed_2", "overhang_fan_speed_3", + "chamber_temperature", + "chamber_minimal_temperature", "colorprint_heights", "cooling", "default_acceleration", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3e832eef10..632a48fdcc 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -496,6 +496,29 @@ void PrintConfigDef::init_fff_params() def->max = 300; def->set_default_value(new ConfigOptionInts { 0 }); + def = this->add("chamber_temperature", coInts); + def->label = L("Nominal"); + def->full_label = L("Chamber temperature"); + def->tooltip = L("Required chamber temperature for the print.\nWhen set to zero, " + "the nominal chamber temperature is not set in the G-code."); + def->sidetext = L("°C"); + def->min = 0; + def->max = 1000; + def->mode = comExpert; + def->set_default_value(new ConfigOptionInts{ 0 }); + + def = this->add("chamber_minimal_temperature", coInts); + def->label = L("Minimal"); + def->full_label = L("Chamber minimal temperature"); + def->tooltip = L("Minimal chamber temperature that the printer waits for before the print starts. This allows " + "to start the print before the nominal chamber temperature is reached.\nWhen set to zero, " + "the minimal chamber temperature is not set in the G-code."); + def->sidetext = L("°C"); + def->min = 0; + def->max = 1000; + def->mode = comExpert; + def->set_default_value(new ConfigOptionInts{ 0 }); + def = this->add("before_layer_gcode", coString); def->label = L("Before layer change G-code"); def->tooltip = L("This custom code is inserted at every layer change, right before the Z move. " @@ -2696,16 +2719,17 @@ void PrintConfigDef::init_fff_params() def = this->add("autoemit_temperature_commands", coBool); def->label = L("Emit temperature commands automatically"); - def->tooltip = L("When enabled, PrusaSlicer will check whether your Custom Start G-Code contains M104 or M190. " + def->tooltip = L("When enabled, PrusaSlicer will check whether your custom Start G-Code contains G-codes to set " + "extruder, bed or chamber temperature (M104, M109, M140, M190, M141 and M191). " "If so, the temperatures will not be emitted automatically so you're free to customize " "the order of heating commands and other custom actions. Note that you can use " "placeholder variables for all PrusaSlicer settings, so you can put " "a \"M109 S[first_layer_temperature]\" command wherever you want.\n" - "If your Custom Start G-Code does NOT contain M104 or M190, " - "PrusaSlicer will execute the Start G-Code after bed reached its target temperature " - "and extruder just started heating.\n\n" - "When disabled, PrusaSlicer will NOT emit commands to heat up extruder and bed, " - "leaving both to Custom Start G-Code."); + "If your custom Start G-Code does NOT contain these G-codes, " + "PrusaSlicer will execute the Start G-Code after heated chamber was set to its temperature, " + "bed reached its target temperature and extruder just started heating.\n\n" + "When disabled, PrusaSlicer will NOT emit commands to heat up extruder, bed or chamber, " + "leaving all to Custom Start G-Code."); def->mode = comExpert; def->set_default_value(new ConfigOptionBool(true)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 067f8fefda..72ba652e5f 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -820,6 +820,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionInts, overhang_fan_speed_1)) ((ConfigOptionInts, overhang_fan_speed_2)) ((ConfigOptionInts, overhang_fan_speed_3)) + ((ConfigOptionInts, chamber_temperature)) + ((ConfigOptionInts, chamber_minimal_temperature)) ((ConfigOptionBool, complete_objects)) ((ConfigOptionFloats, colorprint_heights)) ((ConfigOptionBools, cooling)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 37a6120d15..fdf0d3a339 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2178,6 +2178,11 @@ void TabFilament::build() line.append_option(optgroup->get_option("bed_temperature")); optgroup->append_line(line); + line = { L("Chamber"), "" }; + line.append_option(optgroup->get_option("chamber_temperature")); + line.append_option(optgroup->get_option("chamber_minimal_temperature")); + optgroup->append_line(line); + page = add_options_page(L("Cooling"), "cooling"); std::string category_path = "cooling_127569#"; optgroup = page->new_optgroup(L("Enable"));