From f02f24c4b78b9c6d52fbcf515793fccb437bc1b6 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 14 Mar 2019 13:15:04 +0100 Subject: [PATCH] Implemented set extruder number on multiple items at the same time (#1940) --- src/slic3r/GUI/GUI_ObjectList.cpp | 114 +++++++++++++++++++++++++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 4 ++ 2 files changed, 110 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 4757c95b9..f6ccbbd7d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -43,6 +43,18 @@ static PrinterTechnology printer_technology() return wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(); } +// Config from current edited printer preset +DynamicPrintConfig& printer_config() +{ + return wxGetApp().preset_bundle->printers.get_edited_preset().config; +} + +int extruders_count() +{ + return printer_technology() == ptSLA ? 1 : + printer_config().option<ConfigOptionFloats>("nozzle_diameter")->values.size(); +} + ObjectList::ObjectList(wxWindow* parent) : wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE), m_parent(parent) @@ -430,6 +442,9 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) if (is_windows10()) fix_through_netfabb(); } + else if (title == _("Extruder")) + show_extruder_selection_menu(); + #ifndef __WXMSW__ GetMainWindow()->SetToolTip(""); // hide tooltip #endif //__WXMSW__ @@ -437,9 +452,13 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) void ObjectList::show_context_menu() { - if (multiple_selection() && selected_instances_of_same_object()) + if (multiple_selection()) { - wxGetApp().plater()->PopupMenu(&m_menu_instance); + if (selected_instances_of_same_object()) + wxGetApp().plater()->PopupMenu(&m_menu_instance); + else + show_extruder_selection_menu(); + return; } @@ -644,8 +663,7 @@ void ObjectList::get_options_menu(settings_menu_hierarchy& settings_menu, const { auto options = get_options(is_part); - auto extruders_cnt = printer_technology() == ptSLA ? 1 : - wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter")->values.size(); + const int extruders_cnt = extruders_count(); DynamicPrintConfig config; for (auto& option : options) @@ -1079,8 +1097,7 @@ void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) const FreqSettingsBundle& bundle = printer_technology() == ptFFF ? FREQ_SETTINGS_BUNDLE_FFF : FREQ_SETTINGS_BUNDLE_SLA; - auto extruders_cnt = printer_technology() == ptSLA ? 1 : - wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter")->values.size(); + const int extruders_cnt = extruders_count(); for (auto& it : bundle) { if (it.first.empty() || it.first == "Extruders" && extruders_cnt == 1) @@ -1277,7 +1294,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode const wxString name = _(L("Generic")) + "-" + _(type_name); TriangleMesh mesh; - auto& bed_shape = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionPoints>("bed_shape")->values; + auto& bed_shape = printer_config().option<ConfigOptionPoints>("bed_shape")->values; const auto& sz = BoundingBoxf(bed_shape).size(); const auto side = 0.1 * std::max(sz(0), sz(1)); @@ -1456,7 +1473,7 @@ void ObjectList::split() ModelVolume* volume; if (!get_volume_by_item(item, volume)) return; - DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + DynamicPrintConfig& config = printer_config(); const ConfigOption *nozzle_dmtrs_opt = config.option("nozzle_diameter", false); const auto nozzle_dmrs_cnt = (nozzle_dmtrs_opt == nullptr) ? size_t(1) : dynamic_cast<const ConfigOptionFloats*>(nozzle_dmtrs_opt)->values.size(); if (volume->split(nozzle_dmrs_cnt) == 1) { @@ -2338,5 +2355,86 @@ void ObjectList::OnEditingDone(wxDataViewEvent &event) _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); } +void ObjectList::show_extruder_selection_menu() +{ + wxDataViewItemArray sels; + GetSelections(sels); + + for (const wxDataViewItem& item : sels) + if (!(m_objects_model->GetItemType(item) & (itVolume | itObject))) + // show this menu only for Object(s)/Volume(s) selection + return; + + wxMenu* menu = new wxMenu(); + append_menu_item(menu, wxID_ANY, _(L("Set extruder for selected items")), + _(L("Select extruder number for selected objects and/or parts")), + [this](wxCommandEvent&) { extruder_selection(); }, "", menu); + PopupMenu(menu); +} + +void ObjectList::extruder_selection() +{ + wxArrayString choices; + choices.Add("default"); + for (int i = 1; i <= extruders_count(); ++i) + choices.Add(wxString::Format("%d", i)); + + const wxString& selected_extruder = wxGetSingleChoice(_(L("Select extruder number:")), + _(L("This extruder will be set for selected items")), + choices, 0, this); + if (selected_extruder.IsEmpty()) + return; + + const int extruder_num = selected_extruder == "default" ? 0 : atoi(selected_extruder.c_str()); + +// /* Another variant for an extruder selection */ +// extruder_num = wxGetNumberFromUser(_(L("Attention!!! \n" +// "It's a possibile to set an extruder number \n" +// "for whole Object(s) and/or object Part(s), \n" +// "not for an Instance. ")), +// _(L("Enter extruder number:")), +// _(L("This extruder will be set for selected items")), +// 1, 1, 5, this); + + set_extruder_for_selected_items(extruder_num); +} + +void ObjectList::set_extruder_for_selected_items(const int extruder) const +{ + wxDataViewItemArray sels; + GetSelections(sels); + + for (const wxDataViewItem& item : sels) + { + const ItemType type = m_objects_model->GetItemType(item); + + const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) : + m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); + + const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1; + + DynamicPrintConfig& config = type & itObject ? (*m_objects)[obj_idx]->config : + (*m_objects)[obj_idx]->volumes[vol_idx]->config; + + if (config.has("extruder")) { + if (extruder == 0) + config.erase("extruder"); + else + config.option<ConfigOptionInt>("extruder")->value = extruder; + } + else if (extruder > 0) + config.set_key_value("extruder", new ConfigOptionInt(extruder)); + + const wxString extruder_str = extruder == 0 ? wxString ("default") : + wxString::Format("%d", config.option<ConfigOptionInt>("extruder")->value); + m_objects_model->SetValue(extruder_str, item, 1); + + wxGetApp().plater()->canvas3D()->ensure_on_bed(obj_idx); + } + + // update scene + wxGetApp().plater()->update(); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index a4df67497..fa4db8f9d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -283,6 +283,10 @@ private: void ItemValueChanged(wxDataViewEvent &event); void OnEditingDone(wxDataViewEvent &event); + void show_extruder_selection_menu(); + void extruder_selection(); + void set_extruder_for_selected_items(const int extruder) const ; + std::vector<std::string> get_options(const bool is_part); const std::vector<std::string>& get_options_for_bundle(const wxString& bundle_name); void get_options_menu(settings_menu_hierarchy& settings_menu, const bool is_part);