From b395da52f6dcd42bb27d1b64f75dc032fed357e3 Mon Sep 17 00:00:00 2001 From: Ocraftyone Date: Wed, 5 Jun 2024 01:47:31 -0400 Subject: [PATCH] Spoolman Statistics Moved to Preset Spoolman statistics are now stored in the filament preset and are not saved to a file --- src/libslic3r/GCode.cpp | 29 ++++++++++++++++++ src/libslic3r/Preset.cpp | 2 +- src/libslic3r/Preset.hpp | 10 ++++++ src/libslic3r/PresetBundle.cpp | 13 ++++++++ src/libslic3r/PrintConfig.cpp | 56 ++++++++-------------------------- src/libslic3r/PrintConfig.hpp | 4 +++ src/slic3r/GUI/Tab.cpp | 48 +++++++++++++++++++++++------ src/slic3r/GUI/Tab.hpp | 1 + src/slic3r/Utils/Spoolman.cpp | 26 ++++++++-------- src/slic3r/Utils/Spoolman.hpp | 1 + 10 files changed, 123 insertions(+), 67 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 467ec4bbeb..23afbf5a34 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1666,6 +1666,35 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu result->filename = path; } + std::vector filaments_with_spoolman_idxs; + for (int l = 0; l < print->config().filament_density.size(); ++l) { + if (print->config().filament_spoolman_enabled.get_at(l)) + filaments_with_spoolman_idxs.push_back(l); + } + + if (!filaments_with_spoolman_idxs.empty()) { + // get used filament (meters and grams) from used volume in respect to the active extruder + auto get_used_filament_from_volume = [&](int extruder_id) { + double volume = print->m_print_statistics.filament_stats[extruder_id]; + std::pair ret = { volume / (PI * sqr(0.5 * print->config().filament_diameter.get_at(extruder_id))), + volume * print->config().filament_density.get_at(extruder_id) * 0.001 }; + return ret; + }; + + for (const auto& item : filaments_with_spoolman_idxs) { + auto [est_used_length, est_used_weight] = get_used_filament_from_volume(item); + double remaining_length = print->config().filament_remaining_length.get_at(item); + double remaining_weight = print->config().filament_remaining_weight.get_at(item); + + if (est_used_length > remaining_length || est_used_weight > remaining_weight) { + std::string filament_name = print->config().filament_settings_id.get_at(item); + std::string msg = boost::str(boost::format(_("Filament %1% does not have enough material for the print. Used: %2$.2f m, %3$.2f g, Remaining: %4$.2f m, %5$.2f g")) % + filament_name % (est_used_length * 0.001) % est_used_weight % remaining_length % remaining_weight); + print->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, msg); + } + } + } + //BBS: add some log for error output BOOST_LOG_TRIVIAL(debug) << boost::format("Finished processing gcode to %1% ") % path_tmp; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 89c3b1944e..13875d15f8 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -852,7 +852,7 @@ static std::vector s_Preset_filament_options { "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_multitool_ramming", "filament_multitool_ramming_volume", "filament_multitool_ramming_flow", "activate_chamber_temp_control", "filament_long_retractions_when_cut","filament_retraction_distances_when_cut", - "spoolman_spool_id", "spoolman_remaining_weight", "spoolman_used_weight", "spoolman_remaining_length", "spoolman_used_length", "spoolman_archived" + "spoolman_spool_id" }; static std::vector s_Preset_machine_limits_options { diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index ef4e97b721..5e274663b9 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -244,6 +244,16 @@ public: long long updated_time{0}; //last updated time std::map key_values; + // indicate if spoolman is enabled for this preset + bool spoolman_enabled() const { return config.opt_int("spoolman_spool_id") > 0; } + + // Orca: spoolman statistics. these are not stored in the preset file + double spoolman_remaining_length = 0; + double spoolman_remaining_weight = 0; + double spoolman_used_length = 0; + double spoolman_used_weight = 0; + bool spoolman_archived = false; + static std::string get_type_string(Preset::Type type); // get string type for iot static std::string get_iot_type_string(Preset::Type type); diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index c28e32847f..746ddb2f1f 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -2110,6 +2110,9 @@ DynamicPrintConfig PresetBundle::full_fff_config() const std::vector print_compatible_printers; //BBS: add logic for settings check between different system presets std::vector different_settings; + std::vector filament_spoolman_enabled; + std::vector filament_remaining_weight; + std::vector filament_remaining_length; std::string different_print_settings, different_printer_settings; compatible_printers_condition.emplace_back(this->prints.get_edited_preset().compatible_printers_condition()); @@ -2132,6 +2135,9 @@ DynamicPrintConfig PresetBundle::full_fff_config() const out.apply(this->filaments.get_edited_preset().config); compatible_printers_condition.emplace_back(this->filaments.get_edited_preset().compatible_printers_condition()); compatible_prints_condition .emplace_back(this->filaments.get_edited_preset().compatible_prints_condition()); + filament_spoolman_enabled.emplace_back(this->filaments.get_edited_preset().spoolman_enabled()); + filament_remaining_weight.emplace_back(this->filaments.get_edited_preset().spoolman_remaining_weight); + filament_remaining_length.emplace_back(this->filaments.get_edited_preset().spoolman_remaining_weight); //BBS: add logic for settings check between different system presets //std::string filament_inherits = this->filaments.get_edited_preset().inherits(); std::string current_preset_name = this->filament_presets[0]; @@ -2173,6 +2179,9 @@ DynamicPrintConfig PresetBundle::full_fff_config() const DynamicPrintConfig &cfg_rw = *const_cast(cfg); compatible_printers_condition.emplace_back(Preset::compatible_printers_condition(cfg_rw)); compatible_prints_condition .emplace_back(Preset::compatible_prints_condition(cfg_rw)); + filament_spoolman_enabled.emplace_back(preset->spoolman_enabled()); + filament_remaining_weight.emplace_back(preset->spoolman_remaining_weight); + filament_remaining_length.emplace_back(preset->spoolman_remaining_weight); //BBS: add logic for settings check between different system presets std::string filament_inherits = Preset::inherits(cfg_rw); @@ -2272,6 +2281,10 @@ DynamicPrintConfig PresetBundle::full_fff_config() const out.option("filament_settings_id", true)->values = this->filament_presets; out.option("printer_settings_id", true)->value = this->printers.get_selected_preset_name(); out.option("filament_ids", true)->values = filament_ids; + out.option("filament_spoolman_enabled", true)->values = filament_spoolman_enabled; + out.option("filament_remaining_weight", true)->values = filament_remaining_weight; + out.option("filament_remaining_length", true)->values = filament_remaining_length; + // Serialize the collected "compatible_printers_condition" and "inherits" fields. // There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored. // The vector will not be stored if all fields are empty strings. diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 12a2dfe514..48b3776dc0 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2016,6 +2016,18 @@ def = this->add("filament_loading_speed", coFloats); def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; + def = this->add("filament_spoolman_enabled", coBools); + def->set_default_value(new ConfigOptionBools()); + def->cli = ConfigOptionDef::nocli; + + def = this->add("filament_remaining_weight", coFloats); + def->set_default_value(new ConfigOptionFloats()); + def->cli = ConfigOptionDef::nocli; + + def = this->add("filament_remaining_length", coFloats); + def->set_default_value(new ConfigOptionFloats()); + def->cli = ConfigOptionDef::nocli; + def = this->add("filament_vendor", coStrings); def->label = L("Vendor"); def->tooltip = L("Vendor of filament. For show only"); @@ -2032,50 +2044,6 @@ def = this->add("filament_loading_speed", coFloats); def->set_default_value(new ConfigOptionInt()); def->cli = ConfigOptionDef::nocli; - def = this->add("spoolman_remaining_weight", coFloat); - def->label = L("Remaining Weight"); - def->tooltip = L("Remaining weight of the spool"); - def->mode = comAdvanced; - def->sidetext = L("g"); - def->readonly = true; - def->set_default_value(new ConfigOptionFloat()); - def->cli = ConfigOptionDef::nocli; - - def = this->add("spoolman_used_weight", coFloat); - def->label = L("Used Weight"); - def->tooltip = L("Used weight of the spool"); - def->mode = comAdvanced; - def->sidetext = L("g"); - def->readonly = true; - def->set_default_value(new ConfigOptionFloat()); - def->cli = ConfigOptionDef::nocli; - - def = this->add("spoolman_remaining_length", coFloat); - def->label = L("Remaining Length"); - def->tooltip = L("Remaining length of the filament on the spool"); - def->mode = comAdvanced; - def->sidetext = L("mm"); - def->readonly = true; - def->set_default_value(new ConfigOptionFloat()); - def->cli = ConfigOptionDef::nocli; - - def = this->add("spoolman_used_length", coFloat); - def->label = L("Used Length"); - def->tooltip = L("Used length of the filament from the spool"); - def->mode = comAdvanced; - def->sidetext = L("mm"); - def->readonly = true; - def->set_default_value(new ConfigOptionFloat()); - def->cli = ConfigOptionDef::nocli; - - def = this->add("spoolman_archived", coBool); - def->label = L("Archived"); - def->tooltip = L("Indicates if the spool is archived"); - def->mode = comAdvanced; - def->readonly = true; - def->set_default_value(new ConfigOptionBool()); - def->cli = ConfigOptionDef::nocli; - def = this->add("infill_direction", coFloat); def->label = L("Infill direction"); def->category = L("Strength"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index be3edef9a3..ea408fcd92 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1031,6 +1031,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, fan_kickstart)) ((ConfigOptionBool, fan_speedup_overhangs)) ((ConfigOptionFloat, fan_speedup_time)) + ((ConfigOptionStrings, filament_settings_id)) ((ConfigOptionFloats, filament_diameter)) ((ConfigOptionFloats, filament_density)) ((ConfigOptionStrings, filament_type)) @@ -1134,6 +1135,9 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionStrings, small_area_infill_flow_compensation_model)) ((ConfigOptionBool, has_scarf_joint_seam)) + ((ConfigOptionBools, filament_spoolman_enabled)) + ((ConfigOptionFloats, filament_remaining_weight)) + ((ConfigOptionFloats, filament_remaining_length)) ) // This object is mapped to Perl as Slic3r::Config::Print. diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index f4a8b7da60..1eccfe5f5a 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3191,6 +3191,19 @@ void TabFilament::update_filament_overrides_page() } } +void TabFilament::update_spoolman_statistics() { + Preset* selected_preset = &m_presets->get_selected_preset(); + + if (!selected_preset->spoolman_enabled()) + return; + + m_active_page->get_field("spoolman_remaining_weight")->set_value(double_to_string(selected_preset->spoolman_remaining_weight, 2), false); + m_active_page->get_field("spoolman_used_weight")->set_value(double_to_string(selected_preset->spoolman_used_weight, 2), false); + m_active_page->get_field("spoolman_remaining_length")->set_value(double_to_string(selected_preset->spoolman_remaining_length * 0.001, 2), false); + m_active_page->get_field("spoolman_used_length")->set_value(double_to_string(selected_preset->spoolman_used_length * 0.001, 2), false); + m_active_page->get_field("spoolman_archived")->set_value(selected_preset->spoolman_archived, false); +} + void TabFilament::build() { m_presets = &m_preset_bundle->filaments; @@ -3404,7 +3417,7 @@ void TabFilament::build() return; } if (!Spoolman::is_server_valid()) { - show_error(parent, "Failed to get data from the Spoolman server. Make sure that the port is correct and the server is running."); + show_error(this, "Failed to get data from the Spoolman server. Make sure that the port is correct and the server is running."); return; } auto res1 = Spoolman::update_filament_preset_from_spool(&m_presets->get_edited_preset(), true, stats_only); @@ -3413,9 +3426,7 @@ void TabFilament::build() if (res1.has_failed() || res2.has_failed()) return; - const Preset* preset = m_presets->get_selected_preset_parent(); - m_presets->get_selected_preset().save(preset ? &preset->config : nullptr); - update_dirty(); + update_spoolman_statistics(); }; auto refresh_all_btn = new wxButton(parent, wxID_ANY, _L("Update Filament")); @@ -3431,12 +3442,28 @@ void TabFilament::build() }; optgroup->append_line(line); - optgroup = page->new_optgroup("Spool Statistics"); - optgroup->append_single_option_line("spoolman_remaining_weight"); - optgroup->append_single_option_line("spoolman_used_weight"); - optgroup->append_single_option_line("spoolman_remaining_length"); - optgroup->append_single_option_line("spoolman_used_length"); - optgroup->append_single_option_line("spoolman_archived"); + optgroup = page->new_optgroup(_L("Spool Statistics")); + + auto build_statistics_line = [&](const std::string& key, const std::string& label, + const std::string& sidetext, const ConfigOptionType& type = coFloat) { + auto def = ConfigOptionDef(); + def.opt_key = key; + def.label = label; + def.type = type; + def.sidetext = sidetext; + def.readonly = true; + if (type == coFloat) + def.set_default_value(new ConfigOptionFloat()); + else if (type == coBool) + def.set_default_value(new ConfigOptionBool()); + return optgroup->append_single_option_line(Option(def, key)); + }; + + build_statistics_line("spoolman_remaining_weight", "Remaining Weight", "g"); + build_statistics_line("spoolman_used_weight", "Used Weight", "g"); + build_statistics_line("spoolman_remaining_length", "Remaining Length", "m"); + build_statistics_line("spoolman_used_length", "Used Length", "m"); + build_statistics_line("spoolman_archived", "Archived", "", coBool); page->m_should_show_fn = [&](bool current_value) { return m_preset_bundle->printers.get_edited_preset().config.opt_bool("spoolman_enabled"); @@ -3589,6 +3616,7 @@ void TabFilament::toggle_options() if (m_active_page->title() == L("Spoolman")) { toggle_line("spoolman_update", m_config->opt_int("spoolman_spool_id") > 0); + update_spoolman_statistics(); } } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index df33bb4905..7ad32a9398 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -574,6 +574,7 @@ private: void add_filament_overrides_page(); void update_filament_overrides_page(); void update_volumetric_flow_preset_hints(); + void update_spoolman_statistics(); std::map m_overrides_options; diff --git a/src/slic3r/Utils/Spoolman.cpp b/src/slic3r/Utils/Spoolman.cpp index f8f96c9afe..6123718f05 100644 --- a/src/slic3r/Utils/Spoolman.cpp +++ b/src/slic3r/Utils/Spoolman.cpp @@ -16,9 +16,6 @@ template Type get_opt(pt::ptree& data, string path) { return data.ge // Spoolman //--------------------------------- -static vector statistics_keys = {"spoolman_remaining_weight", "spoolman_used_weight", "spoolman_remaining_length", - "spoolman_used_length", "spoolman_archived"}; - pt::ptree Spoolman::get_spoolman_json(const string& api_endpoint) { DynamicPrintConfig& config = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config; @@ -167,7 +164,7 @@ SpoolmanResult Spoolman::create_filament_preset_from_spool(const SpoolmanSpoolSh preset->config.apply(base_profile->config); preset->config.set_key_value("filament_settings_id", new ConfigOptionStrings({filament_preset_name})); preset->config.set("inherits", inherits, true); - spool->apply_to_config(preset->config); + spool->apply_to_preset(preset); preset->filament_id = get_filament_id(filament_preset_name); preset->version = base_profile->version; preset->loaded = true; @@ -178,7 +175,6 @@ SpoolmanResult Spoolman::create_filament_preset_from_spool(const SpoolmanSpoolSh SpoolmanResult Spoolman::update_filament_preset_from_spool(Preset* filament_preset, bool update_from_server, bool only_update_statistics) { - DynamicConfig config; SpoolmanResult result; const int& spool_id = filament_preset->config.opt_int("spoolman_spool_id"); @@ -190,8 +186,7 @@ SpoolmanResult Spoolman::update_filament_preset_from_spool(Preset* filament_pres SpoolmanSpoolShrPtr& spool = get_instance()->m_spools[spool_id]; if (update_from_server) spool->update_from_server(!only_update_statistics); - spool->apply_to_config(config); - filament_preset->config.apply_only(config, only_update_statistics ? statistics_keys : config.keys()); + spool->apply_to_preset(filament_preset, only_update_statistics); return result; } @@ -284,14 +279,21 @@ void SpoolmanSpool::update_from_server(bool recursive) void SpoolmanSpool::apply_to_config(Slic3r::DynamicConfig& config) const { config.set_key_value("spoolman_spool_id", new ConfigOptionInt(id)); - config.set_key_value("spoolman_remaining_weight", new ConfigOptionFloat(remaining_weight)); - config.set_key_value("spoolman_used_weight", new ConfigOptionFloat(used_weight)); - config.set_key_value("spoolman_remaining_length", new ConfigOptionFloat(remaining_length)); - config.set_key_value("spoolman_used_length", new ConfigOptionFloat(used_length)); - config.set_key_value("spoolman_archived", new ConfigOptionBool(archived)); m_filament_ptr->apply_to_config(config); } +void SpoolmanSpool::apply_to_preset(Preset* preset, bool only_update_statistics) const +{ + preset->spoolman_remaining_weight = remaining_weight; + preset->spoolman_used_weight = used_weight; + preset->spoolman_remaining_length = remaining_length; + preset->spoolman_used_length = used_length; + preset->spoolman_archived = archived; + if (only_update_statistics) + return; + this->apply_to_config(preset->config); +} + void SpoolmanSpool::update_from_json(pt::ptree json_data) { if (int filament_id = json_data.get("filament.id"); m_filament_ptr && m_filament_ptr->id != filament_id) { diff --git a/src/slic3r/Utils/Spoolman.hpp b/src/slic3r/Utils/Spoolman.hpp index e9cfe2e4b9..224c9d9d1d 100644 --- a/src/slic3r/Utils/Spoolman.hpp +++ b/src/slic3r/Utils/Spoolman.hpp @@ -161,6 +161,7 @@ public: void update_from_server(bool recursive = false); void apply_to_config(DynamicConfig& config) const; + void apply_to_preset(Preset* preset, bool only_update_statistics = false) const; private: Spoolman* m_spoolman;