From 05a00edb7984a2799d3fc670d5596c08cb27c90a Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Sat, 19 Nov 2022 22:08:27 +0800 Subject: [PATCH] ENH: support default filament for modifier 1. set modifier's initial filament index to "default" (0) 2. allow to change modifier's filament index to "default" Change-Id: I66e546e20fa5492532dd8733df5b0d38a92fd4d7 Signed-off-by: yifan.wu --- src/slic3r/GUI/ExtraRenderers.cpp | 11 ++++++-- src/slic3r/GUI/ExtraRenderers.hpp | 2 ++ src/slic3r/GUI/GUI_Factories.cpp | 24 ++++++++++++---- src/slic3r/GUI/GUI_ObjectList.cpp | 14 ++++++---- src/slic3r/GUI/ObjectDataViewModel.cpp | 21 ++++++++++++-- src/slic3r/GUI/wxExtensions.cpp | 38 ++++++++++++++++++++++++++ src/slic3r/GUI/wxExtensions.hpp | 1 + 7 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/ExtraRenderers.cpp b/src/slic3r/GUI/ExtraRenderers.cpp index 4931a71ea..7f77c0a4c 100644 --- a/src/slic3r/GUI/ExtraRenderers.cpp +++ b/src/slic3r/GUI/ExtraRenderers.cpp @@ -313,13 +313,18 @@ wxWindow* BitmapChoiceRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelR labelRect.GetTopLeft(), wxSize(labelRect.GetWidth(), -1), 0, nullptr, wxCB_READONLY | CB_NO_DROP_ICON | CB_NO_TEXT); c_editor->GetDropDown().SetUseContentWidth(true); - // BBS + + if (has_default_extruder && has_default_extruder()) + c_editor->Append(_L("default"), *get_default_extruder_color_icon()); + for (size_t i = 0; i < icons.size(); i++) c_editor->Append(wxString::Format("%d", i+1), *icons[i]); - c_editor->SetSelection(atoi(data.GetText().c_str()) - 1); + if (has_default_extruder && has_default_extruder()) + c_editor->SetSelection(atoi(data.GetText().c_str())); + else + c_editor->SetSelection(atoi(data.GetText().c_str()) - 1); - #ifdef __linux__ c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { // to avoid event propagation to other sidebar items diff --git a/src/slic3r/GUI/ExtraRenderers.hpp b/src/slic3r/GUI/ExtraRenderers.hpp index 432e31deb..ef16ddece 100644 --- a/src/slic3r/GUI/ExtraRenderers.hpp +++ b/src/slic3r/GUI/ExtraRenderers.hpp @@ -153,11 +153,13 @@ public: void set_can_create_editor_ctrl_function(std::function can_create_fn) { can_create_editor_ctrl = can_create_fn; } void set_default_extruder_idx(std::function default_extruder_idx_fn) { get_default_extruder_idx = default_extruder_idx_fn; } + void set_has_default_extruder(std::function has_default_extruder_fn) { has_default_extruder = has_default_extruder_fn; } private: DataViewBitmapText m_value; std::function can_create_editor_ctrl { nullptr }; std::function get_default_extruder_idx{ nullptr }; + std::function has_default_extruder{ nullptr }; }; diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index e661bf14c..54b403d00 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -1436,22 +1436,34 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu) int initial_extruder = -1; // negative value for multiple object/part selection if (sels.Count() == 1) { const ModelConfig& config = obj_list()->get_item_config(sels[0]); - // BBS: set default extruder to 1 - initial_extruder = config.has("extruder") ? config.extruder() : 1; + // BBS + const auto sel_vol = obj_list()->get_selected_model_volume(); + if (sel_vol && sel_vol->type() == ModelVolumeType::PARAMETER_MODIFIER) + initial_extruder = config.has("extruder") ? config.extruder() : 0; + else + initial_extruder = config.has("extruder") ? config.extruder() : 1; } - for (int i = 1; i <= filaments_cnt; i++) + // BBS + bool has_modifier = false; + for (auto sel : sels) { + if (obj_list()->GetModel()->GetVolumeType(sel) == ModelVolumeType::PARAMETER_MODIFIER) { + has_modifier = true; + break; + } + } + + for (int i = has_modifier ? 0 : 1; i <= filaments_cnt; i++) { // BBS //bool is_active_extruder = i == initial_extruder; bool is_active_extruder = false; - int icon_idx = i == 0 ? 0 : i - 1; - const wxString& item_name = wxString::Format(_L("Filament %d"), i) + + const wxString& item_name = (i == 0 ? _L("Default") : wxString::Format(_L("Filament %d"), i)) + (is_active_extruder ? " (" + _L("current") + ")" : ""); append_menu_item(extruder_selection_menu, wxID_ANY, item_name, "", - [i](wxCommandEvent&) { obj_list()->set_extruder_for_selected_items(i); }, *icons[icon_idx], menu, + [i](wxCommandEvent&) { obj_list()->set_extruder_for_selected_items(i); }, i == 0 ? wxNullBitmap : *icons[i - 1], menu, [is_active_extruder]() { return !is_active_extruder; }, m_parent); } menu->Append(wxID_ANY, name, extruder_selection_menu, _L("Change Filament")); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 02c4f91ef..5719dbfa8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -354,6 +354,9 @@ void ObjectList::create_objects_ctrl() bmp_choice_renderer->set_default_extruder_idx([this]() { return m_objects_model->GetDefaultExtruderIdx(GetSelection()); }); + bmp_choice_renderer->set_has_default_extruder([this]() { + return m_objects_model->GetVolumeType(GetSelection()) == ModelVolumeType::PARAMETER_MODIFIER; + }); AppendColumn(new wxDataViewColumn(_L("Fila."), bmp_choice_renderer, colFilament, m_columns_width[colFilament] * em, wxALIGN_CENTER_HORIZONTAL, 0)); @@ -1367,7 +1370,7 @@ void ObjectList::key_event(wxKeyEvent& event) //else if (event.GetUnicodeKey() == 'p') // toggle_printable_state(); else if (filaments_count() > 1) { - std::vector numbers = { '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + std::vector numbers = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; wxChar key_char = event.GetUnicodeKey(); if (std::find(numbers.begin(), numbers.end(), key_char) != numbers.end()) { long extruder_number; @@ -1846,7 +1849,7 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo // set a default extruder value, since user can't add it manually // BBS int extruder_id = 0; - if (model_object.config.has("extruder")) + if (new_volume->type() == ModelVolumeType::MODEL_PART && model_object.config.has("extruder")) extruder_id = model_object.config.opt_int("extruder"); new_volume->config.set_key_value("extruder", new ConfigOptionInt(extruder_id)); // update source data @@ -1949,10 +1952,11 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode const wxString name = _L("Generic") + "-" + _(type_name); new_volume->name = into_u8(name); + // set a default extruder value, since user can't add it manually // BBS int extruder_id = 0; - if (model_object.config.has("extruder")) + if (new_volume->type() == ModelVolumeType::MODEL_PART && model_object.config.has("extruder")) extruder_id = model_object.config.opt_int("extruder"); new_volume->config.set_key_value("extruder", new ConfigOptionInt(extruder_id)); new_volume->source.is_from_builtin_objects = true; @@ -4844,11 +4848,11 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) else config.set_key_value("extruder", new ConfigOptionInt(extruder)); - // for object, clear all its volume's extruder config + // for object, clear all its part volume's extruder config if (type & itObject) { ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); for (ModelVolume* mv : node->m_model_object->volumes) { - if (mv->config.has("extruder")) + if (mv->type() == ModelVolumeType::MODEL_PART && mv->config.has("extruder")) mv->config.erase("extruder"); } } diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 5300f5238..0debef4b6 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -349,6 +349,11 @@ void ObjectDataViewModelNode::UpdateExtruderAndColorIcon(wxString extruder /*= " else if (m_type & itVolume && m_volume_type == ModelVolumeType::MODEL_PART) { extruder_idx = atoi(m_parent->GetExtruder().c_str()); } + // BBS + else if (m_type & itVolume && m_volume_type == ModelVolumeType::PARAMETER_MODIFIER) { + m_extruder_bmp = *get_default_extruder_color_icon(); + return; + } else { m_extruder_bmp = wxNullBitmap; return; @@ -546,10 +551,20 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent if (insert_position >= 0) insert_position++; } - wxString extruder_str = extruder == 0 ? _(L("default")) : wxString::Format("%d", extruder); + // BBS + wxString extruder_str; + if (extruder == 0) { + if (volume_type == ModelVolumeType::PARAMETER_MODIFIER) + extruder_str = _L("default"); + else + extruder_str = root->m_extruder; + } + else { + extruder_str = wxString::Format("%d", extruder); + } const auto node = new ObjectDataViewModelNode(root, name, volume_type, GetVolumeIcon(volume_type, warning_icon_name), - extruder == 0 ? root->m_extruder : extruder_str, root->m_volumes_cnt, warning_icon_name); + extruder_str, root->m_volumes_cnt, warning_icon_name); insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position); // if part with errors is added, but object wasn't marked, then mark it @@ -1378,7 +1393,7 @@ void ObjectDataViewModel::UpdateVolumesExtruderBitmap(wxDataViewItem obj_item, b return; ObjectDataViewModelNode* obj_node = static_cast(obj_item.GetID()); for (auto child : obj_node->GetChildren()) - if (child->GetVolumeType() == ModelVolumeType::MODEL_PART || child->GetVolumeType() == ModelVolumeType::PARAMETER_MODIFIER) + if (child->GetVolumeType() == ModelVolumeType::MODEL_PART) child->UpdateExtruderAndColorIcon(use_obj_extruder ? obj_node->GetExtruder() : ""); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 8eb2d9d07..406698f21 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -462,6 +462,44 @@ wxBitmap create_scaled_bitmap( const std::string& bmp_name_in, return *bmp; } +wxBitmap* get_default_extruder_color_icon(bool thin_icon/* = false*/) +{ + static Slic3r::GUI::BitmapCache bmp_cache; + + const double em = Slic3r::GUI::wxGetApp().em_unit(); + const int icon_width = lround((thin_icon ? 2 : 4.5) * em); + const int icon_height = lround(2 * em); + bool dark_mode = Slic3r::GUI::wxGetApp().dark_mode(); + + wxClientDC cdc((wxWindow*)Slic3r::GUI::wxGetApp().mainframe); + wxMemoryDC dc(&cdc); + dc.SetFont(::Label::Body_12); + + wxString label = _L("default"); + std::string bitmap_key = std::string("default_color") + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width) + + "-i" + label.ToStdString(); + + wxBitmap* bitmap = bmp_cache.find(bitmap_key); + if (bitmap == nullptr) { + // Paint the color icon. + //Slic3r::GUI::BitmapCache::parse_color(color, rgb); + // there is no neede to scale created solid bitmap + wxColor clr(255, 255, 255, 0); + bitmap = bmp_cache.insert(bitmap_key, wxBitmap(icon_width, icon_height)); + dc.SelectObject(*bitmap); + dc.SetBackground(wxBrush(clr)); + dc.Clear(); + dc.SetBrush(wxBrush(clr)); + dc.SetPen(*wxGREY_PEN); + auto size = dc.GetTextExtent(wxString(label)); + dc.SetTextForeground(clr.GetLuminance() < 0.51 ? *wxWHITE : *wxBLACK); + dc.DrawText(label, (icon_width - size.x) / 2, (icon_height - size.y) / 2); + dc.SelectObject(wxNullBitmap); + } + + return bitmap; +} + std::vector get_extruder_color_icons(bool thin_icon/* = false*/) { static Slic3r::GUI::BitmapCache bmp_cache; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 7545f9c93..1a9ebf607 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -64,6 +64,7 @@ wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullp const int px_cnt = 16, const bool grayscale = false, const bool resize = false); #endif +wxBitmap* get_default_extruder_color_icon(bool thin_icon = false); std::vector get_extruder_color_icons(bool thin_icon = false); namespace Slic3r {