diff --git a/src/slic3r/GUI/UserAccount.cpp b/src/slic3r/GUI/UserAccount.cpp index 814f81376c..25647115f7 100644 --- a/src/slic3r/GUI/UserAccount.cpp +++ b/src/slic3r/GUI/UserAccount.cpp @@ -3,8 +3,11 @@ #include "UserAccountUtils.hpp" #include "format.hpp" #include "GUI.hpp" +#include "GUI_App.hpp" #include "libslic3r/Utils.hpp" +#include "libslic3r/Preset.hpp" +#include "libslic3r/PresetBundle.hpp" #include #include @@ -210,15 +213,17 @@ bool UserAccount::on_connect_printers_success(const std::string& data, AppConfig BOOST_LOG_TRIVIAL(error) << "Missing printer model for printer uuid: " << *printer_uuid; continue; } - std::pair model_nozzle_pair = m_printer_uuid_map[*printer_uuid]; + + std::string printer_name = m_printer_uuid_map[*printer_uuid]; - if (new_printer_map.find(model_nozzle_pair) == new_printer_map.end()) { - new_printer_map[model_nozzle_pair].reserve(static_cast(ConnectPrinterState::CONNECT_PRINTER_STATE_COUNT)); + if (new_printer_map.find(printer_name) == new_printer_map.end()) { + new_printer_map[printer_name].reserve(static_cast(ConnectPrinterState::CONNECT_PRINTER_STATE_COUNT)); for (size_t i = 0; i < static_cast(ConnectPrinterState::CONNECT_PRINTER_STATE_COUNT); i++) { - new_printer_map[model_nozzle_pair].push_back(0); + new_printer_map[printer_name].push_back(0); } } - new_printer_map[model_nozzle_pair][static_cast(state)] += 1; + new_printer_map[printer_name][static_cast(state)] += 1; + } // compare new and old printer map and update old map into new @@ -277,10 +282,20 @@ bool UserAccount::on_connect_uiid_map_success(const std::string& data, AppConfig std::map> config_options_to_match; UserAccountUtils::fill_config_options_from_json(ptree, config_options_to_match); + const Preset* printer_preset = UserAccountUtils::find_preset_by_nozzle_and_options(wxGetApp().preset_bundle->printers, *printer_model, config_options_to_match); + BOOST_LOG_TRIVIAL(error) << (printer_preset ? printer_preset->name : std::string("UNKNOWN")) << " " << *printer_uuid; + if (printer_preset) { + m_printer_uuid_map[*printer_uuid] = printer_preset->name; + } else { + //assert(false); + BOOST_LOG_TRIVIAL(error) << "Failed to find preset for printer model: " << *printer_model; + } + /* const auto nozzle_diameter_opt = printer_tree.second.get_optional("nozzle_diameter"); const std::string nozzle_diameter = (nozzle_diameter_opt && *nozzle_diameter_opt != "0.0") ? *nozzle_diameter_opt : std::string(); std::pair model_nozzle_pair = { *printer_model, nozzle_diameter }; m_printer_uuid_map[*printer_uuid] = model_nozzle_pair; + */ } m_communication->on_uuid_map_success(); return on_connect_printers_success(data, app_config, out_printers_changed); diff --git a/src/slic3r/GUI/UserAccount.hpp b/src/slic3r/GUI/UserAccount.hpp index d690c6deb4..418acaccc8 100644 --- a/src/slic3r/GUI/UserAccount.hpp +++ b/src/slic3r/GUI/UserAccount.hpp @@ -24,10 +24,9 @@ enum class ConnectPrinterState { CONNECT_PRINTER_ERROR, CONNECT_PRINTER_STATE_COUNT }; -// is pair of printer_model and nozzle_diameter. std::vector is vector of ConnectPrinterState counters -typedef std::map, std::vector> ConnectPrinterStateMap; -// inner map is map of parameters -typedef std::map< std::string, std::map> ConnectUUIDToModelNozzleMap; +// printer preset name and std::vector is vector of ConnectPrinterState counters +typedef std::map> ConnectPrinterStateMap; +typedef std::map< std::string, std::string> ConnectUUIDToPresetName; // Class UserAccount should handle every request for entities outside PrusaSlicer like PrusaAuth or PrusaConnect. // Outside communication is implemented in class UserAccountCommunication that runs separate thread. Results come back in events to Plater. // All incoming data shoud be stored in UserAccount. @@ -86,7 +85,7 @@ private: std::unique_ptr m_communication; ConnectPrinterStateMap m_printer_map; - ConnectUUIDToModelNozzleMap m_printer_uuid_map; + ConnectUUIDToPresetName m_printer_uuid_map; std::map m_account_user_data; std::string m_username; size_t m_fail_counter { 0 }; diff --git a/src/slic3r/GUI/UserAccountUtils.cpp b/src/slic3r/GUI/UserAccountUtils.cpp index fad0212d9a..e70f858d4a 100644 --- a/src/slic3r/GUI/UserAccountUtils.cpp +++ b/src/slic3r/GUI/UserAccountUtils.cpp @@ -1,5 +1,9 @@ #include "UserAccountUtils.hpp" +#include "libslic3r/Preset.hpp" +#include "slic3r/GUI/Field.hpp" +#include "slic3r/GUI/GUI.hpp" + #include #include #include @@ -320,6 +324,95 @@ std::string get_print_data_from_json(const std::string& json, const std::string& return result; } +const Preset* find_preset_by_nozzle_and_options( + const PrinterPresetCollection& collection + , const std::string& model_id + , std::map>& options) +{ + // find all matching presets when repo prefix is omitted + std::vector results; + for (const Preset &preset : collection) { + // trim repo prefix + std::string printer_model = preset.config.opt_string("printer_model"); + std::string vendor_repo_prefix; + if (preset.vendor) { + vendor_repo_prefix = preset.vendor->repo_prefix; + } else if (std::string inherits = preset.inherits(); !inherits.empty()) { + const Preset *parent = collection.find_preset(inherits); + if (parent && parent->vendor) { + vendor_repo_prefix = parent->vendor->repo_prefix; + } + } + if (printer_model.find(vendor_repo_prefix) == 0) { + printer_model = printer_model.substr(vendor_repo_prefix.size() + ); + boost::trim_left(printer_model); + } + + if (!preset.is_system || printer_model != model_id) + continue; + if (preset.printer_technology() == ptFFF) { + // options (including nozzle_diameter) + bool failed = false; + for (const auto& opt : options) { + assert(preset.config.has(opt.first)); + // We compare only first value now, but options contains data for all (some might be empty tho) + std::string opt_val; + if (preset.config.option(opt.first)->is_scalar()) { + opt_val = preset.config.option(opt.first)->serialize(); + } else { + switch (preset.config.option(opt.first)->type()) { + case coInts: opt_val = std::to_string(static_cast(preset.config.option(opt.first))->values[0]); break; + case coFloats: + opt_val = GUI::into_u8(double_to_string(static_cast(preset.config.option(opt.first))->values[0])); + if (size_t pos = opt_val.find(",") != std::string::npos) + opt_val.replace(pos, 1, 1, '.'); + break; + case coStrings: opt_val = static_cast(preset.config.option(opt.first))->values[0]; break; + case coBools: opt_val = static_cast(preset.config.option(opt.first))->values[0] ? "1" : "0"; break; + default: + assert(false); + continue; + } + } + + if (opt_val != opt.second[0]) + { + failed = true; + break; + } + } + if (!failed) { + results.push_back(&preset); + } + } else { + + } + } + // find visible without prefix + for (const Preset *preset : results) { + if (preset->is_visible && preset->config.opt_string("printer_model") == model_id) { + return preset; + } + } + // find one visible + for (const Preset *preset : results) { + if (preset->is_visible) { + return preset; + } + } + // find one without prefix + for (const Preset* preset : results) { + if (preset->config.opt_string("printer_model") == model_id) { + return preset; + } + } + if (results.size() != 0) { + return results.front(); + } + return nullptr; +} + }}} // Slic3r::GUI::UserAccountUtils diff --git a/src/slic3r/GUI/UserAccountUtils.hpp b/src/slic3r/GUI/UserAccountUtils.hpp index d98e2d00dd..499c98af1d 100644 --- a/src/slic3r/GUI/UserAccountUtils.hpp +++ b/src/slic3r/GUI/UserAccountUtils.hpp @@ -7,7 +7,10 @@ #include -namespace Slic3r { namespace GUI { +namespace Slic3r { +class Preset; +class PrinterPresetCollection; +namespace GUI { namespace UserAccountUtils { // If ptree parameter is empty, json parameter needs to contain data and ptree is filled. @@ -23,6 +26,7 @@ void fill_material_from_json(const std::string& json, std::vector& std::string get_print_data_from_json(const std::string &json, const std::string &keyword); +const Preset* find_preset_by_nozzle_and_options( const PrinterPresetCollection& collection, const std::string& model_id, std::map>& options); }}} // Slic3r::GUI::UserAccountUtils #endif // slic3r_UserAccountUtils_hpp_