From dcf26e1302063bbdb7a5d20be0ec8fbc6241dff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Mon, 11 Nov 2024 10:10:29 +0100 Subject: [PATCH] SPE-2501: Add an option to specify which extruder controls the bed temperature. --- src/libslic3r/GCode.cpp | 37 ++++++++++++++++++++++++++++++----- src/libslic3r/GCode.hpp | 1 + src/libslic3r/Preset.cpp | 1 + src/libslic3r/PrintConfig.cpp | 20 +++++++++++++++++++ src/libslic3r/PrintConfig.hpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6c27390ea4..3906a05304 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1215,7 +1215,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail // 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); + const std::string start_gcode = this->_process_start_gcode(print, initial_extruder_id); 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); @@ -1888,15 +1888,34 @@ void GCodeGenerator::print_machine_envelope(GCodeOutputStream &file, const Print } } +std::string GCodeGenerator::_process_start_gcode(const Print& print, unsigned int current_extruder_id) +{ + const int num_extruders = print.config().nozzle_diameter.values.size(); + const int bed_temperature_extruder = print.config().bed_temperature_extruder; + if (0 < bed_temperature_extruder && bed_temperature_extruder <= num_extruders) { + const int first_layer_bed_temperature = print.config().first_layer_bed_temperature.get_at(bed_temperature_extruder - 1); + DynamicConfig config; + config.set_key_value("first_layer_bed_temperature", new ConfigOptionInts(num_extruders, first_layer_bed_temperature)); + return this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, current_extruder_id, &config); + } else { + return this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, current_extruder_id); + } +} + // Write 1st layer bed temperatures into the G-code. // Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. // M140 - Set Extruder Temperature // M190 - Set Extruder Temperature and Wait void GCodeGenerator::_print_first_layer_bed_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait) { - bool autoemit = print.config().autoemit_temperature_commands; - // Initial bed temperature based on the first extruder. - int temp = print.config().first_layer_bed_temperature.get_at(first_printing_extruder_id); + const bool autoemit = print.config().autoemit_temperature_commands; + const int num_extruders = print.config().nozzle_diameter.values.size(); + const int bed_temperature_extruder = print.config().bed_temperature_extruder; + const bool use_first_printing_extruder = bed_temperature_extruder <= 0 || bed_temperature_extruder > num_extruders; + + // Initial bed temperature based on the first printing extruder or based on the extruded in bed_temperature_extruder. + int temp = print.config().first_layer_bed_temperature.get_at(use_first_printing_extruder ? first_printing_extruder_id : bed_temperature_extruder - 1); + // 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, 140, 190, false, temp_by_gcode); @@ -2646,7 +2665,15 @@ LayerResult GCodeGenerator::process_layer( if (temperature > 0 && (temperature != print.config().first_layer_temperature.get_at(extruder.id()))) gcode += m_writer.set_temperature(temperature, false, extruder.id()); } - gcode += m_writer.set_bed_temperature(print.config().bed_temperature.get_at(first_extruder_id)); + + // Bed temperature for layers from the 2nd layer is based on the first printing + // extruder on the layer or on the extruded in bed_temperature_extruder. + const int num_extruders = print.config().nozzle_diameter.values.size(); + const int bed_temperature_extruder = print.config().bed_temperature_extruder; + const bool use_first_extruder = bed_temperature_extruder <= 0 || bed_temperature_extruder > num_extruders; + const int bed_temperature = print.config().bed_temperature.get_at(use_first_extruder ? first_extruder_id : bed_temperature_extruder - 1); + gcode += m_writer.set_bed_temperature(bed_temperature); + // Mark the temperature transition from 1st to 2nd layer to be finished. m_second_layer_things_done = true; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index eabbdc41b9..6b35337e76 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -494,6 +494,7 @@ private: std::string _extrude(const ExtrusionAttributes &attribs, const Geometry::ArcWelder::Path &path, std::string_view description, double speed, const EmitModifiers &emit_modifiers = EmitModifiers()); void print_machine_envelope(GCodeOutputStream &file, const Print &print); + std::string _process_start_gcode(const Print &print, unsigned int current_extruder_id); 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); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 5ff7364e5c..8e226e2239 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -511,6 +511,7 @@ static std::vector s_Preset_print_options { "wall_distribution_count", "min_feature_size", "min_bead_width", "top_one_perimeter_type", "only_one_perimeter_first_layer", "automatic_extrusion_widths", "automatic_infill_combination", "automatic_infill_combination_max_layer_height", + "bed_temperature_extruder" }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1bce82c2fd..c35d6ae652 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -618,6 +618,16 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionInts{ 0 }); + def = this->add("bed_temperature_extruder", coInt); + def->label = L("Bed temperature by extruder"); + def->category = L("Extruders"); + def->tooltip = L("The extruder which determines bed temperatures. " + "Set to 0 to determine temperatures based on the first printing extruder " + "of the first and the second layers."); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionInt(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. " @@ -5162,6 +5172,16 @@ void DynamicPrintConfig::normalize_fdm() if (!this->has("solid_infill_extruder") && this->has("infill_extruder")) this->option("solid_infill_extruder", true)->setInt(this->option("infill_extruder")->getInt()); + if (this->has("bed_temperature_extruder")) { + const size_t num_extruders = this->opt("nozzle_diameter")->size(); + const int extruder = this->opt("bed_temperature_extruder")->value; + + // Replace invalid values with 0. + if (extruder < 0 || extruder > num_extruders) { + this->option("bed_temperature_extruder")->setInt(0); + } + } + if (this->has("spiral_vase") && this->opt("spiral_vase", true)->value) { { // this should be actually done only on the spiral layers instead of all diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 5f21c786c6..f860caf4c8 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -798,6 +798,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionEnum, arc_fitting)) ((ConfigOptionBool, autoemit_temperature_commands)) + ((ConfigOptionInt, bed_temperature_extruder)) ((ConfigOptionString, before_layer_gcode)) ((ConfigOptionString, between_objects_gcode)) ((ConfigOptionBool, binary_gcode)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 623b4853c0..ba75abb3b1 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1635,6 +1635,7 @@ void TabPrint::build() optgroup->append_single_option_line("support_material_extruder"); optgroup->append_single_option_line("support_material_interface_extruder"); optgroup->append_single_option_line("wipe_tower_extruder"); + optgroup->append_single_option_line("bed_temperature_extruder"); optgroup = page->new_optgroup(L("Ooze prevention")); optgroup->append_single_option_line("ooze_prevention");