From 725e60d006771a5a6817638a30873fd464439794 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 3 Jun 2021 10:37:26 +0200 Subject: [PATCH 1/3] PrusaLink class --- src/libslic3r/PrintConfig.cpp | 4 ++- src/libslic3r/PrintConfig.hpp | 4 ++- src/slic3r/GUI/PhysicalPrinterDialog.cpp | 9 +++++ src/slic3r/GUI/PhysicalPrinterDialog.hpp | 2 +- src/slic3r/Utils/OctoPrint.cpp | 44 ++++++++++++++++++++++++ src/slic3r/Utils/OctoPrint.hpp | 25 ++++++++++++++ src/slic3r/Utils/PrintHost.cpp | 1 + 7 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b3084f550..a05299618 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1541,18 +1541,20 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain " "the kind of the host."); def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("prusalink"); def->enum_values.push_back("octoprint"); def->enum_values.push_back("duet"); def->enum_values.push_back("flashair"); def->enum_values.push_back("astrobox"); def->enum_values.push_back("repetier"); + def->enum_labels.push_back("PrusaLink"); def->enum_labels.push_back("OctoPrint"); def->enum_labels.push_back("Duet"); def->enum_labels.push_back("FlashAir"); def->enum_labels.push_back("AstroBox"); def->enum_labels.push_back("Repetier"); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionEnum(htOctoPrint)); + def->set_default_value(new ConfigOptionEnum(/*htOctoPrint*/htPrusaLink)); def = this->add("only_retract_when_crossing_perimeters", coBool); def->label = L("Only retract when crossing perimeters"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index b5896891e..dc959e373 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -36,7 +36,7 @@ enum class MachineLimitsUsage { }; enum PrintHostType { - htOctoPrint, htDuet, htFlashAir, htAstroBox, htRepetier + htPrusaLink, htOctoPrint, htDuet, htFlashAir, htAstroBox, htRepetier }; enum AuthorizationType { @@ -122,11 +122,13 @@ template<> inline const t_config_enum_values& ConfigOptionEnum inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { + keys_map["prusalink"] = htPrusaLink; keys_map["octoprint"] = htOctoPrint; keys_map["duet"] = htDuet; keys_map["flashair"] = htFlashAir; keys_map["astrobox"] = htAstroBox; keys_map["repetier"] = htRepetier; + } return keys_map; } diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 620a3ddca..6f0262980 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -62,6 +62,8 @@ PresetForPrinter::PresetForPrinter(PhysicalPrinterDialog* parent, const std::str if (preset->name == edited_preset.name) preset = &edited_preset; + m_parent->selected_preset_changed(preset->name); + // if created physical printer doesn't have any settings, use the settings from the selected preset if (m_parent->get_printer()->has_empty_config()) { // update Print Host upload from the selected preset @@ -645,5 +647,12 @@ void PhysicalPrinterDialog::DeletePreset(PresetForPrinter* preset_for_printer) this->Fit(); } +void PhysicalPrinterDialog::selected_preset_changed(std::string preset_name) +{ + if (preset_name.rfind("Original Prusa i3 MK3", 0) == 0) + { + BOOST_LOG_TRIVIAL(debug) << "Original Prusa i3 MK3"; + } +} }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.hpp b/src/slic3r/GUI/PhysicalPrinterDialog.hpp index 7ee1f7d92..0ce9c2720 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.hpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.hpp @@ -95,7 +95,7 @@ public: PrinterTechnology get_printer_technology(); void DeletePreset(PresetForPrinter* preset_for_printer); - + void selected_preset_changed(std::string preset_name); protected: void on_dpi_changed(const wxRect& suggested_rect) override; void on_sys_color_changed() override {}; diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index fad45f822..d23d83a00 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -213,4 +213,48 @@ void SL1Host::set_auth(Http &http) const } } +// PrusaLink +PrusaLink::PrusaLink(DynamicPrintConfig* config) : + OctoPrint(config), + authorization_type(dynamic_cast*>(config->option("printhost_authorization_type"))->value), + username(config->opt_string("printhost_user")), + password(config->opt_string("printhost_password")) +{ +} + +const char* PrusaLink::get_name() const { return "PrusaLink"; } + +wxString PrusaLink::get_test_ok_msg() const +{ + return _(L("Connection to PrusaLink works correctly.")); +} + +wxString PrusaLink::get_test_failed_msg(wxString& msg) const +{ + return GUI::from_u8((boost::format("%s: %s") + % _utf8(L("Could not connect to PrusaLink")) + % std::string(msg.ToUTF8())).str()); +} + +bool PrusaLink::validate_version_text(const boost::optional& version_text) const +{ + return version_text ? boost::starts_with(*version_text, "PrusaLink") : false; +} + +void PrusaLink::set_auth(Http& http) const +{ + switch (authorization_type) { + case atKeyPassword: + http.header("X-Api-Key", get_apikey()); + break; + case atUserPassword: + http.auth_digest(username, password); + break; + } + + if (!get_cafile().empty()) { + http.ca_file(get_cafile()); + } +} + } diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index ed1c61bd6..025fd3da5 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -70,6 +70,31 @@ private: std::string password; }; +class PrusaLink : public OctoPrint +{ +public: + PrusaLink(DynamicPrintConfig* config); + ~PrusaLink() override = default; + + const char* get_name() const override; + + wxString get_test_ok_msg() const override; + wxString get_test_failed_msg(wxString& msg) const override; + bool can_start_print() const override { return false; } + +protected: + bool validate_version_text(const boost::optional& version_text) const override; + +private: + void set_auth(Http& http) const override; + + // Host authorization type. + AuthorizationType authorization_type; + // username and password for HTTP Digest Authentization (RFC RFC2617) + std::string username; + std::string password; +}; + } #endif diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index 589679e47..53200a4c9 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -50,6 +50,7 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config) case htFlashAir: return new FlashAir(config); case htAstroBox: return new AstroBox(config); case htRepetier: return new Repetier(config); + case htPrusaLink: return new PrusaLink(config); default: return nullptr; } } else { From 80f4571cd7e6c664345b7ce86aca7e376ec2eb3a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 4 Jun 2021 08:42:04 +0200 Subject: [PATCH 2/3] PhysicalPrinterDialog : Update of the HostType in respect to the selected printers --- src/slic3r/GUI/Field.cpp | 10 +++++- src/slic3r/GUI/PhysicalPrinterDialog.cpp | 45 +++++++++++++++++++++++- src/slic3r/GUI/PhysicalPrinterDialog.hpp | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 88c833187..c516d8bb9 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1111,6 +1111,10 @@ void Choice::set_value(const boost::any& value, bool change_event) } case coEnum: { int val = boost::any_cast(value); + if (m_opt_id.compare("host_type") == 0 && val != 0 && + m_opt.enum_values.size() > field->GetCount()) // for case, when PrusaLink isn't used as a HostType + val--; + if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern") { if (!m_opt.enum_values.empty()) { @@ -1178,7 +1182,7 @@ void Choice::set_values(const wxArrayString &values) auto ww = dynamic_cast(window); auto value = ww->GetValue(); ww->Clear(); - ww->Append(""); +// ww->Append(""); for (const auto &el : values) ww->Append(el); ww->SetValue(value); @@ -1201,6 +1205,10 @@ boost::any& Choice::get_value() if (m_opt.type == coEnum) { int ret_enum = field->GetSelection(); + if (m_opt_id.compare("host_type") == 0 && + m_opt.enum_values.size() > field->GetCount()) // for case, when PrusaLink isn't used as a HostType + ret_enum++; + if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern") { if (!m_opt.enum_values.empty()) { diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 6f0262980..9d609cdd7 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -466,6 +466,8 @@ void PhysicalPrinterDialog::update() m_optgroup->hide_field(opt_key); const auto opt = m_config->option>("host_type"); supports_multiple_printers = opt && opt->value == htRepetier; + + update_host_type(); } else { m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false); @@ -489,6 +491,44 @@ void PhysicalPrinterDialog::update() this->Layout(); } +void PhysicalPrinterDialog::update_host_type() +{ + bool all_presets_are_from_mk3_family = true; + + for (PresetForPrinter* preset : m_presets) { + std::string preset_name = preset->get_preset_name(); + if (Preset* preset = wxGetApp().preset_bundle->printers.find_preset(preset_name)) { + if (preset->vendor->name == "Prusa Research") { + const std::vector& models = preset->vendor->models; + std::string model_id = preset->config.opt_string("printer_model"); + auto it = std::find_if(models.begin(), models.end(), + [model_id](const VendorProfile::PrinterModel& model) { return model.id == model_id; }); + if (it != models.end() && it->family == "MK3") + continue; + } + } + all_presets_are_from_mk3_family = false; + break; + } + + Field* ht = m_optgroup->get_field("host_type"); + + wxArrayString types; + // Append localized enum_labels + assert(ht->m_opt.enum_labels.size() == ht->m_opt.enum_values.size()); + for (size_t i = 0; i < ht->m_opt.enum_labels.size(); i++) { + if (ht->m_opt.enum_values[i] == "prusalink" && !all_presets_are_from_mk3_family) + continue; + types.Add(_(ht->m_opt.enum_labels[i])); + } + + Choice* choice = dynamic_cast(ht); + int val = m_config->option("host_type")->getInt(); + choice->set_values(types); + val = m_config->option("host_type")->getInt(); + choice->set_value(m_config->option("host_type")->getInt()); +} + wxString PhysicalPrinterDialog::get_printer_name() { @@ -617,8 +657,9 @@ void PhysicalPrinterDialog::AddPreset(wxEvent& event) m_presets_sizer->Add(m_presets.back()->sizer(), 1, wxEXPAND | wxTOP, BORDER_W); update_full_printer_names(); - this->Fit(); + + update_host_type(); } void PhysicalPrinterDialog::DeletePreset(PresetForPrinter* preset_for_printer) @@ -645,6 +686,8 @@ void PhysicalPrinterDialog::DeletePreset(PresetForPrinter* preset_for_printer) this->Layout(); this->Fit(); + + update_host_type(); } void PhysicalPrinterDialog::selected_preset_changed(std::string preset_name) diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.hpp b/src/slic3r/GUI/PhysicalPrinterDialog.hpp index 0ce9c2720..8cee6a32e 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.hpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.hpp @@ -86,6 +86,7 @@ public: ~PhysicalPrinterDialog(); void update(); + void update_host_type(); void update_printhost_buttons(); void update_printers(); wxString get_printer_name(); From 246c5599163434c1da7aecbed3b55d41476bb48d Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 17 Jun 2021 10:46:00 +0200 Subject: [PATCH 3/3] prusalink: bug fixes of physical printer dialog, start print after upload, accept both OctoPrint and PrusaLink as validation string --- src/libslic3r/PrintConfig.cpp | 2 +- src/slic3r/GUI/PhysicalPrinterDialog.cpp | 76 ++++++++++++++---------- src/slic3r/GUI/PhysicalPrinterDialog.hpp | 7 ++- src/slic3r/Utils/OctoPrint.cpp | 2 +- src/slic3r/Utils/OctoPrint.hpp | 2 +- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index a05299618..a9761b6f7 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1554,7 +1554,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back("AstroBox"); def->enum_labels.push_back("Repetier"); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionEnum(/*htOctoPrint*/htPrusaLink)); + def->set_default_value(new ConfigOptionEnum(htOctoPrint)); def = this->add("only_retract_when_crossing_perimeters", coBool); def->label = L("Only retract when crossing perimeters"); diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 9d609cdd7..7ef013478 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -62,14 +62,13 @@ PresetForPrinter::PresetForPrinter(PhysicalPrinterDialog* parent, const std::str if (preset->name == edited_preset.name) preset = &edited_preset; - m_parent->selected_preset_changed(preset->name); - // if created physical printer doesn't have any settings, use the settings from the selected preset if (m_parent->get_printer()->has_empty_config()) { // update Print Host upload from the selected preset m_parent->get_printer()->update_from_preset(*preset); // update values in parent (PhysicalPrinterDialog) - m_parent->update(); + m_parent->update(true); + } // update PrinterTechnology if it was changed @@ -155,7 +154,8 @@ void PresetForPrinter::msw_rescale() PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent, wxString printer_name) : DPIDialog(parent, wxID_ANY, _L("Physical Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), - m_printer("", wxGetApp().preset_bundle->physical_printers.default_config()) + m_printer("", wxGetApp().preset_bundle->physical_printers.default_config()), + had_all_mk3(!printer_name.empty()) { SetFont(wxGetApp().normal_font()); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -451,7 +451,7 @@ void PhysicalPrinterDialog::update_printhost_buttons() m_printhost_browse_btn->Enable(host->has_auto_discovery()); } -void PhysicalPrinterDialog::update() +void PhysicalPrinterDialog::update(bool printer_change) { m_optgroup->reload_config(); @@ -459,15 +459,24 @@ void PhysicalPrinterDialog::update() // Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment) bool supports_multiple_printers = false; if (tech == ptFFF) { - m_optgroup->show_field("host_type"); - m_optgroup->hide_field("printhost_authorization_type"); - m_optgroup->show_field("printhost_apikey", true); - for (const std::string& opt_key : std::vector{ "printhost_user", "printhost_password" }) - m_optgroup->hide_field(opt_key); + update_host_type(printer_change); const auto opt = m_config->option>("host_type"); - supports_multiple_printers = opt && opt->value == htRepetier; - - update_host_type(); + m_optgroup->show_field("host_type"); + if (opt->value == htPrusaLink) + { + m_optgroup->show_field("printhost_authorization_type"); + AuthorizationType auth_type = m_config->option>("printhost_authorization_type")->value; + m_optgroup->show_field("printhost_apikey", auth_type == AuthorizationType::atKeyPassword); + for (const char* opt_key : { "printhost_user", "printhost_password" }) + m_optgroup->show_field(opt_key, auth_type == AuthorizationType::atUserPassword); + } else { + m_optgroup->hide_field("printhost_authorization_type"); + m_optgroup->show_field("printhost_apikey", true); + for (const std::string& opt_key : std::vector{ "printhost_user", "printhost_password" }) + m_optgroup->hide_field(opt_key); + supports_multiple_printers = opt && opt->value == htRepetier; + } + } else { m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false); @@ -491,21 +500,26 @@ void PhysicalPrinterDialog::update() this->Layout(); } -void PhysicalPrinterDialog::update_host_type() +void PhysicalPrinterDialog::update_host_type(bool printer_change) { + if (m_presets.empty()) + return; bool all_presets_are_from_mk3_family = true; - for (PresetForPrinter* preset : m_presets) { - std::string preset_name = preset->get_preset_name(); + for (PresetForPrinter* prstft : m_presets) { + std::string preset_name = prstft->get_preset_name(); if (Preset* preset = wxGetApp().preset_bundle->printers.find_preset(preset_name)) { - if (preset->vendor->name == "Prusa Research") { + std::string model_id = preset->config.opt_string("printer_model"); + if (preset->vendor && preset->vendor->name == "Prusa Research") { const std::vector& models = preset->vendor->models; - std::string model_id = preset->config.opt_string("printer_model"); auto it = std::find_if(models.begin(), models.end(), [model_id](const VendorProfile::PrinterModel& model) { return model.id == model_id; }); if (it != models.end() && it->family == "MK3") continue; + } else if (!preset->vendor && model_id.rfind("MK3", 0) == 0) { + continue; } + } all_presets_are_from_mk3_family = false; break; @@ -523,10 +537,18 @@ void PhysicalPrinterDialog::update_host_type() } Choice* choice = dynamic_cast(ht); - int val = m_config->option("host_type")->getInt(); choice->set_values(types); - val = m_config->option("host_type")->getInt(); - choice->set_value(m_config->option("host_type")->getInt()); + auto set_to_choice_and_config = [this, choice](PrintHostType type) { + choice->set_value(static_cast(type)); + m_config->set_key_value("host_type", new ConfigOptionEnum(type)); + }; + if ((printer_change && all_presets_are_from_mk3_family) || (!had_all_mk3 && all_presets_are_from_mk3_family)) + set_to_choice_and_config(htPrusaLink); + else if ((printer_change && !all_presets_are_from_mk3_family) || (!all_presets_are_from_mk3_family && m_config->option>("host_type")->value == htPrusaLink)) + set_to_choice_and_config(htOctoPrint); + else + choice->set_value(m_config->option("host_type")->getInt()); + had_all_mk3 = all_presets_are_from_mk3_family; } @@ -659,7 +681,7 @@ void PhysicalPrinterDialog::AddPreset(wxEvent& event) update_full_printer_names(); this->Fit(); - update_host_type(); + update_host_type(true); } void PhysicalPrinterDialog::DeletePreset(PresetForPrinter* preset_for_printer) @@ -687,15 +709,7 @@ void PhysicalPrinterDialog::DeletePreset(PresetForPrinter* preset_for_printer) this->Layout(); this->Fit(); - update_host_type(); -} - -void PhysicalPrinterDialog::selected_preset_changed(std::string preset_name) -{ - if (preset_name.rfind("Original Prusa i3 MK3", 0) == 0) - { - BOOST_LOG_TRIVIAL(debug) << "Original Prusa i3 MK3"; - } + update_host_type(true); } }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.hpp b/src/slic3r/GUI/PhysicalPrinterDialog.hpp index 8cee6a32e..cb9a48b3e 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.hpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.hpp @@ -85,8 +85,8 @@ public: PhysicalPrinterDialog(wxWindow* parent, wxString printer_name); ~PhysicalPrinterDialog(); - void update(); - void update_host_type(); + void update(bool printer_change = false); + void update_host_type(bool printer_change); void update_printhost_buttons(); void update_printers(); wxString get_printer_name(); @@ -96,10 +96,11 @@ public: PrinterTechnology get_printer_technology(); void DeletePreset(PresetForPrinter* preset_for_printer); - void selected_preset_changed(std::string preset_name); protected: void on_dpi_changed(const wxRect& suggested_rect) override; void on_sys_color_changed() override {}; + + bool had_all_mk3; }; diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index d23d83a00..f01e3ad41 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -238,7 +238,7 @@ wxString PrusaLink::get_test_failed_msg(wxString& msg) const bool PrusaLink::validate_version_text(const boost::optional& version_text) const { - return version_text ? boost::starts_with(*version_text, "PrusaLink") : false; + return version_text ? (boost::starts_with(*version_text, "PrusaLink") || boost::starts_with(*version_text, "OctoPrint")) : false; } void PrusaLink::set_auth(Http& http) const diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index 025fd3da5..c880819b8 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -80,7 +80,7 @@ public: wxString get_test_ok_msg() const override; wxString get_test_failed_msg(wxString& msg) const override; - bool can_start_print() const override { return false; } + bool can_start_print() const override { return true; } protected: bool validate_version_text(const boost::optional& version_text) const override;