diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index e50fd3b82b..994fb3ac17 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1901,80 +1901,92 @@ std::vector GCodeGenerator::sort_print_object_i namespace ProcessLayer { +static std::string emit_custom_color_change_gcode_per_print_z( + GCodeGenerator &gcodegen, + const CustomGCode::Item &custom_gcode, + unsigned int current_extruder_id, + unsigned int first_extruder_id, // ID of the first extruder printing this layer. + const PrintConfig &config +) { + const bool single_extruder_multi_material = config.single_extruder_multi_material; + const bool single_extruder_printer = config.nozzle_diameter.size() == 1; + const bool color_change = custom_gcode.type == CustomGCode::ColorChange; + + std::string gcode; + + int color_change_extruder = -1; + if (color_change && custom_gcode.extruder > 0) + color_change_extruder = custom_gcode.extruder - 1; + + assert(color_change_extruder >= 0); + // Color Change or Tool Change as Color Change. + // add tag for processor + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Color_Change) + ",T" + std::to_string(color_change_extruder) + "," + custom_gcode.color + "\n"; + + DynamicConfig cfg; + cfg.set_key_value("color_change_extruder", new ConfigOptionInt(color_change_extruder)); + if (single_extruder_multi_material && !single_extruder_printer && color_change_extruder >= 0 && first_extruder_id != unsigned(color_change_extruder)) { + //! FIXME_in_fw show message during print pause + // FIXME: Why is pause_print_gcode here? Why is it supplied "color_change_extruder"? + gcode += gcodegen.placeholder_parser_process("pause_print_gcode", config.pause_print_gcode, current_extruder_id, &cfg); + gcode += "\n"; + gcode += "M117 Change filament for Extruder " + std::to_string(color_change_extruder) + "\n"; + } else { + gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id, &cfg); + gcode += "\n"; + //FIXME Tell G-code writer that M600 filled the extruder, thus the G-code writer shall reset the extruder to unretracted state after + // return from M600. Thus the G-code generated by the following line is ignored. + // see GH issue #6362 + gcodegen.writer().unretract(); + } + + return gcode; +} + static std::string emit_custom_gcode_per_print_z( GCodeGenerator &gcodegen, - const CustomGCode::Item *custom_gcode, + const CustomGCode::Item &custom_gcode, unsigned int current_extruder_id, // ID of the first extruder printing this layer. unsigned int first_extruder_id, const PrintConfig &config) { std::string gcode; - bool single_extruder_printer = config.nozzle_diameter.size() == 1; - if (custom_gcode != nullptr) { - // Extruder switches are processed by LayerTools, they should be filtered out. - assert(custom_gcode->type != CustomGCode::ToolChange); + // Extruder switches are processed by LayerTools, they should be filtered out. + assert(custom_gcode.type != CustomGCode::ToolChange); - CustomGCode::Type gcode_type = custom_gcode->type; - const bool color_change = gcode_type == CustomGCode::ColorChange; - const bool tool_change = gcode_type == CustomGCode::ToolChange; - // Tool Change is applied as Color Change for a single extruder printer only. - assert(!tool_change || single_extruder_printer); + CustomGCode::Type gcode_type = custom_gcode.type; + const bool color_change = gcode_type == CustomGCode::ColorChange; + const bool tool_change = gcode_type == CustomGCode::ToolChange; + // Tool Change is applied as Color Change for a single extruder printer only. + assert(!tool_change || config.nozzle_diameter.size() == 1); - // we should add or not colorprint_change in respect to nozzle_diameter count instead of really used extruders count - if (color_change || tool_change) { - const bool single_extruder_multi_material = config.single_extruder_multi_material; - const bool single_extruder_printer = config.nozzle_diameter.size() == 1; + // we should add or not colorprint_change in respect to nozzle_diameter count instead of really used extruders count + if (color_change || tool_change) { + gcode += emit_custom_color_change_gcode_per_print_z(gcodegen, custom_gcode, current_extruder_id, first_extruder_id, config); + } else { + if (gcode_type == CustomGCode::PausePrint) { // Pause print + const std::string pause_print_msg = custom_gcode.extra; - int color_change_extruder = -1; - if (color_change && custom_gcode->extruder > 0) - color_change_extruder = custom_gcode->extruder - 1; - - assert(color_change_extruder >= 0); - // Color Change or Tool Change as Color Change. // add tag for processor - gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Color_Change) + ",T" + std::to_string(color_change_extruder) + "," + custom_gcode->color + "\n"; + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Pause_Print) + "\n"; + //! FIXME_in_fw show message during print pause + if (!pause_print_msg.empty()) + gcode += "M117 " + pause_print_msg + "\n"; DynamicConfig cfg; - cfg.set_key_value("color_change_extruder", new ConfigOptionInt(color_change_extruder)); - if (single_extruder_multi_material && !single_extruder_printer && color_change_extruder >= 0 && first_extruder_id != unsigned(color_change_extruder)) { - //! FIXME_in_fw show message during print pause - // FIXME: Why is pause_print_gcode here? Why is it supplied "color_change_extruder"? - gcode += gcodegen.placeholder_parser_process("pause_print_gcode", config.pause_print_gcode, current_extruder_id, &cfg); - gcode += "\n"; - gcode += "M117 Change filament for Extruder " + std::to_string(color_change_extruder) + "\n"; - } else { - gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id, &cfg); - gcode += "\n"; - //FIXME Tell G-code writer that M600 filled the extruder, thus the G-code writer shall reset the extruder to unretracted state after - // return from M600. Thus the G-code generated by the following line is ignored. - // see GH issue #6362 - gcodegen.writer().unretract(); - } + cfg.set_key_value("color_change_extruder", new ConfigOptionInt(int(current_extruder_id))); + gcode += gcodegen.placeholder_parser_process("pause_print_gcode", config.pause_print_gcode, current_extruder_id, &cfg); } else { - if (gcode_type == CustomGCode::PausePrint) { // Pause print - const std::string pause_print_msg = custom_gcode->extra; - - // add tag for processor - gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Pause_Print) + "\n"; - //! FIXME_in_fw show message during print pause - if (!pause_print_msg.empty()) - gcode += "M117 " + pause_print_msg + "\n"; - - DynamicConfig cfg; - cfg.set_key_value("color_change_extruder", new ConfigOptionInt(int(current_extruder_id))); - gcode += gcodegen.placeholder_parser_process("pause_print_gcode", config.pause_print_gcode, current_extruder_id, &cfg); - } else { - // add tag for processor - gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Custom_Code) + "\n"; - if (gcode_type == CustomGCode::Template) // Template Custom Gcode - gcode += gcodegen.placeholder_parser_process("template_custom_gcode", config.template_custom_gcode, current_extruder_id); - else // custom Gcode - gcode += custom_gcode->extra; - } - gcode += "\n"; + // add tag for processor + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Custom_Code) + "\n"; + if (gcode_type == CustomGCode::Template) // Template Custom Gcode + gcode += gcodegen.placeholder_parser_process("template_custom_gcode", config.template_custom_gcode, current_extruder_id); + else // custom Gcode + gcode += custom_gcode.extra; } + gcode += "\n"; } return gcode; @@ -2243,10 +2255,10 @@ LayerResult GCodeGenerator::process_layer( // Map from extruder ID to index of skirt loops to be extruded with that extruder. std::map> skirt_loops_per_extruder; - if (single_object_instance_idx == size_t(-1)) { + if (single_object_instance_idx == size_t(-1) && layer_tools.custom_gcode != nullptr) { // Normal (non-sequential) print. - std::string custom_gcode = ProcessLayer::emit_custom_gcode_per_print_z(*this, layer_tools.custom_gcode, m_writer.extruder()->id(), first_extruder_id, print.config()); - if (layer_tools.custom_gcode != nullptr && layer_tools.custom_gcode->type == CustomGCode::ColorChange) { + std::string custom_gcode = ProcessLayer::emit_custom_gcode_per_print_z(*this, *layer_tools.custom_gcode, m_writer.extruder()->id(), first_extruder_id, print.config()); + if (layer_tools.custom_gcode->type == CustomGCode::ColorChange) { // We have a color change to do on this layer, but we want to do it immediately before the first extrusion instead of now, in order to fix GH #2672 m_pending_pre_extrusion_gcode = custom_gcode; } else {