From 7ac7a0af15bf9f25d694cb4656fcf4a410f73380 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 25 Oct 2021 16:21:04 +0200 Subject: [PATCH] Allow to choose between M73 and M117 for remaining_times supermerill/SuperSlicer#1693 --- resources/ui_layout/printer_fff.ui | 5 ++- src/libslic3r/GCode/GCodeProcessor.cpp | 51 +++++++++++++++++-------- src/libslic3r/GCode/GCodeProcessor.hpp | 2 +- src/libslic3r/Preset.cpp | 1 + src/libslic3r/PrintConfig.cpp | 22 +++++++++-- src/libslic3r/PrintConfig.hpp | 17 ++++++++- src/slic3r/GUI/Field.cpp | 4 ++ src/slic3r/GUI/GUI.cpp | 2 + src/slic3r/GUI/OptionsGroup.cpp | 2 + src/slic3r/GUI/Tab.cpp | 5 +++ src/slic3r/GUI/UnsavedChangesDialog.cpp | 2 + 11 files changed, 90 insertions(+), 23 deletions(-) diff --git a/resources/ui_layout/printer_fff.ui b/resources/ui_layout/printer_fff.ui index abe0e33b6..5ccc4da39 100644 --- a/resources/ui_layout/printer_fff.ui +++ b/resources/ui_layout/printer_fff.ui @@ -14,7 +14,10 @@ group:Print Host upload group:silent_mode_event:Firmware setting:gcode_flavor setting:silent_mode - setting:remaining_times + line:Print remaining times + setting:label$:remaining_times + setting:remaining_times_type + end_line line:Gcode precision setting:gcode_precision_xyz setting:gcode_precision_e diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9dcd96975..c36fba9e0 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -347,14 +347,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) return int(::roundf(time_in_seconds / 60.0f)); }; - auto format_line_M73 = [](const std::string& mask, int percent, int time) { - char line_M73[64]; - sprintf(line_M73, mask.c_str(), - std::to_string(percent).c_str(), - std::to_string(time).c_str()); - return std::string(line_M73); - }; - GCodeReader parser; std::string gcode_line; size_t g1_lines_counter = 0; @@ -378,9 +370,18 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; if (machine.enabled) { - ret += format_line_M73(machine.line_m73_mask.c_str(), - (line == First_Line_M73_Placeholder_Tag) ? 0 : 100, - (line == First_Line_M73_Placeholder_Tag) ? time_in_minutes(machine.time) : 0); + if (machine.remaining_times_type == rtM73) { + ret += (boost::format("M73 P%1% R%2%\n") + % std::to_string((line == First_Line_M73_Placeholder_Tag) ? 0 : 100) + % std::to_string((line == First_Line_M73_Placeholder_Tag) ? time_in_minutes(machine.time) : 0)).str(); + } else if (machine.remaining_times_type == rtM117) { + if((line == First_Line_M73_Placeholder_Tag)) + ret += (boost::format("M117 Time Left %1%h%2%m%3%s\n") + % std::to_string(int32_t(machine.time) / 3600) % std::to_string(int32_t(machine.time / 60) % 60) % std::to_string(int32_t(machine.time) % 60) + ).str(); + else + ret += "M117 Time Left 0s\n"; + } } } } @@ -434,8 +435,15 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) std::pair to_export = { int(100.0f * elapsed_time / machine.time), time_in_minutes(machine.time - elapsed_time) }; if (last_exported[i] != to_export) { - export_line += format_line_M73(machine.line_m73_mask.c_str(), - to_export.first, to_export.second); + if (machine.remaining_times_type == rtM73) { + export_line += (boost::format("M73 P%1% R%2%\n") + % std::to_string(to_export.first) + % std::to_string(to_export.second)).str(); + } else if (machine.remaining_times_type == rtM117) { + export_line += (boost::format("M117 Time Left %1%h%2%m%3%s\n") + % std::to_string(int32_t(machine.time - elapsed_time) / 3600) % std::to_string((int32_t(machine.time - elapsed_time) / 60) % 60) % std::to_string(int32_t(machine.time - elapsed_time) % 60) + ).str(); + } last_exported[i] = to_export; } } @@ -519,8 +527,6 @@ unsigned int GCodeProcessor::s_result_id = 0; GCodeProcessor::GCodeProcessor() { reset(); - m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n"; - m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n"; } void GCodeProcessor::apply_config(const PrintConfig& config) @@ -585,7 +591,12 @@ void GCodeProcessor::apply_config(const PrintConfig& config) for (auto& machine : this->m_time_processor.machines) { machine.time_acceleration = float(time_estimation_compensation); } - }} + } + + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].remaining_times_type = config.remaining_times_type.value; + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].remaining_times_type = config.remaining_times_type.value; + +} void GCodeProcessor::apply_config(const DynamicPrintConfig& config) { @@ -778,6 +789,14 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) machine.time_acceleration = float(time_estimation_compensation); } } + + + const ConfigOptionEnum* remaining_times_type = config.option>("remaining_times_type"); + if (remaining_times_type) { + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].remaining_times_type = remaining_times_type->value; + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].remaining_times_type = remaining_times_type->value; + } + } void GCodeProcessor::enable_stealth_time_estimator(bool enabled) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index d672fc5ea..191f7756a 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -208,7 +208,7 @@ namespace Slic3r { float extrude_factor_override_percentage; float time; // s float time_acceleration; - std::string line_m73_mask; + RemainingTimeType remaining_times_type; State curr; State prev; CustomGCodeTime gcode_time; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index b9c50bbae..b311d722c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -751,6 +751,7 @@ const std::vector& Preset::printer_options() "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits", "remaining_times", + "remaining_times_type", "silent_mode", "machine_limits_usage", "thumbnails", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index bd0fc0fc8..66d7e54a3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2512,13 +2512,27 @@ void PrintConfigDef::init_fff_params() def = this->add("remaining_times", coBool); def->label = L("Supports remaining times"); def->category = OptionCategory::firmware; - def->tooltip = L("Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute" - " intervals into the G-code to let the firmware show accurate remaining time." - " As of now only the Prusa i3 MK3 firmware recognizes M73." - " Also the i3 MK3 firmware supports M73 Qxx Sxx for the silent mode."); + def->tooltip = L("Emit somethign at 1 minute intervals into the G-code to let the firmware show accurate remaining time."); def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("remaining_times_type", coEnum); + def->label = L("Method"); + def->full_label = L("Supports remaining times method"); + def->category = OptionCategory::firmware; + def->tooltip = L("M73: Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute" + " intervals into the G-code to let the firmware show accurate remaining time." + " As of now only the Prusa i3 MK3 firmware recognizes M73." + " Also the i3 MK3 firmware supports M73 Qxx Sxx for the silent mode." + "\nM117: Send a command to display a message to the printer, this is 'Time Left .h..m..s'." ); + def->mode = comExpert; + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("m117"); + def->enum_values.push_back("m73"); + def->enum_labels.push_back(L("M117")); + def->enum_labels.push_back(L("M73")); + def->set_default_value(new ConfigOptionEnum(RemainingTimeType::rtM73)); + def = this->add("silent_mode", coBool); def->label = L("Supports stealth mode"); def->category = OptionCategory::firmware; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index b5827e6e9..6914ba919 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -132,6 +132,11 @@ enum InfillConnection { icConnected, icHoles, icOuterShell, icNotConnected, }; +enum RemainingTimeType { + rtM117, + rtM73, +}; + enum SupportZDistanceType { zdFilament, zdPlane, zdNone, }; @@ -334,6 +339,14 @@ template<> inline const t_config_enum_values& ConfigOptionEnum return keys_map; } +template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { + static const t_config_enum_values keys_map = { + { "m117", rtM117 }, + { "m73", rtM73 } + }; + return keys_map; +} + template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static const t_config_enum_values keys_map = { { "filament", zdFilament }, @@ -341,7 +354,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static const t_config_enum_values keys_map = { @@ -1139,6 +1152,7 @@ public: ConfigOptionBool high_current_on_filament_swap; ConfigOptionFloat parking_pos_retraction; ConfigOptionBool remaining_times; + ConfigOptionEnum remaining_times_type; ConfigOptionBool silent_mode; ConfigOptionFloat extra_loading_move; ConfigOptionBool wipe_advanced; @@ -1255,6 +1269,7 @@ protected: OPT_PTR(high_current_on_filament_swap); OPT_PTR(parking_pos_retraction); OPT_PTR(remaining_times); + OPT_PTR(remaining_times_type); OPT_PTR(silent_mode); OPT_PTR(extra_loading_move); OPT_PTR(wipe_advanced); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index a4cf9cd41..b7010bc1d 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1229,6 +1229,8 @@ void Choice::set_value(const boost::any& value, bool change_event) val = idx_from_enum_value(val); else if (m_opt_id == "printhost_authorization_type") val = idx_from_enum_value(val); + else if (m_opt_id.compare("remaining_times_type") == 0) + val = idx_from_enum_value(val); else if (m_opt_id.compare("seam_position") == 0) val = idx_from_enum_value(val); else if (m_opt_id.compare("support_material_contact_distance_type") == 0) @@ -1351,6 +1353,8 @@ boost::any& Choice::get_value() convert_to_enum_value(ret_enum); else if (m_opt_id == "printhost_authorization_type") convert_to_enum_value(ret_enum); + else if (m_opt_id.compare("remaining_times_type") == 0) + convert_to_enum_value(ret_enum); else if (m_opt_id.compare("seam_position") == 0) convert_to_enum_value(ret_enum); else if (m_opt_id.compare("support_material_contact_distance_type") == 0) diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 5b1b156d6..60d86bf32 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -217,6 +217,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key == "printhost_authorization_type") config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + else if (opt_key.compare("remaining_times_type") == 0) + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("seam_position") == 0 || opt_key.compare("perimeter_loop_seam") == 0) config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("support_material_contact_distance_type") == 0) diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 609760b21..1334183db 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -988,6 +988,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = static_cast(config.option>(opt_key)->value); } else if (opt_key == "printhost_authorization_type") { ret = static_cast(config.option>(opt_key)->value); + } else if (opt_key == "remaining_times_type"){ + ret = static_cast(config.option>(opt_key)->value); } else if (opt_key == "seam_position" || opt_key == "perimeter_loop_seam") { ret = static_cast(config.option>(opt_key)->value); } else if (opt_key == "support_material_contact_distance_type"){ diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index bac518069..02898c981 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2895,6 +2895,11 @@ void TabPrinter::toggle_options() field = get_field("thumbnails_color"); if (field) field->toggle(custom_color); + //firmware + bool have_remaining_times = m_config->opt_bool("remaining_times"); + field = get_field("remaining_times_type"); + if (field) field->toggle(have_remaining_times); + bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; // Disable silent mode for non-marlin firmwares. field = get_field("silent_mode"); diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index a45eaf1a0..b5927b40f 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -983,6 +983,8 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return get_string_from_enum(opt_key, config); if (opt_key == "printhost_authorization_type") return get_string_from_enum(opt_key, config); + if (opt_key == "remaining_times_type") + return get_string_from_enum(opt_key, config); if (opt_key == "seam_position") return get_string_from_enum(opt_key, config); if (opt_key == "support_material_contact_distance_type")