From 79814a766248ef7fd805b196fec7ef2195517a52 Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Wed, 17 Aug 2022 16:29:47 +0800 Subject: [PATCH] ENH: support default filament for volumes Signed-off-by: yifan.wu Change-Id: I51cfb0e3a40578f94c6d20e85c12cda2b6bb2e74 --- src/slic3r/GUI/ExtraRenderers.cpp | 7 ++- src/slic3r/GUI/GUI_Factories.cpp | 4 +- src/slic3r/GUI/GUI_ObjectList.cpp | 21 ++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 3 + src/slic3r/GUI/ObjectDataViewModel.cpp | 43 +++++++------ src/slic3r/GUI/ObjectDataViewModel.hpp | 2 +- src/slic3r/GUI/wxExtensions.cpp | 85 ++++++++++++++++---------- src/slic3r/GUI/wxExtensions.hpp | 3 + 8 files changed, 106 insertions(+), 62 deletions(-) diff --git a/src/slic3r/GUI/ExtraRenderers.cpp b/src/slic3r/GUI/ExtraRenderers.cpp index 4931a71ea2..fd5206ddc3 100644 --- a/src/slic3r/GUI/ExtraRenderers.cpp +++ b/src/slic3r/GUI/ExtraRenderers.cpp @@ -313,11 +313,16 @@ 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 + int def_id = get_default_extruder_idx ? get_default_extruder_idx() : 0; + wxBitmap* default_icon = get_extruder_color_icon(def_id, true); + if (is_volume_selected()) + c_editor->Append("default", *default_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); + c_editor->SetSelection(atoi(data.GetText().c_str())); #ifdef __linux__ diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 9935afc1ef..30b6da13f7 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -689,7 +689,9 @@ void MenuFactory::append_menu_item_change_extruder(wxMenu* menu) initial_extruder = config.has("extruder") ? config.extruder() : 1; } - for (int i = 0; i <= filaments_cnt; i++) + ItemType sel_type = obj_list()->get_item_type(sels[0]); + int i = (sel_type & ItemType::itVolume) ? 0 : 1; + for (; i < filaments_cnt; i++) { bool is_active_extruder = i == initial_extruder; int icon_idx = i == 0 ? 0 : i - 1; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 1bb9ca0052..dbed51e3b7 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -587,6 +587,11 @@ ModelConfig& ObjectList::get_item_config(const wxDataViewItem& item) const (*m_objects)[obj_idx]->config; } +ItemType ObjectList::get_item_type(const wxDataViewItem& item) const +{ + return m_objects_model->GetItemType(item); +} + void ObjectList::update_filament_values_for_items(const size_t filaments_count) { for (size_t i = 0; i < m_objects->size(); ++i) @@ -1364,7 +1369,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; @@ -1841,8 +1846,7 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo ModelVolume* new_volume = model_object.add_volume(std::move(mesh), type); new_volume->name = boost::filesystem::path(input_file).filename().string(); // set a default extruder value, since user can't add it manually - // BBS - new_volume->config.set_key_value("extruder", new ConfigOptionInt(1)); + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); // update source data new_volume->source.input_file = input_file; new_volume->source.object_idx = obj_idx; @@ -1944,8 +1948,7 @@ 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 - new_volume->config.set_key_value("extruder", new ConfigOptionInt(1)); + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); new_volume->source.is_from_builtin_objects = true; select_item([this, obj_idx, new_volume]() { @@ -4718,7 +4721,7 @@ void ObjectList::ItemValueChanged(wxDataViewEvent &event) else if (event.GetColumn() == colFilament) { wxDataViewItem item = event.GetItem(); if (m_objects_model->GetItemType(item) == itObject) - m_objects_model->UpdateVolumesExtruderBitmap(item, true); + m_objects_model->UpdateVolumesExtruderBitmap(item); update_filament_in_config(item); } } @@ -4798,13 +4801,17 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) wxDataViewItem item = (sel_item_type & itInstance) ? m_objects_model->GetObject(item) : sel_item; ItemType type = m_objects_model->GetItemType(item); + // ignore extruder 0 for object + if ((sel_item_type & (itObject | itInstance)) && extruder == 0) + continue; + ModelConfig& config = get_item_config(item); if (config.has("extruder")) config.set("extruder", extruder); else config.set_key_value("extruder", new ConfigOptionInt(extruder)); - // for object, clear all its volume's extruder config + // BBS: for object, clear all its volume's extruder config if (type & itObject) { ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); for (ModelVolume* mv : node->m_model_object->volumes) { diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 0192983ff7..59a8db69a7 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -311,6 +311,9 @@ public: int get_selected_obj_idx() const; ModelConfig& get_item_config(const wxDataViewItem& item) const; + // BBS + ItemType get_item_type(const wxDataViewItem& item) const; + void changed_object(const int obj_idx = -1) const; void part_selection_changed(); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 73e2847898..6080e303fd 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -343,11 +343,16 @@ void ObjectDataViewModelNode::UpdateExtruderAndColorIcon(wxString extruder /*= " m_extruder = extruder; // update extruder // update color icon + bool as_default = false; size_t extruder_idx = atoi(extruder.c_str()); if (extruder_idx == 0) { - if (m_type & itObject); - else if (m_type & itVolume && m_volume_type == ModelVolumeType::MODEL_PART) { + if (m_type & itObject) { + // Do nothing + } + else if (m_type & itVolume) { + // m_volume_type should be MODEL_PART or PARAMETER_MODIFIER type extruder_idx = atoi(m_parent->GetExtruder().c_str()); + as_default = true; } else { m_extruder_bmp = wxNullBitmap; @@ -355,15 +360,8 @@ void ObjectDataViewModelNode::UpdateExtruderAndColorIcon(wxString extruder /*= " } } - if (extruder_idx > 0) --extruder_idx; - // Create the bitmap with color bars. - std::vector bmps = get_extruder_color_icons(false);// use wide icons - if (bmps.empty()) { - m_extruder_bmp = wxNullBitmap; - return; - } - - m_extruder_bmp = *bmps[extruder_idx >= bmps.size() ? 0 : extruder_idx]; + wxBitmap* bitmap = get_extruder_color_icon(extruder_idx, as_default); + m_extruder_bmp = bitmap ? *bitmap : wxNullBitmap; } // ***************************************************************************** @@ -549,7 +547,7 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent wxString extruder_str = extruder == 0 ? _(L("default")) : 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 @@ -1372,26 +1370,33 @@ void ObjectDataViewModel::UpdateItemNames() } // BBS: add use_obj_extruder -void ObjectDataViewModel::UpdateVolumesExtruderBitmap(wxDataViewItem obj_item, bool use_obj_extruder) +void ObjectDataViewModel::UpdateVolumesExtruderBitmap(wxDataViewItem obj_item) { if (!obj_item.IsOk() || GetItemType(obj_item) != itObject) return; ObjectDataViewModelNode* obj_node = static_cast(obj_item.GetID()); + ModelObject* mo = obj_node->m_model_object; for (auto child : obj_node->GetChildren()) - if (child->GetVolumeType() == ModelVolumeType::MODEL_PART) - child->UpdateExtruderAndColorIcon(use_obj_extruder ? obj_node->GetExtruder() : ""); + // BBS: also update PARAMETER_MODIFIER + if (child->GetVolumeType() == ModelVolumeType::MODEL_PART || child->GetVolumeType() == ModelVolumeType::PARAMETER_MODIFIER) { + int vol_idx = child->GetIdx(); + ModelVolume* mv = mo->volumes[vol_idx]; + const ConfigOption* opt = mv->config.option("extruder"); + int vol_extr = opt ? opt->getInt() : 0; + child->UpdateExtruderAndColorIcon(std::to_string(vol_extr)); + } } int ObjectDataViewModel::GetDefaultExtruderIdx(wxDataViewItem item) { ItemType type = GetItemType(item); if (type == itObject) - return 0; + return 1; - if (type == itVolume && GetVolumeType(item) == ModelVolumeType::MODEL_PART) { + if (type == itVolume && (GetVolumeType(item) == ModelVolumeType::MODEL_PART || GetVolumeType(item) == ModelVolumeType::PARAMETER_MODIFIER)) { wxDataViewItem obj_item = GetParent(item); int extruder_id = GetExtruderNumber(obj_item); - if (extruder_id > 0) extruder_id--; + //if (extruder_id > 0) extruder_id--; return extruder_id; } @@ -1582,7 +1587,7 @@ void ObjectDataViewModel::SetExtruder(const wxString& extruder, wxDataViewItem i node->UpdateExtruderAndColorIcon(extruder); if (node->GetType() == itObject) - UpdateVolumesExtruderBitmap(item, true); + UpdateVolumesExtruderBitmap(item); // BBS ItemChanged(item); diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp index 749edae4b4..a9101874f8 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.hpp +++ b/src/slic3r/GUI/ObjectDataViewModel.hpp @@ -449,7 +449,7 @@ public: bool UpdateColumValues(unsigned col); void UpdateExtruderBitmap(wxDataViewItem item); // BBS: add use_obj_extruder - void UpdateVolumesExtruderBitmap(wxDataViewItem object_item, bool use_obj_extruder = false); + void UpdateVolumesExtruderBitmap(wxDataViewItem object_item); int GetDefaultExtruderIdx(wxDataViewItem item); // BBS diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 8eb2d9d07e..8667807b12 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -462,16 +462,14 @@ wxBitmap create_scaled_bitmap( const std::string& bmp_name_in, return *bmp; } -std::vector get_extruder_color_icons(bool thin_icon/* = false*/) +wxBitmap* get_extruder_color_icon(int extruder_id, bool as_default, bool thin_icon/* = false*/) { static Slic3r::GUI::BitmapCache bmp_cache; - // Create the bitmap with color bars. - std::vector bmps; + bool dark_mode = Slic3r::GUI::wxGetApp().dark_mode(); std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); - - if (colors.empty()) - return bmps; + if (colors.empty() || extruder_id > colors.size()) + return nullptr; unsigned char rgb[3]; @@ -483,44 +481,65 @@ std::vector get_extruder_color_icons(bool thin_icon/* = false*/) 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(); - - int index = 0; wxClientDC cdc((wxWindow*)Slic3r::GUI::wxGetApp().mainframe); wxMemoryDC dc(&cdc); dc.SetFont(::Label::Body_12); + std::string color = colors[extruder_id - 1]; + auto cache_label = as_default ? "default" : std::to_string(extruder_id); + std::string bitmap_key = color + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width) + + "-i" + cache_label; + + auto disp_label = as_default ? _L("default") : std::to_string(extruder_id); + 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(color); + bitmap = bmp_cache.insert(bitmap_key, wxBitmap(icon_width, icon_height)); + dc.SelectObject(*bitmap); + dc.SetBackground(wxBrush(clr)); + dc.Clear(); + if (clr.Red() > 224 && clr.Blue() > 224 && clr.Green() > 224) { + dc.SetBrush(wxBrush(clr)); + dc.SetPen(*wxGREY_PEN); + dc.DrawRectangle(0, 0, icon_width, icon_height); + } + auto size = dc.GetTextExtent(disp_label); + dc.SetTextForeground(clr.GetLuminance() < 0.51 ? *wxWHITE : *wxBLACK); + dc.DrawText(disp_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*/) +{ + // Create the bitmap with color bars. + std::vector bmps; + int index = 0; + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); for (const std::string &color : colors) { - auto label = std::to_string(++index); - std::string bitmap_key = color + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width) - + "-i" + label; - - 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(color); - bitmap = bmp_cache.insert(bitmap_key, wxBitmap(icon_width, icon_height)); - dc.SelectObject(*bitmap); - dc.SetBackground(wxBrush(clr)); - dc.Clear(); - if (clr.Red() > 224 && clr.Blue() > 224 && clr.Green() > 224) { - dc.SetBrush(wxBrush(clr)); - dc.SetPen(*wxGREY_PEN); - dc.DrawRectangle(0, 0, icon_width, icon_height); - } - 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); - } + wxBitmap* bitmap = get_extruder_color_icon(++index, false, thin_icon); bmps.emplace_back(bitmap); } return bmps; } +bool is_volume_selected() +{ + Slic3r::GUI::ObjectList* obj_list = Slic3r::GUI::wxGetApp().obj_list(); + + wxDataViewItemArray sels; + obj_list->GetSelections(sels); + if (sels.IsEmpty()) + return false; + + return (obj_list->get_item_type(sels[0]) & Slic3r::GUI::ItemType::itVolume) != 0; +} void apply_extruder_selector(Slic3r::GUI::BitmapComboBox** ctrl, wxWindow* parent, diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 7545f9c934..5c423bb0af 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -64,7 +64,10 @@ 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 +// BBS +wxBitmap* get_extruder_color_icon(int extruder_id, bool as_default, bool thin_icon = false); std::vector get_extruder_color_icons(bool thin_icon = false); +bool is_volume_selected(); namespace Slic3r { namespace GUI {