From 5c547ea4a1e505b95e927af378cda391485863ef Mon Sep 17 00:00:00 2001 From: Michael Rook <54159303+michaelr0@users.noreply.github.com> Date: Thu, 11 Dec 2025 02:19:57 +1100 Subject: [PATCH] Add ability to disable Power Loss Recovery on BBL machines (#11582) * Add ability to disable Power Loss Recovery * Fix typo in PrintConfig.hpp for power loss recovery * Attempt to resolve Unknown option exception: disable_power_less_recovery Add disable_power_loss_recovery property to any json which had scan_first_layer * Revert "Attempt to resolve Unknown option exception: disable_power_less_recovery" This reverts commit ddaf34b317f8797540235b8f7d179b1c9b6d10f8. * Fix typo * Change attribution from BBS to Orca in PrintConfig.cpp * Mini refactor power loss recovery handling in GCode export - Moved power loss recovery G-code generation to a new method in GCodeWriter. - Support Marlin 2 * Update comments and power loss recovery handling * Implement power loss recovery G-code commands Added functions to start and end power loss recovery with appropriate G-code commands and comments. * Add power loss recovery methods to GCodeWriter * refactor and fix build errors --------- Co-authored-by: Michael Rook Co-authored-by: Ioannis Giannakas <59056762+igiannakas@users.noreply.github.com> Co-authored-by: SoftFever --- resources/profiles/BBL.json | 2 +- .../BBL/machine/fdm_machine_common.json | 1 + src/libslic3r/GCode.cpp | 42 +++++++++---------- src/libslic3r/GCodeWriter.cpp | 18 ++++++++ src/libslic3r/GCodeWriter.hpp | 1 + src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 6 +++ src/libslic3r/PrintConfig.hpp | 1 + src/slic3r/GUI/Tab.cpp | 6 +++ 9 files changed, 54 insertions(+), 25 deletions(-) diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 28ce9d1e90..9425300cb4 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "02.00.00.55", + "version": "02.00.00.56", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/machine/fdm_machine_common.json b/resources/profiles/BBL/machine/fdm_machine_common.json index e33d6b9f9b..0073ac6a8a 100644 --- a/resources/profiles/BBL/machine/fdm_machine_common.json +++ b/resources/profiles/BBL/machine/fdm_machine_common.json @@ -136,6 +136,7 @@ "60" ], "scan_first_layer": "0", + "enable_power_loss_recovery": "1", "silent_mode": "0", "single_extruder_multi_material": "1", "support_air_filtration": "0", diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index a5af72f4c9..3e3fd6f9cf 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3084,11 +3084,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_sorted_layer_filaments.emplace_back(lt.extruders); } - //BBS: close powerlost recovery + // Orca: finish tracking power lost recovery { - if (is_bbl_printers && m_second_layer_things_done) { - file.write("; close powerlost recovery\n"); - file.write("M1003 S0\n"); + if (m_second_layer_things_done && print.config().enable_power_loss_recovery.value == true) { + file.write(m_writer.enable_power_loss_recovery(false)); } } ++ finished_objects; @@ -3166,12 +3165,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_sorted_layer_filaments.emplace_back(lt.extruders); } - //BBS: close powerlost recovery - { - if (is_bbl_printers && m_second_layer_things_done) { - file.write("; close powerlost recovery\n"); - file.write("M1003 S0\n"); - } + // Orca: finish tracking power lost recovery + if (m_second_layer_things_done && print.config().enable_power_loss_recovery.value == true) { + file.write(m_writer.enable_power_loss_recovery(false)); } if (m_wipe_tower) // Purge the extruder, pull out the active filament. @@ -4386,21 +4382,21 @@ LayerResult GCode::process_layer( } if (!first_layer && !m_second_layer_things_done) { - if (print.is_BBL_printer()) { - // BBS: open powerlost recovery - { - gcode += "; open powerlost recovery\n"; - gcode += "M1003 S1\n"; + // Orca: start tracking power lost recovery + if (print.config().enable_power_loss_recovery.value == true) { + gcode += m_writer.enable_power_loss_recovery(true); } - // BBS: open first layer inspection at second layer - if (print.config().scan_first_layer.value) { - // BBS: retract first to avoid droping when scan model - gcode += this->retract(); - gcode += "M976 S1 P1 ; scan model before printing 2nd layer\n"; - gcode += "M400 P100\n"; - gcode += this->unretract(); + + if (print.is_BBL_printer()) { + // BBS: open first layer inspection at second layer + if (print.config().scan_first_layer.value) { + // BBS: retract first to avoid droping when scan model + gcode += this->retract(); + gcode += "M976 S1 P1 ; scan model before printing 2nd layer\n"; + gcode += "M400 P100\n"; + gcode += this->unretract(); + } } - } // Reset acceleration at sencond layer // Orca: only set once, don't need to call set_accel_and_jerk if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) { diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 2e4627590f..6340a7af5c 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -1,5 +1,6 @@ #include "GCodeWriter.hpp" #include "CustomGCode.hpp" +#include "PrintConfig.hpp" #include #include #include @@ -442,6 +443,23 @@ std::string GCodeWriter::reset_e(bool force) } } +std::string GCodeWriter::enable_power_loss_recovery(bool enable) +{ + std::ostringstream gcode; + + if (m_is_bbl_printers) { + gcode << "; start tracking Power Loss Recovery https://wiki.bambulab.com/en/knowledge-sharing/power-loss-recovery\n"; + gcode << "M1003 S" << (enable ? "1" : "0") << "\n"; + } + else if (FLAVOR_IS(gcfMarlinFirmware)) { + gcode << "; start tracking Power-loss Recovery https://marlinfw.org/docs/gcode/M413.html\n"; + gcode << "M413 S" << (enable ? "1" : "0") << "\n"; + } + + return gcode.str(); +} + + std::string GCodeWriter::update_progress(unsigned int num, unsigned int tot, bool allow_100) const { if (FLAVOR_IS_NOT(gcfMakerWare) && FLAVOR_IS_NOT(gcfSailfish)) diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 2c68c921d8..729c89263e 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -61,6 +61,7 @@ public: std::string set_input_shaping(char axis, float damp, float freq, std::string type) const; std::string reset_e(bool force = false); std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const; + std::string enable_power_loss_recovery(bool enable); // return false if this extruder was already selected bool need_toolchange(unsigned int filament_id) const; std::string set_extruder(unsigned int filament_id); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 1dcdd83000..f5b0d1c713 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1007,7 +1007,7 @@ static std::vector s_Preset_printer_options { "nozzle_height", "master_extruder_id", "default_print_profile", "inherits", "silent_mode", - "scan_first_layer", "wrapping_detection_layers", "wrapping_exclude_area", "machine_load_filament_time", "machine_unload_filament_time", "machine_tool_change_time", "time_cost", "machine_pause_gcode", "template_custom_gcode", + "scan_first_layer", "enable_power_loss_recovery", "wrapping_detection_layers", "wrapping_exclude_area", "machine_load_filament_time", "machine_unload_filament_time", "machine_tool_change_time", "time_cost", "machine_pause_gcode", "template_custom_gcode", "nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types", "travel_slope", "retract_lift_enforce","support_chamber_temp_control","support_air_filtration","printer_structure", "best_object_pos", "head_wrap_detect_zone", "host_type", "print_host", "printhost_apikey", "bbl_use_printhost", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index bcb2f833c7..3e48103915 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3365,6 +3365,12 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + // Orca + def = this->add("enable_power_loss_recovery", coBool); + def->label = L("Turn on Power Loss Recovery"); + def->tooltip = L("Enable this to insert power loss recovery commands in generated G-code.(Only for Bambu Lab printers and Marlin firmware based printers)"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); //BBS // def = this->add("spaghetti_detector", coBool); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 338fd5c1a7..3e34a8362b 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1271,6 +1271,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionIntsNullable, filament_flush_temp)) // BBS ((ConfigOptionBool, scan_first_layer)) + ((ConfigOptionBool, enable_power_loss_recovery)) ((ConfigOptionBool, enable_wrapping_detection)) ((ConfigOptionInt, wrapping_detection_layers)) ((ConfigOptionPoints, wrapping_exclude_area)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 253a76a286..c26403c9fd 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4360,11 +4360,13 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("preferred_orientation", "printer_basic_information_printable_space#preferred-orientation"); optgroup = page->new_optgroup(L("Advanced"), L"param_advanced"); + optgroup->append_single_option_line("printer_structure", "printer_basic_information_advanced#printer-structure"); optgroup->append_single_option_line("gcode_flavor", "printer_basic_information_advanced#g-code-flavor"); optgroup->append_single_option_line("pellet_modded_printer", "printer_basic_information_advanced#pellet-modded-printer"); optgroup->append_single_option_line("bbl_use_printhost", "printer_basic_information_advanced#use-3rd-party-print-host"); optgroup->append_single_option_line("scan_first_layer" , "printer_basic_information_advanced#scan-first-layer"); + optgroup->append_single_option_line("enable_power_loss_recovery"); //option = optgroup->get_option("wrapping_exclude_area"); //option.opt.full_width = true; //optgroup->append_single_option_line(option); @@ -5199,7 +5201,11 @@ void TabPrinter::toggle_options() // SoftFever: hide non-BBL settings for (auto el : {"use_firmware_retraction", "use_relative_e_distances", "support_multi_bed_types", "pellet_modded_printer", "bed_mesh_max", "bed_mesh_min", "bed_mesh_probe_distance", "adaptive_bed_mesh_margin", "thumbnails"}) toggle_line(el, !is_BBL_printer); + + auto gcf = m_config->option>("gcode_flavor")->value; + toggle_line("enable_power_loss_recovery", is_BBL_printer || gcf == gcfMarlinFirmware); } + if (m_active_page->title() == L("Machine G-code")) { PresetBundle *preset_bundle = wxGetApp().preset_bundle;