From 1a90c581c41b4d5cb35f6eece3aafbc55f2af97b Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Thu, 15 May 2025 13:49:03 +0800 Subject: [PATCH] FIX: paste all of object settings Change-Id: I32681190b20a2392069f6da5059feda070b312d1 Jira: STUDIO-12194 --- src/slic3r/GUI/GUI_Factories.cpp | 4 +-- src/slic3r/GUI/GUI_ObjectList.cpp | 53 +++++++++++++++++++++++++++++-- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index c1b7840a9..e59b3ec11 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -1865,9 +1865,7 @@ void MenuFactory::append_menu_item_per_object_process(wxMenu* menu) wxGetApp().obj_list()->paste_settings_into_list(); }, "", nullptr, []() { - Selection &selection = plater()->canvas3D()->get_selection(); - return selection.is_single_full_object() || selection.is_multiple_full_object() || selection.is_single_full_instance() || selection.is_multiple_full_instance() || - selection.is_single_volume() || selection.is_multiple_volume(); + return wxGetApp().obj_list()->can_paste_settings_into_list(); }, m_parent); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 58ace5dda..3a68f7bf3 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1222,7 +1222,31 @@ void ObjectList::copy_settings_to_clipboard() if (m_objects_model->GetItemType(item) & itSettings) item = m_objects_model->GetParent(item); - m_clipboard.get_config_cache() = get_item_config(item).get(); + wxDataViewItemArray items; + items.push_back(item); + while ((m_objects_model->GetItemType(items.back()) & itObject) == 0) { + if (m_objects_model->GetItemType(items.back()) & itLayerRoot) + items.back() = m_objects_model->GetParent(items.back()); + else + items.push_back(m_objects_model->GetParent(items.back())); + } + auto &config = m_clipboard.get_config_cache(); + config.clear(); + while (!items.empty()) { + config.apply(get_item_config(items.back()).get()); + items.pop_back(); + } + + m_clipboard.set_type(ItemType(m_objects_model->GetItemType(item) | itSettings)); +} + +bool GUI::ObjectList::can_paste_settings_into_list() +{ + wxDataViewItemArray sels; + GetSelections(sels); + if (sels.empty()) + return false; + return m_clipboard.get_type() == (m_objects_model->GetItemType(sels.front()) | itSettings); } void ObjectList::paste_settings_into_list() @@ -1231,6 +1255,8 @@ void ObjectList::paste_settings_into_list() GetSelections(sels); take_snapshot("Paste settings"); + std::unique_ptr global_keys; // need copy from global + for (auto item : sels) { if (m_objects_model->GetItemType(item) & itSettings) @@ -1246,6 +1272,25 @@ void ObjectList::paste_settings_into_list() auto keys = config_cache.keys(); auto part_options = SettingsFactory::get_options(true); auto config = &get_item_config(item); + auto extruder = config->option("extruder") ? config->option("extruder")->clone() : nullptr; + config->reset(); + + if (item_type & (itVolume | itLayer)) { + if (global_keys == nullptr) { + auto object = m_objects_model->GetParent(item); + DynamicPrintConfig config; + config.apply_only(*wxGetApp().get_tab(Preset::TYPE_PRINT)->get_config(), keys); + config.apply_only(get_item_config(object).get(), keys); + auto equals = config.equal(config_cache); + global_keys.reset(new t_config_option_keys); + auto keys2 = get_item_config(object).keys(); + std::copy_if(keys2.begin(), keys2.end(), std::back_inserter(*global_keys), + [&equals](auto &e) { return std::find(equals.begin(), equals.end(), e) == equals.end(); }); + keys.erase(std::remove_if(keys.begin(), keys.end(), + [&equals](auto &e) { return std::find(equals.begin(), equals.end(), e) != equals.end(); }), keys.end()); + } + config->apply_only(*wxGetApp().get_tab(Preset::TYPE_PRINT)->get_config(), *global_keys); + } for (const std::string& opt_key: keys) { if (item_type & (itVolume | itLayer) && @@ -1256,6 +1301,10 @@ void ObjectList::paste_settings_into_list() if (option) config->set_key_value(opt_key, option->clone()); } + if (extruder) + config->set_key_value("extruder", extruder); + else + config->erase("extruder"); // Add settings item for object/sub-object and show them add_settings_item(item, &config->get()); @@ -1613,7 +1662,7 @@ bool ObjectList::paste_from_clipboard() if (m_clipboard.get_type() & itSettings) paste_settings_into_list(); - if (m_clipboard.get_type() & (itLayer | itLayerRoot)) + else if (m_clipboard.get_type() & (itLayer | itLayerRoot)) paste_layers_into_list(); return true; diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index e78820974..0981b3267 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -437,6 +437,7 @@ public: void paste_layers_into_list(); void copy_settings_to_clipboard(); void paste_settings_into_list(); + bool can_paste_settings_into_list(); bool clipboard_is_empty() const { return m_clipboard.empty(); } void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes); void paste_objects_into_list(const std::vector& object_idxs);