From dd70dd6e101dcadec70e0bd2e6ae7069ec5f3ad5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 27 May 2019 13:07:37 +0200 Subject: Implemented LayerItem for ObjectList --- src/slic3r/GUI/GUI_ObjectList.cpp | 28 +++++++- src/slic3r/GUI/GUI_ObjectList.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 4 ++ src/slic3r/GUI/wxExtensions.cpp | 142 ++++++++++++++++++++++++++++++-------- src/slic3r/GUI/wxExtensions.hpp | 18 +++-- 5 files changed, 156 insertions(+), 40 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dffa02e95..5e14459e2 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1137,6 +1137,12 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu) [this]() { return is_splittable(); }, wxGetApp().plater()); } +wxMenuItem* ObjectList::append_menu_item_layers_editing(wxMenu* menu) +{ + return append_menu_item(menu, wxID_ANY, _(L("Edit Layers")), "", + [this](wxCommandEvent&) { layers_editing(); }, "table.png", menu); +} + wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) { MenuWithSeparators* menu = dynamic_cast(menu_); @@ -1301,7 +1307,11 @@ void ObjectList::create_object_popupmenu(wxMenu *menu) append_menu_item_scale_selection_to_fit_print_volume(menu); // Split object to parts - m_menu_item_split = append_menu_item_split(menu); + append_menu_item_split(menu); + menu->AppendSeparator(); + + // Layers Editing for object + append_menu_item_layers_editing(menu); menu->AppendSeparator(); // rest of a object_menu will be added later in: @@ -1330,7 +1340,7 @@ void ObjectList::create_part_popupmenu(wxMenu *menu) append_menu_item_fix_through_netfabb(menu); append_menu_item_export_stl(menu); - m_menu_item_split_part = append_menu_item_split(menu); + append_menu_item_split(menu); // Append change part type menu->AppendSeparator(); @@ -1774,6 +1784,20 @@ void ObjectList::split() changed_object(obj_idx); } +void ObjectList::layers_editing() +{ + const auto item = GetSelection(); + const int obj_idx = get_selected_obj_idx(); + if (!item || obj_idx < 0) + return; + + wxDataViewItem layers_item = m_objects_model->GetItemByType(item, itLayerRoot); + if (!layers_item.IsOk()) + layers_item = m_objects_model->AddLayersRoot(item); + + select_item(layers_item); +} + bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume) { auto obj_idx = get_selected_obj_idx(); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 166606e2e..076ab5f13 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -119,8 +119,6 @@ class ObjectList : public wxDataViewCtrl MenuWithSeparators m_menu_part; MenuWithSeparators m_menu_sla_object; MenuWithSeparators m_menu_instance; - wxMenuItem* m_menu_item_split { nullptr }; - wxMenuItem* m_menu_item_split_part { nullptr }; wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr }; @@ -199,6 +197,7 @@ public: wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type); void append_menu_items_add_volume(wxMenu* menu); wxMenuItem* append_menu_item_split(wxMenu* menu); + wxMenuItem* append_menu_item_layers_editing(wxMenu* menu); wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent); @@ -226,6 +225,7 @@ public: void del_instances_from_object(const int obj_idx); bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void split(); + void layers_editing(); bool get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); bool is_splittable(); bool selected_instances_of_same_object(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 64c698a9b..c0f267204 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3066,6 +3066,10 @@ bool Plater::priv::complit_init_object_menu() [this]() { return can_split() && wxGetApp().get_mode() > comSimple; }, q); object_menu.AppendSeparator(); + // Layers Editing for object + sidebar->obj_list()->append_menu_item_layers_editing(&object_menu); + object_menu.AppendSeparator(); + // "Add (volumes)" popupmenu will be added later in append_menu_items_add_volume() return true; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 76ba853dc..988d4a8ea 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -437,27 +437,44 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_type(type), m_extruder(wxEmptyString) { - if (type == itSettings) { + if (type == itSettings) m_name = "Settings to modified"; - } - else if (type == itInstanceRoot) { + else if (type == itInstanceRoot) m_name = _(L("Instances")); -#ifdef __WXGTK__ - m_container = true; -#endif //__WXGTK__ - } - else if (type == itInstance) { + else if (type == itInstance) + { m_idx = parent->GetChildCount(); m_name = wxString::Format(_(L("Instance %d")), m_idx + 1); set_action_icon(); } + else if (type == itLayerRoot) + { + m_bmp = create_scaled_bitmap(nullptr, "table.png"); // FIXME: pass window ptr + m_name = _(L("Layers")); + } + else if (type == itLayer) + { + m_idx = parent->GetChildCount(); + m_name = wxString::Format(_(L("Layer %d")), m_idx + 1); + m_bmp = create_scaled_bitmap(nullptr, "row.png"); // FIXME: pass window ptr + + set_action_icon(); + } + +#ifdef __WXGTK__ + // it's necessary on GTK because of control have to know if this item will be container + // in another case you couldn't to add subitem for this item + // it will be produce "segmentation fault" + if (type & (itInstanceRoot | itLayerRoot | itLayer)) + m_container = true; +#endif //__WXGTK__ } void ObjectDataViewModelNode::set_action_icon() { - m_action_icon_name = m_type == itObject ? "advanced_plus" : - m_type == itVolume ? "cog" : "set_separate_obj"; + m_action_icon_name = m_type & itObject ? "advanced_plus" : + m_type & (itVolume | itLayer) ? "cog" : /*m_type & itInstance*/ "set_separate_obj"; m_action_icon = create_scaled_bitmap(nullptr, m_action_icon_name); // FIXME: pass window ptr } @@ -619,36 +636,62 @@ wxDataViewItem ObjectDataViewModel::AddSettingsChild(const wxDataViewItem &paren return child; } -int get_istances_root_idx(ObjectDataViewModelNode *parent_node) +static int get_root_idx(ObjectDataViewModelNode *parent_node, const ItemType root_type) { - // because of istance_root is a last item of the object - const int inst_root_idx = parent_node->GetChildCount()-1; + // because of istance_root and layers_root are at the end of the list, so + // start locking from the end + for (int root_idx = parent_node->GetChildCount() - 1; root_idx >= 0; root_idx--) + { + // if there is SettingsItem or VolumeItem, then RootItems don't exist in current ObjectItem + if (parent_node->GetNthChild(root_idx)->GetType() & (itSettings | itVolume)) + break; + if (parent_node->GetNthChild(root_idx)->GetType() & root_type) + return root_idx; + } - if (inst_root_idx < 0 || parent_node->GetNthChild(inst_root_idx)->GetType() == itInstanceRoot) - return inst_root_idx; - return -1; } +/* return values: + * true => root_node is created and added to the parent_root + * false => root node alredy exists +*/ +static bool append_root_node(ObjectDataViewModelNode *parent_node, + ObjectDataViewModelNode **root_node, + const ItemType root_type) +{ + const int inst_root_id = get_root_idx(parent_node, root_type); + + *root_node = inst_root_id < 0 ? + new ObjectDataViewModelNode(parent_node, root_type) : + parent_node->GetNthChild(inst_root_id); + + if (inst_root_id < 0) { + if ((root_type&itInstanceRoot) || + (root_type&itLayerRoot) && get_root_idx(parent_node, itInstanceRoot)<0) + parent_node->Append(*root_node); + else if (root_type&itLayerRoot) + parent_node->Insert(*root_node, unsigned int(get_root_idx(parent_node, itInstanceRoot))); + return true; + } + + return false; +} + wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); - // Check and create/get instances root node - const int inst_root_id = get_istances_root_idx(parent_node); + // get InstanceRoot node + ObjectDataViewModelNode *inst_root_node { nullptr }; - ObjectDataViewModelNode *inst_root_node = inst_root_id < 0 ? - new ObjectDataViewModelNode(parent_node, itInstanceRoot) : - parent_node->GetNthChild(inst_root_id); + const bool appended = append_root_node(parent_node, &inst_root_node, itInstanceRoot); const wxDataViewItem inst_root_item((void*)inst_root_node); + if (!inst_root_node) return wxDataViewItem(0); - if (inst_root_id < 0) { - parent_node->Append(inst_root_node); - // notify control - ItemAdded(parent_item, inst_root_item); -// if (num == 1) num++; - } + if (appended) + ItemAdded(parent_item, inst_root_item);// notify control // Add instance nodes ObjectDataViewModelNode *instance_node = nullptr; @@ -665,6 +708,47 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &paren return wxDataViewItem((void*)instance_node); } +wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_item) +{ + ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); + if (!parent_node) return wxDataViewItem(0); + + // get LayerRoot node + ObjectDataViewModelNode *layer_root_node{ nullptr }; + const bool appended = append_root_node(parent_node, &layer_root_node, itLayerRoot); + if (!layer_root_node) return wxDataViewItem(0); + + const wxDataViewItem layer_root_item((void*)layer_root_node); + + if (appended) + ItemAdded(parent_item, layer_root_item);// notify control + + return wxDataViewItem((void*)layer_root_item); +} + +wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item) +{ + ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); + if (!parent_node) return wxDataViewItem(0); + + // get LayerRoot node + const int root_idx = get_root_idx(parent_node, itLayerRoot); + if (root_idx < 0) return wxDataViewItem(0); + ObjectDataViewModelNode *layer_root_node = parent_node->GetNthChild(root_idx); + + const wxDataViewItem layer_root_item((void*)layer_root_node); + + // Add layer node + ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, itLayer); + layer_root_node->Append(layer_node); + + // notify control + const wxDataViewItem instance_item((void*)layer_node); + ItemAdded(layer_root_item, instance_item); + + return wxDataViewItem((void*)layer_node); +} + wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) { auto ret_item = wxDataViewItem(0); @@ -817,7 +901,7 @@ wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &par ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return ret_item; - const int inst_root_id = get_istances_root_idx(parent_node); + const int inst_root_id = get_root_idx(parent_node, itInstanceRoot); if (inst_root_id < 0) return ret_item; wxDataViewItemArray items; @@ -2573,7 +2657,7 @@ ModeSizer::ModeSizer(wxWindow *parent, int hgap/* = 10*/) : m_mode_btns.push_back(new ModeButton(parent, wxID_ANY, button.second, button.first));; #endif // __WXOSX__ - m_mode_btns.back()->Bind(wxEVT_BUTTON, std::bind(modebtnfn, std::placeholders::_1, m_mode_btns.size() - 1)); + m_mode_btns.back()->Bind(wxEVT_BUTTON, std::bind(modebtnfn, std::placeholders::_1, int(m_mode_btns.size() - 1))); Add(m_mode_btns.back()); } } diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 78fb7be55..424f7832a 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -159,12 +159,14 @@ DECLARE_VARIANT_OBJECT(DataViewBitmapText) // ---------------------------------------------------------------------------- enum ItemType { - itUndef = 0, - itObject = 1, - itVolume = 2, - itInstanceRoot = 4, - itInstance = 8, - itSettings = 16 + itUndef = 0, + itObject = 1, + itVolume = 2, + itInstanceRoot = 4, + itInstance = 8, + itSettings = 16, + itLayerRoot = 32, + itLayer = 64, }; class ObjectDataViewModelNode; @@ -348,7 +350,7 @@ public: } // Set action icons for node - void set_action_icon(); + void set_action_icon(); void update_settings_digest_bitmaps(); bool update_settings_digest(const std::vector& categories); @@ -388,6 +390,8 @@ public: const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); + wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); + wxDataViewItem AddLayersChild(const wxDataViewItem &parent_item); wxDataViewItem Delete(const wxDataViewItem &item); wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); void DeleteAll(); -- cgit v1.2.3 From 9d19e3d2a72742fd3398174b01be7e1ad583407b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 27 May 2019 16:13:24 +0200 Subject: Improved Delete() Add() ans Select() functions for Layer(s)Item --- src/slic3r/GUI/GUI_ObjectList.cpp | 19 ++++++--- src/slic3r/GUI/wxExtensions.cpp | 84 +++++++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 36 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 5e14459e2..e180f1dfc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1648,6 +1648,8 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) del_settings_from_config(); else if (type == itInstanceRoot && obj_idx != -1) del_instances_from_object(obj_idx); + else if ((type & itLayerRoot) && obj_idx != -1) + /*del_layers_from_object(obj_idx)*/; else if (idx == -1) return; else if (!del_subobject_from_object(obj_idx, idx, type)) @@ -1728,6 +1730,8 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con } object->delete_instance(idx); } + else if (type == itLayer) { + } else return false; @@ -1791,9 +1795,11 @@ void ObjectList::layers_editing() if (!item || obj_idx < 0) return; - wxDataViewItem layers_item = m_objects_model->GetItemByType(item, itLayerRoot); + wxDataViewItem obj_item = m_objects_model->GetTopParent(item); + + wxDataViewItem layers_item = m_objects_model->GetItemByType(obj_item, itLayerRoot); if (!layers_item.IsOk()) - layers_item = m_objects_model->AddLayersRoot(item); + layers_item = m_objects_model->AddLayersRoot(obj_item); select_item(layers_item); } @@ -2171,7 +2177,8 @@ void ObjectList::update_selections() m_selection_mode = smInstance; // We doesn't update selection if SettingsItem for the current object/part is selected - if (GetSelectedItemsCount() == 1 && m_objects_model->GetItemType(GetSelection()) == itSettings ) +// if (GetSelectedItemsCount() == 1 && m_objects_model->GetItemType(GetSelection()) == itSettings ) + if (GetSelectedItemsCount() == 1 && m_objects_model->GetItemType(GetSelection()) & (itSettings | itLayerRoot | itLayer)) { const auto item = GetSelection(); if (selection.is_single_full_object() && @@ -2294,8 +2301,8 @@ void ObjectList::update_selections_on_canvas() auto add_to_selection = [this](const wxDataViewItem& item, Selection& selection, int instance_idx, bool as_single_selection) { const ItemType& type = m_objects_model->GetItemType(item); - if ( type == itInstanceRoot || m_objects_model->GetParent(item) == wxDataViewItem(0) ) { - wxDataViewItem obj_item = type == itInstanceRoot ? m_objects_model->GetParent(item) : item; + if ( type == itLayerRoot || m_objects_model->GetParent(item) == wxDataViewItem(0) ) { + wxDataViewItem obj_item = type == itLayerRoot ? m_objects_model->GetParent(item) : item; selection.add_object(m_objects_model->GetIdByItem(obj_item), as_single_selection); return; } @@ -2317,7 +2324,7 @@ void ObjectList::update_selections_on_canvas() if (sel_cnt == 1) { wxDataViewItem item = GetSelection(); - if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot)) + if (m_objects_model->GetItemType(item) & (itSettings | itInstanceRoot | itLayerRoot | itLayer)) add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, true); else add_to_selection(item, selection, instance_idx, true); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 988d4a8ea..7849f66dd 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -540,6 +540,22 @@ void ObjectDataViewModelNode::SetIdx(const int& idx) // ObjectDataViewModel // ---------------------------------------------------------------------------- +static int get_root_idx(ObjectDataViewModelNode *parent_node, const ItemType root_type) +{ + // because of istance_root and layers_root are at the end of the list, so + // start locking from the end + for (int root_idx = parent_node->GetChildCount() - 1; root_idx >= 0; root_idx--) + { + // if there is SettingsItem or VolumeItem, then RootItems don't exist in current ObjectItem + if (parent_node->GetNthChild(root_idx)->GetType() & (itSettings | itVolume)) + break; + if (parent_node->GetNthChild(root_idx)->GetType() & root_type) + return root_idx; + } + + return -1; +} + ObjectDataViewModel::ObjectDataViewModel() { m_bitmap_cache = new Slic3r::GUI::BitmapCache; @@ -584,10 +600,10 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent wxString extruder_str = extruder == 0 ? _(L("default")) : wxString::Format("%d", extruder); - // because of istance_root is a last item of the object - int insert_position = root->GetChildCount() - 1; - if (insert_position < 0 || root->GetNthChild(insert_position)->m_type != itInstanceRoot) - insert_position = -1; + // get insertion position according to the existed Layers and/or Instances Items + int insert_position = get_root_idx(root, itLayerRoot); + if (insert_position < 0) + insert_position = get_root_idx(root, itInstanceRoot); const bool obj_errors = root->m_bmp.IsOk(); @@ -603,7 +619,7 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent ItemAdded(parent_item, child); root->m_volumes_cnt++; - if (insert_position > 0) insert_position++; + if (insert_position >= 0) insert_position++; } const auto node = new ObjectDataViewModelNode(root, name, GetVolumeIcon(volume_type, has_errors), extruder_str, root->m_volumes_cnt); @@ -636,22 +652,6 @@ wxDataViewItem ObjectDataViewModel::AddSettingsChild(const wxDataViewItem &paren return child; } -static int get_root_idx(ObjectDataViewModelNode *parent_node, const ItemType root_type) -{ - // because of istance_root and layers_root are at the end of the list, so - // start locking from the end - for (int root_idx = parent_node->GetChildCount() - 1; root_idx >= 0; root_idx--) - { - // if there is SettingsItem or VolumeItem, then RootItems don't exist in current ObjectItem - if (parent_node->GetNthChild(root_idx)->GetType() & (itSettings | itVolume)) - break; - if (parent_node->GetNthChild(root_idx)->GetType() & root_type) - return root_idx; - } - - return -1; -} - /* return values: * true => root_node is created and added to the parent_root * false => root node alredy exists @@ -723,6 +723,8 @@ wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_i if (appended) ItemAdded(parent_item, layer_root_item);// notify control + AddLayersChild(layer_root_item); + return wxDataViewItem((void*)layer_root_item); } @@ -732,9 +734,15 @@ wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_ if (!parent_node) return wxDataViewItem(0); // get LayerRoot node - const int root_idx = get_root_idx(parent_node, itLayerRoot); - if (root_idx < 0) return wxDataViewItem(0); - ObjectDataViewModelNode *layer_root_node = parent_node->GetNthChild(root_idx); + ObjectDataViewModelNode *layer_root_node; + + if (parent_node->GetType() & itLayerRoot) + layer_root_node = parent_node; + else { + const int root_idx = get_root_idx(parent_node, itLayerRoot); + if (root_idx < 0) return wxDataViewItem(0); + layer_root_node = parent_node->GetNthChild(root_idx); + } const wxDataViewItem layer_root_item((void*)layer_root_node); @@ -763,9 +771,9 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ // thus removing the node from it doesn't result in freeing it if (node_parent) { - if (node->m_type == itInstanceRoot) + if (node->m_type & (itInstanceRoot|itLayerRoot)) { - for (int i = node->GetChildCount() - 1; i > 0; i--) + for (int i = node->GetChildCount() - 1; i >= (node->m_type & itInstanceRoot ? 1 : 0); i--) Delete(wxDataViewItem(node->GetNthChild(i))); return parent; } @@ -774,7 +782,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) auto idx = node->GetIdx(); - if (node->m_type == itVolume) { + if (node->m_type & (itVolume|itLayer)) { node_parent->m_volumes_cnt--; DeleteSettings(item); } @@ -810,6 +818,22 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) delete node_parent; ret_item = wxDataViewItem(obj_node); +#ifndef __WXGTK__ + if (obj_node->GetChildCount() == 0) + obj_node->m_container = false; +#endif //__WXGTK__ + ItemDeleted(ret_item, wxDataViewItem(node_parent)); + return ret_item; + } + + // if there was last layer item, delete this one and layers root item + if (node_parent->GetChildCount() == 0 && node_parent->m_type == itLayerRoot) + { + ObjectDataViewModelNode *obj_node = node_parent->GetParent(); + obj_node->GetChildren().Remove(node_parent); + delete node_parent; + ret_item = wxDataViewItem(obj_node); + #ifndef __WXGTK__ if (obj_node->GetChildCount() == 0) obj_node->m_container = false; @@ -819,7 +843,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) } // if there is last volume item after deleting, delete this last volume too - if (node_parent->GetChildCount() <= 3) + if (node_parent->GetChildCount() <= 3) // 3??? #ys_FIXME { int vol_cnt = 0; int vol_idx = 0; @@ -1120,7 +1144,7 @@ void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type type = itUndef; ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); - if (!node || node->GetIdx() <-1 || node->GetIdx() ==-1 && !(node->GetType() & (itObject | itSettings | itInstanceRoot))) + if (!node || node->GetIdx() <-1 || node->GetIdx() == -1 && !(node->GetType() & (itObject | itSettings | itInstanceRoot | itLayerRoot/* | itLayer*/))) return; idx = node->GetIdx(); @@ -1128,7 +1152,7 @@ void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type ObjectDataViewModelNode *parent_node = node->GetParent(); if (!parent_node) return; - if (type == itInstance) + if (type & (itInstance | itLayer)) parent_node = node->GetParent()->GetParent(); if (!parent_node || parent_node->m_type != itObject) { type = itUndef; return; } -- cgit v1.2.3 From 765d4264ae9380a549bd84bd8d79d776858d8816 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 28 May 2019 16:38:04 +0200 Subject: Implemented ObjectLayers class + some code refactoring --- src/slic3r/GUI/GUI_App.cpp | 5 ++ src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/GUI_ObjectLayers.cpp | 150 ++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GUI_ObjectLayers.hpp | 36 ++++++++ src/slic3r/GUI/GUI_ObjectList.cpp | 29 ++++++- src/slic3r/GUI/GUI_ObjectList.hpp | 12 ++- src/slic3r/GUI/GUI_ObjectSettings.cpp | 4 +- src/slic3r/GUI/Plater.cpp | 13 +++ src/slic3r/GUI/Plater.hpp | 2 + 9 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 src/slic3r/GUI/GUI_ObjectLayers.cpp create mode 100644 src/slic3r/GUI/GUI_ObjectLayers.hpp (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b75b946e6..405de3ae9 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -924,6 +924,11 @@ ObjectList* GUI_App::obj_list() return sidebar().obj_list(); } +ObjectLayers* GUI_App::obj_layers() +{ + return sidebar().obj_layers(); +} + Plater* GUI_App::plater() { return plater_; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index b70f0dc16..675121824 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -155,6 +155,7 @@ public: ObjectManipulation* obj_manipul(); ObjectSettings* obj_settings(); ObjectList* obj_list(); + ObjectLayers* obj_layers(); Plater* plater(); std::vector *model_objects(); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp new file mode 100644 index 000000000..31a17bbf6 --- /dev/null +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -0,0 +1,150 @@ +#include "GUI_ObjectLayers.hpp" +#include "GUI_ObjectList.hpp" + +#include "OptionsGroup.hpp" +#include "PresetBundle.hpp" +#include "libslic3r/Model.hpp" + +#include + +#include "I18N.hpp" + +#include + +namespace Slic3r +{ +namespace GUI +{ + +ObjectLayers::ObjectLayers(wxWindow* parent) : + OG_Settings(parent, true) +{ + m_og->label_width = 0; + m_og->set_grid_vgap(5); + + // Legend for object layers + Line line = Line{ "", "" }; + + ConfigOptionDef def; + def.label = ""; + def.gui_type = "legend"; + def.type = coString; + def.width = field_width; + + for (const std::string axis : { "Min Z", "Max Z", "Layer height" }) { + def.set_default_value(new ConfigOptionString{ axis }); + std::string label = boost::algorithm::replace_all_copy(axis, " ", "_"); + boost::algorithm::to_lower(label); + line.append_option(Option(def, label + "_legend")); + } + + m_og->append_line(line); + + m_bmp_delete = ScalableBitmap(parent, "cross"); + m_bmp_add = ScalableBitmap(parent, "add_copies"); +} + +void ObjectLayers::update_layers_list() +{ + ObjectList* objects_ctrl = wxGetApp().obj_list(); + if (objects_ctrl->multiple_selection()) return; + + const auto item = objects_ctrl->GetSelection(); + if (!item) return; + + const int obj_idx = objects_ctrl->get_selected_obj_idx(); + if (obj_idx < 0) return; + + const ItemType type = objects_ctrl->GetModel()->GetItemType(item); + if (!(type & (itLayerRoot | itLayer))) return; + + ModelObject* object = objects_ctrl->object(obj_idx); + if (!object || object->layer_height_ranges.empty()) return; + + auto grid_sizer = m_og->get_grid_sizer(); + + const int cols = grid_sizer->GetCols(); + const int rows = grid_sizer->GetRows(); + for (int idx = cols*rows-1; idx >= cols; idx--) { + grid_sizer->Remove(idx); + } + + ConfigOptionDef def; + def.label = ""; + def.gui_type = ""; + def.type = coFloat; + def.width = field_width; + + if (type & itLayerRoot) + { + auto create_btns = [this](wxWindow* parent) { + auto sizer = new wxBoxSizer(wxHORIZONTAL); + auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + del_btn->SetToolTip(_(L("Remove layer"))); + + sizer->Add(del_btn, 0, wxRIGHT, em_unit(parent)); + + del_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { + del_layer(); +// wxTheApp->CallAfter([this]() { +// wxWindowUpdateLocker noUpdates(m_parent); +// update_layers_list(); +// m_parent->Layout(); +// }); + }); + + auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); + add_btn->SetToolTip(_(L("Add layer"))); + + sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); + + add_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { + add_layer(); +// wxTheApp->CallAfter([this]() { +// wxWindowUpdateLocker noUpdates(m_parent); +// update_layers_list(); +// m_parent->Layout(); +// }); + }); + + return sizer; + }; + + Line line{"",""}; + for (const auto layer : object->layer_height_ranges) + { + std::string label = (boost::format("min_z_%.2f") % layer.first.first).str(); + def.set_default_value(new ConfigOptionFloat(layer.first.first)); + line.append_option(Option(def, label)); + + label = (boost::format("max_z_%.2f") % layer.first.second).str(); + def.set_default_value(new ConfigOptionFloat(layer.first.second)); + line.append_option(Option(def, label)); + + label = (boost::format("layer_height_%.2f_%.2f") % layer.first.first % layer.first.second).str(); + def.set_default_value(new ConfigOptionFloat(layer.second)); + line.append_option(Option(def, label)); + + line.append_widget(create_btns); + } + + m_og->append_line(line); + } +} + +void ObjectLayers::UpdateAndShow(const bool show) +{ + if (show) + update_layers_list(); + + OG_Settings::UpdateAndShow(show); +} + +void ObjectLayers::msw_rescale() +{ + m_bmp_delete.msw_rescale(); + m_bmp_add.msw_rescale(); +} + +} //namespace GUI +} //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp new file mode 100644 index 000000000..8f8b55998 --- /dev/null +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -0,0 +1,36 @@ +#ifndef slic3r_GUI_ObjectLayers_hpp_ +#define slic3r_GUI_ObjectLayers_hpp_ + +#include "GUI_ObjectSettings.hpp" +#include "wxExtensions.hpp" + +class wxBoxSizer; + +namespace Slic3r { +class ModelObject; + +namespace GUI { +class ConfigOptionsGroup; + +class ObjectLayers : public OG_Settings +{ + ScalableBitmap m_bmp_delete; + ScalableBitmap m_bmp_add; + + int field_width {8}; + +public: + ObjectLayers(wxWindow* parent); + ~ObjectLayers() {} + + void update_layers_list(); + void add_layer() {}; + void del_layer() {}; + + void UpdateAndShow(const bool show) override; + void msw_rescale(); +}; + +}} + +#endif // slic3r_GUI_ObjectLayers_hpp_ diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index e180f1dfc..080ebbe21 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1,6 +1,7 @@ #include "libslic3r/libslic3r.h" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" +#include "GUI_ObjectLayers.hpp" #include "GUI_App.hpp" #include "I18N.hpp" @@ -1799,7 +1800,11 @@ void ObjectList::layers_editing() wxDataViewItem layers_item = m_objects_model->GetItemByType(obj_item, itLayerRoot); if (!layers_item.IsOk()) + { + const t_layer_height_range first_range = { 0.0f, 0.2f }; + object(obj_idx)->layer_height_ranges[first_range] = 0.1f; layers_item = m_objects_model->AddLayersRoot(obj_item); + } select_item(layers_item); } @@ -1873,6 +1878,7 @@ void ObjectList::part_selection_changed() bool update_and_show_manipulations = false; bool update_and_show_settings = false; + bool update_and_show_layers = false; const auto item = GetSelection(); @@ -1898,7 +1904,8 @@ void ObjectList::part_selection_changed() auto parent = m_objects_model->GetParent(item); // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene obj_idx = m_objects_model->GetIdByItem(parent); - if (m_objects_model->GetItemType(item) == itSettings) { + const ItemType type = m_objects_model->GetItemType(item); + if (type & itSettings) { if (m_objects_model->GetParent(parent) == wxDataViewItem(0)) { og_name = _(L("Object Settings to modify")); m_config = &(*m_objects)[obj_idx]->config; @@ -1912,13 +1919,13 @@ void ObjectList::part_selection_changed() } update_and_show_settings = true; } - else if (m_objects_model->GetItemType(item) == itVolume) { + else if (type & itVolume) { og_name = _(L("Part manipulation")); volume_id = m_objects_model->GetVolumeIdByItem(item); m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; update_and_show_manipulations = true; } - else if (m_objects_model->GetItemType(item) == itInstance) { + else if (type & itInstance) { og_name = _(L("Instance manipulation")); update_and_show_manipulations = true; @@ -1926,6 +1933,10 @@ void ObjectList::part_selection_changed() const int obj_idx_ = m_objects_model->GetObjectIdByItem(item); m_config = &(*m_objects)[obj_idx_]->config; } + else if (type & (itLayerRoot|itLayer)) { + og_name = type & itLayerRoot ? _(L("Layers Editing")) : _(L("Layer Editing")); + update_and_show_layers = true; + } } } } @@ -1944,11 +1955,15 @@ void ObjectList::part_selection_changed() if (update_and_show_settings) wxGetApp().obj_settings()->get_og()->set_name(" " + og_name + " "); + if (update_and_show_layers) + wxGetApp().obj_layers()->get_og()->set_name(" " + og_name + " "); + Sidebar& panel = wxGetApp().sidebar(); panel.Freeze(); wxGetApp().obj_manipul() ->UpdateAndShow(update_and_show_manipulations); wxGetApp().obj_settings()->UpdateAndShow(update_and_show_settings); + wxGetApp().obj_layers() ->UpdateAndShow(update_and_show_layers); wxGetApp().sidebar().show_info_sizer(); panel.Layout(); @@ -2946,5 +2961,13 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const wxGetApp().plater()->update(); } +ModelObject* ObjectList::object(const int obj_idx) const +{ + if (obj_idx < 0) + return nullptr; + + return (*m_objects)[obj_idx]; +} + } //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 076ab5f13..764aac1e8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -122,6 +122,10 @@ class ObjectList : public wxDataViewCtrl wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr }; + ObjectDataViewModel *m_objects_model{ nullptr }; + DynamicPrintConfig *m_config {nullptr}; + std::vector *m_objects{ nullptr }; + std::vector m_bmp_vector; int m_selected_object_id = -1; @@ -151,11 +155,11 @@ public: std::map CATEGORY_ICON; - ObjectDataViewModel *m_objects_model{ nullptr }; - DynamicPrintConfig *m_config {nullptr}; - - std::vector *m_objects{ nullptr }; + ObjectDataViewModel* GetModel() const { return m_objects_model; } + DynamicPrintConfig* config() const { return m_config; } + std::vector* objects() const { return m_objects; } + ModelObject* object(const int obj_idx) const ; void create_objects_ctrl(); void create_popup_menus(); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 4107e872a..a4aa7dec2 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -68,8 +68,8 @@ void ObjectSettings::update_settings_list() m_settings_list_sizer->Clear(true); auto objects_ctrl = wxGetApp().obj_list(); - auto objects_model = wxGetApp().obj_list()->m_objects_model; - auto config = wxGetApp().obj_list()->m_config; + auto objects_model = wxGetApp().obj_list()->GetModel(); + auto config = wxGetApp().obj_list()->config(); const auto item = objects_ctrl->GetSelection(); if (item && !objects_ctrl->multiple_selection() && diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c0f267204..88abe9b83 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -43,6 +43,7 @@ #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" +#include "GUI_ObjectLayers.hpp" #include "GUI_Utils.hpp" #include "wxExtensions.hpp" #include "MainFrame.hpp" @@ -611,6 +612,7 @@ struct Sidebar::priv ObjectList *object_list; ObjectManipulation *object_manipulation; ObjectSettings *object_settings; + ObjectLayers *object_layers; ObjectInfo *object_info; SlicedInfo *sliced_info; @@ -729,6 +731,11 @@ Sidebar::Sidebar(Plater *parent) p->object_settings = new ObjectSettings(p->scrolled); p->object_settings->Hide(); p->sizer_params->Add(p->object_settings->get_sizer(), 0, wxEXPAND | wxTOP, margin_5); + + // Object Layers + p->object_layers = new ObjectLayers(p->scrolled); + p->object_layers->Hide(); + p->sizer_params->Add(p->object_layers->get_sizer(), 0, wxEXPAND | wxTOP, margin_5); // Info boxes p->object_info = new ObjectInfo(p->scrolled); @@ -922,6 +929,7 @@ void Sidebar::msw_rescale() p->object_list->msw_rescale(); p->object_manipulation->msw_rescale(); p->object_settings->msw_rescale(); + p->object_layers->msw_rescale(); p->object_info->msw_rescale(); @@ -943,6 +951,11 @@ ObjectSettings* Sidebar::obj_settings() return p->object_settings; } +ObjectLayers* Sidebar::obj_layers() +{ + return p->object_layers; +} + wxScrolledWindow* Sidebar::scrolled_panel() { return p->scrolled; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 16c9cbe64..3e50797a6 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -33,6 +33,7 @@ class MainFrame; class ConfigOptionsGroup; class ObjectManipulation; class ObjectSettings; +class ObjectLayers; class ObjectList; class GLCanvas3D; @@ -93,6 +94,7 @@ public: ObjectManipulation* obj_manipul(); ObjectList* obj_list(); ObjectSettings* obj_settings(); + ObjectLayers* obj_layers(); wxScrolledWindow* scrolled_panel(); wxPanel* presets_panel(); -- cgit v1.2.3 From bf56d79354cd74d645ea3e030c476c41d9c649eb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 30 May 2019 12:41:16 +0200 Subject: Layers sizer updating --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 173 ++++++++++++++++++++++-------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 9 +- src/slic3r/GUI/GUI_ObjectList.cpp | 4 + src/slic3r/GUI/OptionsGroup.cpp | 11 +++ src/slic3r/GUI/OptionsGroup.hpp | 2 + 5 files changed, 128 insertions(+), 71 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 31a17bbf6..80aa6bcca 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -14,13 +14,17 @@ namespace Slic3r { namespace GUI -{ +{ + +typedef std::map t_layer_height_ranges; + +#define field_width 8 ObjectLayers::ObjectLayers(wxWindow* parent) : OG_Settings(parent, true) { - m_og->label_width = 0; - m_og->set_grid_vgap(5); + m_og->label_width = 1; +// m_og->set_grid_vgap(5); // Legend for object layers Line line = Line{ "", "" }; @@ -36,6 +40,8 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : std::string label = boost::algorithm::replace_all_copy(axis, " ", "_"); boost::algorithm::to_lower(label); line.append_option(Option(def, label + "_legend")); + + m_legends.push_back(label + "_legend"); } m_og->append_line(line); @@ -44,6 +50,83 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_bmp_add = ScalableBitmap(parent, "add_copies"); } +static Line create_new_layer(const t_layer_height_ranges::value_type& layer) +{ + Line line = Line{ "", "" }; + ConfigOptionDef def; + def.label = ""; + def.gui_type = ""; + def.type = coFloat; + def.width = field_width; + + std::string label = (boost::format("min_z_%.2f") % layer.first.first).str(); + def.set_default_value(new ConfigOptionFloat(layer.first.first)); + line.append_option(Option(def, label)); + + label = (boost::format("max_z_%.2f") % layer.first.second).str(); + def.set_default_value(new ConfigOptionFloat(layer.first.second)); + line.append_option(Option(def, label)); + + label = (boost::format("layer_height_%.2f_%.2f") % layer.first.first % layer.first.second).str(); + def.set_default_value(new ConfigOptionFloat(layer.second)); + line.append_option(Option(def, label)); + + return line; +} + +void ObjectLayers::create_layers_list() +{ + auto create_btns = [this](wxWindow* parent) { + auto sizer = new wxBoxSizer(wxHORIZONTAL); + + auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + del_btn->SetToolTip(_(L("Remove layer"))); + + sizer->Add(del_btn, 0, wxRIGHT, em_unit(parent)); + + del_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { + del_layer(); +// wxTheApp->CallAfter([this]() { +// wxWindowUpdateLocker noUpdates(m_parent); +// update_layers_list(); +// m_parent->Layout(); +// }); + }); + + auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); + add_btn->SetToolTip(_(L("Add layer"))); + + sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); + + add_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { + add_layer(); +// wxTheApp->CallAfter([this]() { +// wxWindowUpdateLocker noUpdates(m_parent); +// update_layers_list(); +// m_parent->Layout(); +// }); + }); + + return sizer; + }; + + for (const auto layer : m_object->layer_height_ranges) + { + Line line = create_new_layer(layer); + line.append_widget(create_btns); + m_og->append_line(line); + } +} + +void ObjectLayers::create_layer() +{ + for (const auto layer : m_object->layer_height_ranges) + { + m_og->append_line(create_new_layer(layer)); + break; + } +} + void ObjectLayers::update_layers_list() { ObjectList* objects_ctrl = wxGetApp().obj_list(); @@ -58,78 +141,32 @@ void ObjectLayers::update_layers_list() const ItemType type = objects_ctrl->GetModel()->GetItemType(item); if (!(type & (itLayerRoot | itLayer))) return; - ModelObject* object = objects_ctrl->object(obj_idx); - if (!object || object->layer_height_ranges.empty()) return; + m_object = objects_ctrl->object(obj_idx); + if (!m_object || m_object->layer_height_ranges.empty()) return; - auto grid_sizer = m_og->get_grid_sizer(); + // Delete all controls from options group except of the legends - const int cols = grid_sizer->GetCols(); - const int rows = grid_sizer->GetRows(); + auto grid_sizer = m_og->get_grid_sizer(); + const int cols = grid_sizer->GetEffectiveColsCount(); + const int rows = grid_sizer->GetEffectiveRowsCount(); for (int idx = cols*rows-1; idx >= cols; idx--) { - grid_sizer->Remove(idx); + wxSizerItem* t = grid_sizer->GetItem(idx); + if (t->IsSizer()) + t->GetSizer()->Clear(true); + grid_sizer->Remove(idx); } - ConfigOptionDef def; - def.label = ""; - def.gui_type = ""; - def.type = coFloat; - def.width = field_width; + m_og->clear_fields_except_of(m_legends); - if (type & itLayerRoot) - { - auto create_btns = [this](wxWindow* parent) { - auto sizer = new wxBoxSizer(wxHORIZONTAL); - auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); - del_btn->SetToolTip(_(L("Remove layer"))); - - sizer->Add(del_btn, 0, wxRIGHT, em_unit(parent)); - - del_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { - del_layer(); -// wxTheApp->CallAfter([this]() { -// wxWindowUpdateLocker noUpdates(m_parent); -// update_layers_list(); -// m_parent->Layout(); -// }); - }); - - auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); - add_btn->SetToolTip(_(L("Add layer"))); - - sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); - - add_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { - add_layer(); -// wxTheApp->CallAfter([this]() { -// wxWindowUpdateLocker noUpdates(m_parent); -// update_layers_list(); -// m_parent->Layout(); -// }); - }); - - return sizer; - }; - - Line line{"",""}; - for (const auto layer : object->layer_height_ranges) - { - std::string label = (boost::format("min_z_%.2f") % layer.first.first).str(); - def.set_default_value(new ConfigOptionFloat(layer.first.first)); - line.append_option(Option(def, label)); - - label = (boost::format("max_z_%.2f") % layer.first.second).str(); - def.set_default_value(new ConfigOptionFloat(layer.first.second)); - line.append_option(Option(def, label)); - - label = (boost::format("layer_height_%.2f_%.2f") % layer.first.first % layer.first.second).str(); - def.set_default_value(new ConfigOptionFloat(layer.second)); - line.append_option(Option(def, label)); - - line.append_widget(create_btns); - } - m_og->append_line(line); - } + // Add new control according to the selected item + + if (type & itLayerRoot) + create_layers_list(); + else + create_layer(); + + m_parent->Layout(); } void ObjectLayers::UpdateAndShow(const bool show) diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 8f8b55998..13a3da911 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -14,15 +14,18 @@ class ConfigOptionsGroup; class ObjectLayers : public OG_Settings { - ScalableBitmap m_bmp_delete; - ScalableBitmap m_bmp_add; + ScalableBitmap m_bmp_delete; + ScalableBitmap m_bmp_add; + ModelObject* m_object {nullptr}; - int field_width {8}; + std::vector m_legends; public: ObjectLayers(wxWindow* parent); ~ObjectLayers() {} + void create_layers_list(); + void create_layer(); void update_layers_list(); void add_layer() {}; void del_layer() {}; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 080ebbe21..00eb3e7de 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1803,6 +1803,10 @@ void ObjectList::layers_editing() { const t_layer_height_range first_range = { 0.0f, 0.2f }; object(obj_idx)->layer_height_ranges[first_range] = 0.1f; + + const t_layer_height_range second_range = { 0.2f, 0.4f }; + object(obj_idx)->layer_height_ranges[second_range] = 0.05f; + layers_item = m_objects_model->AddLayersRoot(obj_item); } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 2ac6b00af..67feefa3f 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -320,6 +320,17 @@ Line OptionsGroup::create_single_option_line(const Option& option) const { return retval; } +void OptionsGroup::clear_fields_except_of(const std::vector left_fields) +{ + auto it = m_fields.begin(); + while (it != m_fields.end()) { + if (std::find(left_fields.begin(), left_fields.end(), it->first) == left_fields.end()) + it = m_fields.erase(it); + else + it++; + } +} + void OptionsGroup::on_set_focus(const std::string& opt_key) { if (m_set_focus != nullptr) diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 73b2c5110..422a5c2a2 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -160,6 +160,8 @@ public: m_show_modified_btns = show; } + void clear_fields_except_of(const std::vector left_fields); + OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false, column_t extra_clmn = nullptr) : m_parent(_parent), title(title), -- cgit v1.2.3 From a516f76f94447e82eed066f022deedf769f07b42 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 30 May 2019 14:41:16 +0200 Subject: Improved layer sizer + fixed build under OSX and Linux --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 17 +++++----- src/slic3r/GUI/GUI_ObjectLayers.hpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 16 +++++++--- src/slic3r/GUI/wxExtensions.cpp | 62 ++++++++++++++++++++++++------------- src/slic3r/GUI/wxExtensions.hpp | 8 ++++- 5 files changed, 70 insertions(+), 35 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 80aa6bcca..f47260530 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -24,7 +24,7 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : OG_Settings(parent, true) { m_og->label_width = 1; -// m_og->set_grid_vgap(5); + m_og->set_grid_vgap(5); // Legend for object layers Line line = Line{ "", "" }; @@ -118,13 +118,16 @@ void ObjectLayers::create_layers_list() } } -void ObjectLayers::create_layer() +void ObjectLayers::create_layer(int id) { - for (const auto layer : m_object->layer_height_ranges) - { - m_og->append_line(create_new_layer(layer)); - break; + t_layer_height_ranges::iterator layer_range = m_object->layer_height_ranges.begin(); + + while (id > 0 && layer_range != m_object->layer_height_ranges.end()) { + layer_range++; + id--; } + + m_og->append_line(create_new_layer(*layer_range)); } void ObjectLayers::update_layers_list() @@ -164,7 +167,7 @@ void ObjectLayers::update_layers_list() if (type & itLayerRoot) create_layers_list(); else - create_layer(); + create_layer(objects_ctrl->GetModel()->GetLayerIdByItem(item)); m_parent->Layout(); } diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 13a3da911..b9e9efb14 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -25,7 +25,7 @@ public: ~ObjectLayers() {} void create_layers_list(); - void create_layer(); + void create_layer(int id); void update_layers_list(); void add_layer() {}; void del_layer() {}; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 00eb3e7de..934ad34fb 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1801,15 +1801,21 @@ void ObjectList::layers_editing() wxDataViewItem layers_item = m_objects_model->GetItemByType(obj_item, itLayerRoot); if (!layers_item.IsOk()) { - const t_layer_height_range first_range = { 0.0f, 0.2f }; - object(obj_idx)->layer_height_ranges[first_range] = 0.1f; - - const t_layer_height_range second_range = { 0.2f, 0.4f }; - object(obj_idx)->layer_height_ranges[second_range] = 0.05f; + // --->>>--- Just for testing + object(obj_idx)->layer_height_ranges[{ 0.0f, 0.2f }] = 0.1f; + object(obj_idx)->layer_height_ranges[{ 0.2f, 0.4f }] = 0.05f; + object(obj_idx)->layer_height_ranges[{ 0.4f, 0.6f }] = 0.2f; + // ---<<<--- Just for testing layers_item = m_objects_model->AddLayersRoot(obj_item); } + for (const auto range : object(obj_idx)->layer_height_ranges) + { + const std::string label = (boost::format("(%.2f-%.2f)") % range.first.first % range.first.second).str(); + m_objects_model->AddLayersChild(layers_item, label); + } + select_item(layers_item); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 7849f66dd..989a97676 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -453,24 +453,39 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_bmp = create_scaled_bitmap(nullptr, "table.png"); // FIXME: pass window ptr m_name = _(L("Layers")); } - else if (type == itLayer) - { - m_idx = parent->GetChildCount(); - m_name = wxString::Format(_(L("Layer %d")), m_idx + 1); - m_bmp = create_scaled_bitmap(nullptr, "row.png"); // FIXME: pass window ptr - - set_action_icon(); - } #ifdef __WXGTK__ // it's necessary on GTK because of control have to know if this item will be container // in another case you couldn't to add subitem for this item // it will be produce "segmentation fault" - if (type & (itInstanceRoot | itLayerRoot | itLayer)) + if (type & (itInstanceRoot | itLayerRoot)) m_container = true; #endif //__WXGTK__ } +ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, + const wxString& label_range, + const wxString& extruder, + const int idx /*= -1 */) : + m_parent(parent), + m_type(itLayer), + m_idx(idx), + m_extruder(extruder) +{ + m_idx = parent->GetChildCount(); + m_name = wxString::Format(_(L("Layer %s")), label_range); + m_bmp = create_scaled_bitmap(nullptr, "row.png"); // FIXME: pass window ptr + +#ifdef __WXGTK__ + // it's necessary on GTK because of control have to know if this item will be container + // in another case you couldn't to add subitem for this item + // it will be produce "segmentation fault" + m_container = true; +#endif //__WXGTK__ + + set_action_icon(); +} + void ObjectDataViewModelNode::set_action_icon() { m_action_icon_name = m_type & itObject ? "advanced_plus" : @@ -671,7 +686,7 @@ static bool append_root_node(ObjectDataViewModelNode *parent_node, (root_type&itLayerRoot) && get_root_idx(parent_node, itInstanceRoot)<0) parent_node->Append(*root_node); else if (root_type&itLayerRoot) - parent_node->Insert(*root_node, unsigned int(get_root_idx(parent_node, itInstanceRoot))); + parent_node->Insert(*root_node, static_cast(get_root_idx(parent_node, itInstanceRoot))); return true; } @@ -723,38 +738,38 @@ wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_i if (appended) ItemAdded(parent_item, layer_root_item);// notify control - AddLayersChild(layer_root_item); - - return wxDataViewItem((void*)layer_root_item); + return layer_root_item; } -wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item) +wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, const std::string& label_range) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); // get LayerRoot node ObjectDataViewModelNode *layer_root_node; + wxDataViewItem layer_root_item; - if (parent_node->GetType() & itLayerRoot) + if (parent_node->GetType() & itLayerRoot) { layer_root_node = parent_node; + layer_root_item = parent_item; + } else { const int root_idx = get_root_idx(parent_node, itLayerRoot); if (root_idx < 0) return wxDataViewItem(0); layer_root_node = parent_node->GetNthChild(root_idx); + layer_root_item = wxDataViewItem((void*)layer_root_node); } - const wxDataViewItem layer_root_item((void*)layer_root_node); - // Add layer node - ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, itLayer); + ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, label_range); layer_root_node->Append(layer_node); // notify control - const wxDataViewItem instance_item((void*)layer_node); - ItemAdded(layer_root_item, instance_item); + const wxDataViewItem layer_item((void*)layer_node); + ItemAdded(layer_root_item, layer_item); - return wxDataViewItem((void*)layer_node); + return layer_item; } wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) @@ -1138,6 +1153,11 @@ int ObjectDataViewModel::GetInstanceIdByItem(const wxDataViewItem& item) const return GetIdByItemAndType(item, itInstance); } +int ObjectDataViewModel::GetLayerIdByItem(const wxDataViewItem& item) const +{ + return GetIdByItemAndType(item, itLayer); +} + void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx) { wxASSERT(item.IsOk()); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 424f7832a..b3d8ebc18 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -231,6 +231,11 @@ public: set_action_icon(); } + ObjectDataViewModelNode(ObjectDataViewModelNode* parent, + const wxString& label_range, + const wxString& extruder = wxEmptyString, + const int idx = -1 ); + ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type); ~ObjectDataViewModelNode() @@ -391,7 +396,7 @@ public: wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); - wxDataViewItem AddLayersChild(const wxDataViewItem &parent_item); + wxDataViewItem AddLayersChild(const wxDataViewItem &parent_item, const std::string& label_range); wxDataViewItem Delete(const wxDataViewItem &item); wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); void DeleteAll(); @@ -406,6 +411,7 @@ public: int GetObjectIdByItem(const wxDataViewItem& item) const; int GetVolumeIdByItem(const wxDataViewItem& item) const; int GetInstanceIdByItem(const wxDataViewItem& item) const; + int GetLayerIdByItem(const wxDataViewItem& item) const; void GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx); int GetRowByItem(const wxDataViewItem& item) const; bool IsEmpty() { return m_objects.empty(); } -- cgit v1.2.3 From e531d224e8b4649ec1a16e58e2d060cc1be271d9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 30 May 2019 16:53:17 +0200 Subject: Implemented delete_layers_from_object() --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 45 +++++++++++++++++++++++++++++-------- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 7 +++--- 4 files changed, 42 insertions(+), 13 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index f47260530..191a65386 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -46,7 +46,7 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_og->append_line(line); - m_bmp_delete = ScalableBitmap(parent, "cross"); + m_bmp_delete = ScalableBitmap(parent, "remove_copies"/*"cross"*/); m_bmp_add = ScalableBitmap(parent, "add_copies"); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 934ad34fb..8043ee565 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1141,7 +1141,7 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu) wxMenuItem* ObjectList::append_menu_item_layers_editing(wxMenu* menu) { return append_menu_item(menu, wxID_ANY, _(L("Edit Layers")), "", - [this](wxCommandEvent&) { layers_editing(); }, "table.png", menu); + [this](wxCommandEvent&) { layers_editing(); }, "layers", menu); } wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) @@ -1650,7 +1650,7 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) else if (type == itInstanceRoot && obj_idx != -1) del_instances_from_object(obj_idx); else if ((type & itLayerRoot) && obj_idx != -1) - /*del_layers_from_object(obj_idx)*/; + del_layers_from_object(obj_idx); else if (idx == -1) return; else if (!del_subobject_from_object(obj_idx, idx, type)) @@ -1692,6 +1692,13 @@ void ObjectList::del_instances_from_object(const int obj_idx) changed_object(obj_idx); } +void ObjectList::del_layers_from_object(const int obj_idx) +{ + object(obj_idx)->layer_height_ranges.clear(); // ? #ys_FIXME + + changed_object(obj_idx); +} + bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type) { if (obj_idx == 1000) @@ -1732,6 +1739,13 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con object->delete_instance(idx); } else if (type == itLayer) { + t_layer_height_ranges::iterator layer_range = object->layer_height_ranges.begin(); + int id = idx; + while (id > 0 && layer_range != object->layer_height_ranges.end()) { + layer_range++; + id--; + } + object->layer_height_ranges.erase(layer_range); } else return false; @@ -1808,12 +1822,12 @@ void ObjectList::layers_editing() // ---<<<--- Just for testing layers_item = m_objects_model->AddLayersRoot(obj_item); - } - for (const auto range : object(obj_idx)->layer_height_ranges) - { - const std::string label = (boost::format("(%.2f-%.2f)") % range.first.first % range.first.second).str(); - m_objects_model->AddLayersChild(layers_item, label); + for (const auto range : object(obj_idx)->layer_height_ranges) + { + const std::string label = (boost::format(" %.2f-%.2f ") % range.first.first % range.first.second).str(); + m_objects_model->AddLayersChild(layers_item, label); + } } select_item(layers_item); @@ -2168,9 +2182,22 @@ void ObjectList::remove() if (m_objects_model->GetParent(item) == wxDataViewItem(0)) delete_from_model_and_list(itObject, m_objects_model->GetIdByItem(item), -1); else { - if (sels.size() == 1) - select_item(m_objects_model->GetParent(item)); +// if (sels.size() == 1) +// select_item(m_objects_model->GetParent(item)); + wxDataViewItem parent = m_objects_model->GetParent(item); + if (sels.size() == 1) { + if (!(m_objects_model->GetItemType(item) & itLayer)) { + select_item(parent); + parent = wxDataViewItem(0); + } + else if (m_objects_model->GetChildren(parent, wxDataViewItemArray()) == 1) + parent = m_objects_model->GetTopParent(item); + } + del_subobject_item(item); + + if (sels.size() == 1 && parent) + select_item(parent); } } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 764aac1e8..6963805e9 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -227,6 +227,7 @@ public: void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(); void del_instances_from_object(const int obj_idx); + void del_layers_from_object(const int obj_idx); bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void split(); void layers_editing(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 989a97676..4511ab8ac 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -450,7 +450,7 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent } else if (type == itLayerRoot) { - m_bmp = create_scaled_bitmap(nullptr, "table.png"); // FIXME: pass window ptr + m_bmp = create_scaled_bitmap(nullptr, "layers"); // FIXME: pass window ptr m_name = _(L("Layers")); } @@ -473,8 +473,9 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_extruder(extruder) { m_idx = parent->GetChildCount(); - m_name = wxString::Format(_(L("Layer %s")), label_range); - m_bmp = create_scaled_bitmap(nullptr, "row.png"); // FIXME: pass window ptr +// m_name = wxString::Format(_(L("Layer %s (mm)")), label_range); + m_name = _(L("Range")) + label_range + "(" + _(L("mm")) + ")"; + m_bmp = create_scaled_bitmap(nullptr, "layers_white"); // FIXME: pass window ptr #ifdef __WXGTK__ // it's necessary on GTK because of control have to know if this item will be container -- cgit v1.2.3 From 38641ef5784f8607f6be77e3242970684fed3810 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 31 May 2019 10:54:52 +0200 Subject: ObjectLayers::del_layer_range() -> delete a layers range using "Del" button from ObjectLayers sizer --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 49 ++++++++++++++----------------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 2 -- src/slic3r/GUI/GUI_ObjectList.cpp | 35 +++++++++++++++++++++++++- src/slic3r/GUI/GUI_ObjectList.hpp | 2 ++ src/slic3r/GUI/wxExtensions.cpp | 25 +++++++++++++++---- src/slic3r/GUI/wxExtensions.hpp | 3 +++ 6 files changed, 78 insertions(+), 38 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 191a65386..5ff650e86 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -16,8 +16,6 @@ namespace Slic3r namespace GUI { -typedef std::map t_layer_height_ranges; - #define field_width 8 ObjectLayers::ObjectLayers(wxWindow* parent) : @@ -76,42 +74,32 @@ static Line create_new_layer(const t_layer_height_ranges::value_type& layer) void ObjectLayers::create_layers_list() { - auto create_btns = [this](wxWindow* parent) { - auto sizer = new wxBoxSizer(wxHORIZONTAL); + for (const auto layer : m_object->layer_height_ranges) + { + auto create_btns = [this, layer](wxWindow* parent) { + auto sizer = new wxBoxSizer(wxHORIZONTAL); - auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); - del_btn->SetToolTip(_(L("Remove layer"))); + auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + del_btn->SetToolTip(_(L("Remove layer"))); - sizer->Add(del_btn, 0, wxRIGHT, em_unit(parent)); + sizer->Add(del_btn, 0, wxRIGHT, em_unit(parent)); - del_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { - del_layer(); -// wxTheApp->CallAfter([this]() { -// wxWindowUpdateLocker noUpdates(m_parent); -// update_layers_list(); -// m_parent->Layout(); -// }); - }); + del_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { + wxGetApp().obj_list()->del_layer_range(layer.first); + }); - auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); - add_btn->SetToolTip(_(L("Add layer"))); + auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); + add_btn->SetToolTip(_(L("Add layer"))); - sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); + sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); - add_btn->Bind(wxEVT_BUTTON, [this](wxEvent &event) { - add_layer(); -// wxTheApp->CallAfter([this]() { -// wxWindowUpdateLocker noUpdates(m_parent); -// update_layers_list(); -// m_parent->Layout(); -// }); - }); + add_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { + wxGetApp().obj_list()->add_layer_range(layer.first); + }); - return sizer; - }; + return sizer; + }; - for (const auto layer : m_object->layer_height_ranges) - { Line line = create_new_layer(layer); line.append_widget(create_btns); m_og->append_line(line); @@ -122,6 +110,7 @@ void ObjectLayers::create_layer(int id) { t_layer_height_ranges::iterator layer_range = m_object->layer_height_ranges.begin(); + // May be not a best solution #ys_FIXME while (id > 0 && layer_range != m_object->layer_height_ranges.end()) { layer_range++; id--; diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index b9e9efb14..0b209d523 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -27,8 +27,6 @@ public: void create_layers_list(); void create_layer(int id); void update_layers_list(); - void add_layer() {}; - void del_layer() {}; void UpdateAndShow(const bool show) override; void msw_rescale(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 8043ee565..cb815fc72 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1812,7 +1812,7 @@ void ObjectList::layers_editing() wxDataViewItem obj_item = m_objects_model->GetTopParent(item); - wxDataViewItem layers_item = m_objects_model->GetItemByType(obj_item, itLayerRoot); + wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(obj_item); if (!layers_item.IsOk()) { // --->>>--- Just for testing @@ -2202,6 +2202,39 @@ void ObjectList::remove() } } +void ObjectList::del_layer_range(const std::pair& range) +{ + const int obj_idx = get_selected_obj_idx(); + if (obj_idx < 0) return; + + t_layer_height_ranges& ranges = object(obj_idx)->layer_height_ranges; + + wxDataViewItem selectable_item = GetSelection(); + int layer_idx = 0; + + if (ranges.size() == 1) + selectable_item = m_objects_model->GetParent(selectable_item); + else { + // May be not a best solution #ys_FIXME + t_layer_height_ranges::iterator layer_selected = ranges.find(range); + t_layer_height_ranges::iterator it = ranges.begin(); + while (it != layer_selected) { + it++; + layer_idx++; + } + } + + wxDataViewItem layer_item = m_objects_model->GetItemByLayerId(obj_idx, layer_idx); + del_subobject_item(layer_item); + + select_item(selectable_item); +} + +void ObjectList::add_layer_range(const std::pair& range) +{ + +} + void ObjectList::init_objects() { m_objects = wxGetApp().model_objects(); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 6963805e9..388369137 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -270,6 +270,8 @@ public: // Remove objects/sub-object from the list void remove(); + void del_layer_range(const std::pair& range); + void add_layer_range(const std::pair& range); void init_objects(); bool multiple_selection() const ; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 4511ab8ac..dbe19dff5 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1098,25 +1098,35 @@ wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_id return wxDataViewItem(0); } -wxDataViewItem ObjectDataViewModel::GetItemByInstanceId(int obj_idx, int inst_idx) +wxDataViewItem ObjectDataViewModel::GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type) { if (obj_idx >= m_objects.size() || obj_idx < 0) { printf("Error! Out of objects range.\n"); return wxDataViewItem(0); } - auto instances_item = GetInstanceRootItem(wxDataViewItem(m_objects[obj_idx])); - if (!instances_item) + auto item = GetItemByType(wxDataViewItem(m_objects[obj_idx]), parent_type); + if (!item) return wxDataViewItem(0); - auto parent = (ObjectDataViewModelNode*)instances_item.GetID();; + auto parent = (ObjectDataViewModelNode*)item.GetID();; for (size_t i = 0; i < parent->GetChildCount(); i++) - if (parent->GetNthChild(i)->m_idx == inst_idx) + if (parent->GetNthChild(i)->m_idx == sub_obj_idx) return wxDataViewItem(parent->GetNthChild(i)); return wxDataViewItem(0); } +wxDataViewItem ObjectDataViewModel::GetItemByInstanceId(int obj_idx, int inst_idx) +{ + return GetItemById(obj_idx, inst_idx, itInstanceRoot); +} + +wxDataViewItem ObjectDataViewModel::GetItemByLayerId(int obj_idx, int layer_idx) +{ + return GetItemById(obj_idx, layer_idx, itLayerRoot); +} + int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const { wxASSERT(item.IsOk()); @@ -1447,6 +1457,11 @@ wxDataViewItem ObjectDataViewModel::GetInstanceRootItem(const wxDataViewItem &it return GetItemByType(item, itInstanceRoot); } +wxDataViewItem ObjectDataViewModel::GetLayerRootItem(const wxDataViewItem &item) const +{ + return GetItemByType(item, itLayerRoot); +} + bool ObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const { if (!item.IsOk()) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index b3d8ebc18..23150a915 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -404,8 +404,10 @@ public: void DeleteVolumeChildren(wxDataViewItem& parent); void DeleteSettings(const wxDataViewItem& parent); wxDataViewItem GetItemById(int obj_idx); + wxDataViewItem GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type); wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); + wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx); int GetIdByItem(const wxDataViewItem& item) const; int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; int GetObjectIdByItem(const wxDataViewItem& item) const; @@ -460,6 +462,7 @@ public: ItemType type) const; wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const; + wxDataViewItem GetLayerRootItem(const wxDataViewItem &item) const; bool IsSettingsItem(const wxDataViewItem &item) const; void UpdateSettingsDigest( const wxDataViewItem &item, const std::vector& categories); -- cgit v1.2.3 From 5f4b7a5292dce6c5e531de06d850006b81f3214c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 31 May 2019 15:29:09 +0200 Subject: ObjectLayers::add_layer_range() -> add a layers range using "Add" button from ObjectLayers sizer --- src/slic3r/GUI/GUI_ObjectList.cpp | 101 +++++++++++++++++++++++++++++++++----- src/slic3r/GUI/GUI_ObjectList.hpp | 4 ++ src/slic3r/GUI/wxExtensions.cpp | 25 +++++++--- src/slic3r/GUI/wxExtensions.hpp | 8 +-- 4 files changed, 116 insertions(+), 22 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index cb815fc72..88d7df6cc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1810,27 +1810,26 @@ void ObjectList::layers_editing() if (!item || obj_idx < 0) return; - wxDataViewItem obj_item = m_objects_model->GetTopParent(item); - + const wxDataViewItem obj_item = m_objects_model->GetTopParent(item); wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(obj_item); + + // if it doesn't exist now if (!layers_item.IsOk()) { - // --->>>--- Just for testing - object(obj_idx)->layer_height_ranges[{ 0.0f, 0.2f }] = 0.1f; - object(obj_idx)->layer_height_ranges[{ 0.2f, 0.4f }] = 0.05f; - object(obj_idx)->layer_height_ranges[{ 0.4f, 0.6f }] = 0.2f; - // ---<<<--- Just for testing - + // create LayerRoor item layers_item = m_objects_model->AddLayersRoot(obj_item); + + if (object(obj_idx)->layer_height_ranges.empty()) + object(obj_idx)->layer_height_ranges[{ 0.0f, 0.2f }] = 0.1f;// some default value + // and create Layer item(s) according to the layer_height_ranges for (const auto range : object(obj_idx)->layer_height_ranges) - { - const std::string label = (boost::format(" %.2f-%.2f ") % range.first.first % range.first.second).str(); - m_objects_model->AddLayersChild(layers_item, label); - } + add_layer_item(range.first, layers_item); } + // select LayerRoor item and expand select_item(layers_item); + Expand(layers_item); } bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume) @@ -2230,7 +2229,83 @@ void ObjectList::del_layer_range(const std::pair& range) select_item(selectable_item); } -void ObjectList::add_layer_range(const std::pair& range) +void ObjectList::add_layer_range(const t_layer_height_range& range) +{ + const int obj_idx = get_selected_obj_idx(); + if (obj_idx < 0) return; + + wxDataViewItem layers_item = GetSelection(); + + t_layer_height_ranges& ranges = object(obj_idx)->layer_height_ranges; + + const t_layer_height_ranges::iterator selected_range = ranges.find(range); + const t_layer_height_ranges::iterator last_range = --ranges.end(); + + if (selected_range->first == last_range->first) + { + const t_layer_height_range new_range = { last_range->first.second, last_range->first.second + 0.2f }; + ranges[new_range] = last_range->second; + add_layer_item(new_range, layers_item); + } + else + { + int layer_idx = 0; + t_layer_height_ranges::iterator next_range = ++ranges.find(range); + + // May be not a best solution #ys_FIXME + t_layer_height_ranges::iterator it = ranges.begin(); + while (it != next_range && it != ranges.end()) { + layer_idx++; + it++; + } + + if (selected_range->first.second == next_range->first.first) + { + const coordf_t delta = (next_range->first.second - next_range->first.first); + if (delta < 0.05f) // next range devision has no mean + return; + + const coordf_t midl_layer = next_range->first.first + 0.5f * delta; + const coordf_t old_height = next_range->second; + t_layer_height_range new_range = { midl_layer, next_range->first.second }; + + // delete old layer + + wxDataViewItem layer_item = m_objects_model->GetItemByLayerId(obj_idx, layer_idx); + del_subobject_item(layer_item); + + // create new 2 layers instead of deleted one + + ranges[new_range] = old_height; + add_layer_item(new_range, layers_item, layer_idx); + + new_range = { selected_range->first.second, midl_layer }; + ranges[new_range] = selected_range->second; + add_layer_item(new_range, layers_item, layer_idx); + } + else + { + const t_layer_height_range new_range = { selected_range->first.second, next_range->first.first }; + ranges[new_range] = selected_range->second; + add_layer_item(new_range, layers_item, layer_idx); + } + } + + changed_object(obj_idx); + + // select item to update layers sizer + select_item(layers_item); +} + +void ObjectList::add_layer_item(const t_layer_height_range& range, + const wxDataViewItem layers_item, + const int layer_idx /* = -1*/) +{ + const std::string label = (boost::format(" %.2f-%.2f ") % range.first % range.second).str(); + m_objects_model->AddLayersChild(layers_item, label, layer_idx); +} + +void ObjectList::edit_layer_range(const std::pair& range) { } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 388369137..15cddd318 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -272,6 +272,10 @@ public: void remove(); void del_layer_range(const std::pair& range); void add_layer_range(const std::pair& range); + void add_layer_item (const std::pair& range, + const wxDataViewItem layers_item, + const int layer_idx = -1); + void edit_layer_range(const std::pair& range); void init_objects(); bool multiple_selection() const ; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index dbe19dff5..adc2e6d07 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -465,14 +465,22 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const wxString& label_range, - const wxString& extruder, - const int idx /*= -1 */) : + const int idx /*= -1 */, + const wxString& extruder) : m_parent(parent), m_type(itLayer), m_idx(idx), m_extruder(extruder) { - m_idx = parent->GetChildCount(); + const int children_cnt = parent->GetChildCount(); + if (idx < 0) + m_idx = children_cnt; + else + { + // update indexes for another Laeyr Nodes + for (int i = m_idx; i < children_cnt; i++) + parent->GetNthChild(i)->SetIdx(i + 1); + } // m_name = wxString::Format(_(L("Layer %s (mm)")), label_range); m_name = _(L("Range")) + label_range + "(" + _(L("mm")) + ")"; m_bmp = create_scaled_bitmap(nullptr, "layers_white"); // FIXME: pass window ptr @@ -742,7 +750,9 @@ wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_i return layer_root_item; } -wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, const std::string& label_range) +wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, + const std::string& label_range, + const int index /* = -1*/) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); @@ -763,8 +773,11 @@ wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_ } // Add layer node - ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, label_range); - layer_root_node->Append(layer_node); + ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, label_range, index); + if (index < 0) + layer_root_node->Append(layer_node); + else + layer_root_node->Insert(layer_node, index); // notify control const wxDataViewItem layer_item((void*)layer_node); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 23150a915..775d89a3b 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -233,8 +233,8 @@ public: ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const wxString& label_range, - const wxString& extruder = wxEmptyString, - const int idx = -1 ); + const int idx = -1, + const wxString& extruder = wxEmptyString ); ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type); @@ -396,7 +396,9 @@ public: wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); - wxDataViewItem AddLayersChild(const wxDataViewItem &parent_item, const std::string& label_range); + wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, + const std::string& label_range, + const int index = -1); wxDataViewItem Delete(const wxDataViewItem &item); wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); void DeleteAll(); -- cgit v1.2.3 From e09207e27e28d37e1873fe4f1c63bbbad3faf6d5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 31 May 2019 15:36:38 +0200 Subject: Fixed OSX and Linux build --- src/slic3r/GUI/GUI_ObjectList.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 88d7df6cc..d9e1e8e82 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2189,8 +2189,11 @@ void ObjectList::remove() select_item(parent); parent = wxDataViewItem(0); } - else if (m_objects_model->GetChildren(parent, wxDataViewItemArray()) == 1) - parent = m_objects_model->GetTopParent(item); + else { + wxDataViewItemArray children; + if (m_objects_model->GetChildren(parent, children) == 1) + parent = m_objects_model->GetTopParent(item); + } } del_subobject_item(item); -- cgit v1.2.3 From 51b18fddeb1b22310171e27b8e606cc0d621f17d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 3 Jun 2019 15:35:21 +0200 Subject: Changed data types --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 37 ++++++++++++++++++------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 1 + src/slic3r/GUI/GUI_ObjectList.cpp | 43 +++++++++++++++++++++---------------- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + 4 files changed, 48 insertions(+), 34 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 5ff650e86..8dae64f3c 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -23,6 +23,8 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : { m_og->label_width = 1; m_og->set_grid_vgap(5); + + m_og->m_on_change = std::bind(&ObjectLayers::on_change, this, std::placeholders::_1, std::placeholders::_2); // Legend for object layers Line line = Line{ "", "" }; @@ -33,9 +35,9 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : def.type = coString; def.width = field_width; - for (const std::string axis : { "Min Z", "Max Z", "Layer height" }) { - def.set_default_value(new ConfigOptionString{ axis }); - std::string label = boost::algorithm::replace_all_copy(axis, " ", "_"); + for (const std::string col : { "Min Z", "Max Z", "Layer height" }) { + def.set_default_value(new ConfigOptionString{ col }); + std::string label = boost::algorithm::replace_all_copy(col, " ", "_"); boost::algorithm::to_lower(label); line.append_option(Option(def, label + "_legend")); @@ -48,7 +50,7 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_bmp_add = ScalableBitmap(parent, "add_copies"); } -static Line create_new_layer(const t_layer_height_ranges::value_type& layer) +static Line create_new_layer(const t_layer_config_ranges::value_type& layer, const int idx) { Line line = Line{ "", "" }; ConfigOptionDef def; @@ -57,16 +59,16 @@ static Line create_new_layer(const t_layer_height_ranges::value_type& layer) def.type = coFloat; def.width = field_width; - std::string label = (boost::format("min_z_%.2f") % layer.first.first).str(); + std::string label = (boost::format("min_z_%d") % idx).str(); def.set_default_value(new ConfigOptionFloat(layer.first.first)); line.append_option(Option(def, label)); - label = (boost::format("max_z_%.2f") % layer.first.second).str(); + label = (boost::format("max_z_%d") % idx).str(); def.set_default_value(new ConfigOptionFloat(layer.first.second)); line.append_option(Option(def, label)); - label = (boost::format("layer_height_%.2f_%.2f") % layer.first.first % layer.first.second).str(); - def.set_default_value(new ConfigOptionFloat(layer.second)); + label = (boost::format("layer_height_%d") % idx).str(); + def.set_default_value(new ConfigOptionFloat(layer.second.option("layer_height")->getFloat())); line.append_option(Option(def, label)); return line; @@ -74,7 +76,7 @@ static Line create_new_layer(const t_layer_height_ranges::value_type& layer) void ObjectLayers::create_layers_list() { - for (const auto layer : m_object->layer_height_ranges) + for (const auto layer : m_object->layer_config_ranges) { auto create_btns = [this, layer](wxWindow* parent) { auto sizer = new wxBoxSizer(wxHORIZONTAL); @@ -100,7 +102,7 @@ void ObjectLayers::create_layers_list() return sizer; }; - Line line = create_new_layer(layer); + Line line = create_new_layer(layer, m_og->get_grid_sizer()->GetEffectiveRowsCount()-1); line.append_widget(create_btns); m_og->append_line(line); } @@ -108,15 +110,15 @@ void ObjectLayers::create_layers_list() void ObjectLayers::create_layer(int id) { - t_layer_height_ranges::iterator layer_range = m_object->layer_height_ranges.begin(); + t_layer_config_ranges::iterator layer_range = m_object->layer_config_ranges.begin(); // May be not a best solution #ys_FIXME - while (id > 0 && layer_range != m_object->layer_height_ranges.end()) { - layer_range++; + while (id > 0 && layer_range != m_object->layer_config_ranges.end()) { + ++layer_range; id--; } - m_og->append_line(create_new_layer(*layer_range)); + m_og->append_line(create_new_layer(*layer_range, m_og->get_grid_sizer()->GetEffectiveRowsCount()-1)); } void ObjectLayers::update_layers_list() @@ -134,7 +136,7 @@ void ObjectLayers::update_layers_list() if (!(type & (itLayerRoot | itLayer))) return; m_object = objects_ctrl->object(obj_idx); - if (!m_object || m_object->layer_height_ranges.empty()) return; + if (!m_object || m_object->layer_config_ranges.empty()) return; // Delete all controls from options group except of the legends @@ -175,5 +177,10 @@ void ObjectLayers::msw_rescale() m_bmp_add.msw_rescale(); } +void ObjectLayers::on_change(t_config_option_key opt_key, const boost::any& value) +{ + +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 0b209d523..6280a7554 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -30,6 +30,7 @@ public: void UpdateAndShow(const bool show) override; void msw_rescale(); + void on_change(t_config_option_key opt_key, const boost::any& value); }; }} diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index d9e1e8e82..9b826f5d8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -700,10 +700,11 @@ void ObjectList::show_context_menu() if (item) { const ItemType type = m_objects_model->GetItemType(item); - if (!(type & (itObject | itVolume | itInstance))) + if (!(type & (itObject | itVolume | itLayer | itInstance))) return; wxMenu* menu = type & itInstance ? &m_menu_instance : + type & itLayer ? &m_menu_layer : m_objects_model->GetParent(item) != wxDataViewItem(0) ? &m_menu_part : printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; @@ -1694,7 +1695,7 @@ void ObjectList::del_instances_from_object(const int obj_idx) void ObjectList::del_layers_from_object(const int obj_idx) { - object(obj_idx)->layer_height_ranges.clear(); // ? #ys_FIXME + object(obj_idx)->layer_config_ranges.clear(); changed_object(obj_idx); } @@ -1739,13 +1740,13 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con object->delete_instance(idx); } else if (type == itLayer) { - t_layer_height_ranges::iterator layer_range = object->layer_height_ranges.begin(); + t_layer_config_ranges::iterator layer_range = object->layer_config_ranges.begin(); int id = idx; - while (id > 0 && layer_range != object->layer_height_ranges.end()) { + while (id > 0 && layer_range != object->layer_config_ranges.end()) { layer_range++; id--; } - object->layer_height_ranges.erase(layer_range); + object->layer_config_ranges.erase(layer_range); } else return false; @@ -1816,14 +1817,16 @@ void ObjectList::layers_editing() // if it doesn't exist now if (!layers_item.IsOk()) { - // create LayerRoor item + // create LayerRoot item layers_item = m_objects_model->AddLayersRoot(obj_item); + + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; - if (object(obj_idx)->layer_height_ranges.empty()) - object(obj_idx)->layer_height_ranges[{ 0.0f, 0.2f }] = 0.1f;// some default value + if (ranges.empty()) + ranges[{ 0.0f, 0.2f }] = *DynamicPrintConfig::new_from_defaults_keys({"layer_height"});// some default value - // and create Layer item(s) according to the layer_height_ranges - for (const auto range : object(obj_idx)->layer_height_ranges) + // and create Layer item(s) according to the layer_config_ranges + for (const auto range : ranges) add_layer_item(range.first, layers_item); } @@ -2239,10 +2242,10 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) wxDataViewItem layers_item = GetSelection(); - t_layer_height_ranges& ranges = object(obj_idx)->layer_height_ranges; + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; - const t_layer_height_ranges::iterator selected_range = ranges.find(range); - const t_layer_height_ranges::iterator last_range = --ranges.end(); + const t_layer_config_ranges::iterator selected_range = ranges.find(range); + const t_layer_config_ranges::iterator last_range = --ranges.end(); if (selected_range->first == last_range->first) { @@ -2253,13 +2256,13 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) else { int layer_idx = 0; - t_layer_height_ranges::iterator next_range = ++ranges.find(range); + t_layer_config_ranges::iterator next_range = ++ranges.find(range); // May be not a best solution #ys_FIXME - t_layer_height_ranges::iterator it = ranges.begin(); + t_layer_config_ranges::iterator it = ranges.begin(); while (it != next_range && it != ranges.end()) { layer_idx++; - it++; + ++it; } if (selected_range->first.second == next_range->first.first) @@ -2269,7 +2272,8 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) return; const coordf_t midl_layer = next_range->first.first + 0.5f * delta; - const coordf_t old_height = next_range->second; + // #ys_FIXME May be it should be copied just a "layer_height" option + const /*coordf_t*/auto old_config = next_range->second; t_layer_height_range new_range = { midl_layer, next_range->first.second }; // delete old layer @@ -2279,7 +2283,7 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) // create new 2 layers instead of deleted one - ranges[new_range] = old_height; + ranges[new_range] = old_config; add_layer_item(new_range, layers_item, layer_idx); new_range = { selected_range->first.second, midl_layer }; @@ -2996,7 +3000,8 @@ void ObjectList::msw_rescale() for (MenuWithSeparators* menu : { &m_menu_object, &m_menu_part, &m_menu_sla_object, - &m_menu_instance }) + &m_menu_instance, + &m_menu_layer }) msw_rescale_menu(menu); Layout(); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 15cddd318..5b4fd4c49 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -119,6 +119,7 @@ class ObjectList : public wxDataViewCtrl MenuWithSeparators m_menu_part; MenuWithSeparators m_menu_sla_object; MenuWithSeparators m_menu_instance; + MenuWithSeparators m_menu_layer; wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr }; -- cgit v1.2.3 From 79a89c4c8fd5b09374ba981fea7c3a3da6711236 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 4 Jun 2019 11:51:25 +0200 Subject: Some code review for avoid use of OptionsGroup --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 153 ++++++++++++++++++------------------ src/slic3r/GUI/GUI_ObjectLayers.hpp | 6 +- 2 files changed, 81 insertions(+), 78 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 8dae64f3c..1bd57e0d8 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -21,90 +21,100 @@ namespace GUI ObjectLayers::ObjectLayers(wxWindow* parent) : OG_Settings(parent, true) { - m_og->label_width = 1; - m_og->set_grid_vgap(5); + m_grid_sizer = new wxFlexGridSizer(3, 5, 5); // "Min Z", "Max Z", "Layer height" & buttons sizer + m_grid_sizer->SetFlexibleDirection(wxHORIZONTAL); - m_og->m_on_change = std::bind(&ObjectLayers::on_change, this, std::placeholders::_1, std::placeholders::_2); - // Legend for object layers - Line line = Line{ "", "" }; - - ConfigOptionDef def; - def.label = ""; - def.gui_type = "legend"; - def.type = coString; - def.width = field_width; - for (const std::string col : { "Min Z", "Max Z", "Layer height" }) { - def.set_default_value(new ConfigOptionString{ col }); - std::string label = boost::algorithm::replace_all_copy(col, " ", "_"); - boost::algorithm::to_lower(label); - line.append_option(Option(def, label + "_legend")); + auto temp = new wxStaticText(m_parent, wxID_ANY, _(L(col)), wxDefaultPosition, /*size*/wxDefaultSize, wxST_ELLIPSIZE_MIDDLE); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + temp->SetFont(wxGetApp().bold_font()); - m_legends.push_back(label + "_legend"); + m_grid_sizer->Add(temp); } - m_og->append_line(line); + m_og->sizer->Clear(true); + m_og->sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 5); m_bmp_delete = ScalableBitmap(parent, "remove_copies"/*"cross"*/); m_bmp_add = ScalableBitmap(parent, "add_copies"); } -static Line create_new_layer(const t_layer_config_ranges::value_type& layer, const int idx) +wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges::value_type& layer) { - Line line = Line{ "", "" }; - ConfigOptionDef def; - def.label = ""; - def.gui_type = ""; - def.type = coFloat; - def.width = field_width; - - std::string label = (boost::format("min_z_%d") % idx).str(); - def.set_default_value(new ConfigOptionFloat(layer.first.first)); - line.append_option(Option(def, label)); - - label = (boost::format("max_z_%d") % idx).str(); - def.set_default_value(new ConfigOptionFloat(layer.first.second)); - line.append_option(Option(def, label)); - - label = (boost::format("layer_height_%d") % idx).str(); - def.set_default_value(new ConfigOptionFloat(layer.second.option("layer_height")->getFloat())); - line.append_option(Option(def, label)); - - return line; + auto size = wxSize(field_width * em_unit(m_parent), wxDefaultCoord); + + // Add control for the "Min Z" + wxString text_value = double_to_string(layer.first.first); + auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_PROCESS_ENTER); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + + temp->Bind(wxEVT_TEXT_ENTER, ([this, temp](wxEvent& e) + { + + }), temp->GetId()); + + temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e) + { + + }), temp->GetId()); + + + temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event) + { + // select all text using Ctrl+A + if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) + temp->SetSelection(-1, -1); //select all + event.Skip(); + })); + + m_grid_sizer->Add(temp); + + // Add control for the "Max Z" + text_value = double_to_string(layer.first.second); + temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_PROCESS_ENTER); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + + m_grid_sizer->Add(temp); + + // Add control for the "Layer height" + auto sizer = new wxBoxSizer(wxHORIZONTAL); + + text_value = double_to_string(layer.second.option("layer_height")->getFloat()); + temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_PROCESS_ENTER); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + sizer->Add(temp); + + m_grid_sizer->Add(sizer); + + return sizer; } void ObjectLayers::create_layers_list() { for (const auto layer : m_object->layer_config_ranges) { - auto create_btns = [this, layer](wxWindow* parent) { - auto sizer = new wxBoxSizer(wxHORIZONTAL); + auto sizer = create_layer_without_buttons(layer); - auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); - del_btn->SetToolTip(_(L("Remove layer"))); + wxWindow* parent = m_parent; + auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + del_btn->SetToolTip(_(L("Remove layer"))); - sizer->Add(del_btn, 0, wxRIGHT, em_unit(parent)); + sizer->Add(del_btn, 0, wxRIGHT | wxLEFT, em_unit(parent)); - del_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { - wxGetApp().obj_list()->del_layer_range(layer.first); - }); + del_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { + wxGetApp().obj_list()->del_layer_range(layer.first); + }); - auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); - add_btn->SetToolTip(_(L("Add layer"))); + auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); + add_btn->SetToolTip(_(L("Add layer"))); - sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); + sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); - add_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { - wxGetApp().obj_list()->add_layer_range(layer.first); - }); - - return sizer; - }; - - Line line = create_new_layer(layer, m_og->get_grid_sizer()->GetEffectiveRowsCount()-1); - line.append_widget(create_btns); - m_og->append_line(line); + add_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { + wxGetApp().obj_list()->add_layer_range(layer.first); + }); } } @@ -117,8 +127,8 @@ void ObjectLayers::create_layer(int id) ++layer_range; id--; } - - m_og->append_line(create_new_layer(*layer_range, m_og->get_grid_sizer()->GetEffectiveRowsCount()-1)); + + create_layer_without_buttons(*layer_range); } void ObjectLayers::update_layers_list() @@ -140,19 +150,17 @@ void ObjectLayers::update_layers_list() // Delete all controls from options group except of the legends - auto grid_sizer = m_og->get_grid_sizer(); - const int cols = grid_sizer->GetEffectiveColsCount(); - const int rows = grid_sizer->GetEffectiveRowsCount(); + const int cols = m_grid_sizer->GetEffectiveColsCount(); + const int rows = m_grid_sizer->GetEffectiveRowsCount(); for (int idx = cols*rows-1; idx >= cols; idx--) { - wxSizerItem* t = grid_sizer->GetItem(idx); + wxSizerItem* t = m_grid_sizer->GetItem(idx); if (t->IsSizer()) t->GetSizer()->Clear(true); - grid_sizer->Remove(idx); + else + t->DeleteWindows(); + m_grid_sizer->Remove(idx); } - m_og->clear_fields_except_of(m_legends); - - // Add new control according to the selected item if (type & itLayerRoot) @@ -177,10 +185,5 @@ void ObjectLayers::msw_rescale() m_bmp_add.msw_rescale(); } -void ObjectLayers::on_change(t_config_option_key opt_key, const boost::any& value) -{ - -} - } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 6280a7554..329452950 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -18,19 +18,19 @@ class ObjectLayers : public OG_Settings ScalableBitmap m_bmp_add; ModelObject* m_object {nullptr}; - std::vector m_legends; + wxFlexGridSizer* m_grid_sizer; public: ObjectLayers(wxWindow* parent); ~ObjectLayers() {} - void create_layers_list(); + wxSizer* create_layer_without_buttons(const std::map, DynamicPrintConfig>::value_type& layer); void create_layer(int id); + void create_layers_list(); void update_layers_list(); void UpdateAndShow(const bool show) override; void msw_rescale(); - void on_change(t_config_option_key opt_key, const boost::any& value); }; }} -- cgit v1.2.3 From 475696167884ac80cf554b9dd6bad772facd3e8c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 4 Jun 2019 15:22:29 +0200 Subject: Added LayerRangeEditor class for universally editing of the layer_range's parameters + Implemented layer_height editing --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 91 +++++++++++++++++++++++++------------ src/slic3r/GUI/GUI_ObjectLayers.hpp | 16 +++++++ src/slic3r/GUI/GUI_ObjectList.cpp | 8 +++- src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- 4 files changed, 85 insertions(+), 32 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 1bd57e0d8..bba39f76a 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -46,44 +46,21 @@ wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges: auto size = wxSize(field_width * em_unit(m_parent), wxDefaultCoord); // Add control for the "Min Z" - wxString text_value = double_to_string(layer.first.first); - auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_PROCESS_ENTER); - temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - - temp->Bind(wxEVT_TEXT_ENTER, ([this, temp](wxEvent& e) - { - - }), temp->GetId()); - - temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e) - { - - }), temp->GetId()); - - - temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event) - { - // select all text using Ctrl+A - if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) - temp->SetSelection(-1, -1); //select all - event.Skip(); - })); - + auto temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.first), size); m_grid_sizer->Add(temp); // Add control for the "Max Z" - text_value = double_to_string(layer.first.second); - temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_PROCESS_ENTER); - temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - + temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.second), size); m_grid_sizer->Add(temp); // Add control for the "Layer height" auto sizer = new wxBoxSizer(wxHORIZONTAL); - text_value = double_to_string(layer.second.option("layer_height")->getFloat()); - temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_PROCESS_ENTER); - temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + const wxString text_value = double_to_string(layer.second.option("layer_height")->getFloat()); + + temp = new LayerRangeEditor(m_parent, text_value, size, [temp, layer](coordf_t layer_height) { + wxGetApp().obj_list()->edit_layer_range(layer.first, layer_height); + } ); sizer->Add(temp); m_grid_sizer->Add(sizer); @@ -185,5 +162,59 @@ void ObjectLayers::msw_rescale() m_bmp_add.msw_rescale(); } +LayerRangeEditor::LayerRangeEditor( wxWindow* parent, + const wxString& value, + const wxSize& size, + std::function edit_fn + ) : + wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, size, wxTE_PROCESS_ENTER) +{ + this->SetFont(wxGetApp().normal_font()); + + this->Bind(wxEVT_TEXT_ENTER, ([this, edit_fn](wxEvent& e) + { + edit_fn(get_value()); + m_enter_pressed = true; + }), this->GetId()); + + this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn](wxEvent& e) + { + e.Skip(); + if (!m_enter_pressed) + edit_fn(get_value()); + m_enter_pressed = false; + }), this->GetId()); + + + this->Bind(wxEVT_CHAR, ([this](wxKeyEvent& event) + { + // select all text using Ctrl+A + if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) + this->SetSelection(-1, -1); //select all + event.Skip(); + })); +} + +coordf_t LayerRangeEditor::get_value() +{ + wxString str = GetValue(); + + coordf_t layer_height; + // Replace the first occurence of comma in decimal number. + str.Replace(",", ".", false); + if (str == ".") + layer_height = 0.0; + else + { + if (!str.ToCDouble(&layer_height) || layer_height < 0.0f) + { + show_error(m_parent, _(L("Invalid numeric input."))); + SetValue(double_to_string(layer_height)); + } + } + + return layer_height; +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 329452950..3aa3cb967 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -12,6 +12,22 @@ class ModelObject; namespace GUI { class ConfigOptionsGroup; +class LayerRangeEditor : public wxTextCtrl +{ + bool m_enter_pressed { false }; +public: + LayerRangeEditor( wxWindow* parent, + const wxString& value = wxEmptyString, + const wxSize& size = wxDefaultSize, + std::function edit_fn = [](coordf_t) {; } + ); + ~LayerRangeEditor() {} + + +private: + coordf_t get_value(); +}; + class ObjectLayers : public OG_Settings { ScalableBitmap m_bmp_delete; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 9b826f5d8..25df5c4fb 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2312,9 +2312,15 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, m_objects_model->AddLayersChild(layers_item, label, layer_idx); } -void ObjectList::edit_layer_range(const std::pair& range) +void ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) { + const int obj_idx = get_selected_obj_idx(); + if (obj_idx < 0) return; + + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; + DynamicPrintConfig* config = &ranges[range]; + config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); } void ObjectList::init_objects() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 5b4fd4c49..5e24b9659 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -276,7 +276,7 @@ public: void add_layer_item (const std::pair& range, const wxDataViewItem layers_item, const int layer_idx = -1); - void edit_layer_range(const std::pair& range); + void edit_layer_range(const std::pair& range, coordf_t layer_height); void init_objects(); bool multiple_selection() const ; -- cgit v1.2.3 From 213635f5596193008a96e1f910b8e2da507e9f9d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 4 Jun 2019 17:30:44 +0200 Subject: Implemented range's min/max Z editing --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 46 ++++++++++++++++++++++--------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 4 ++-- src/slic3r/GUI/GUI_ObjectList.cpp | 28 ++++++++++++++++++++++ src/slic3r/GUI/GUI_ObjectList.hpp | 2 ++ 4 files changed, 59 insertions(+), 21 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index bba39f76a..de1c95fc9 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -43,26 +43,31 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges::value_type& layer) { - auto size = wxSize(field_width * em_unit(m_parent), wxDefaultCoord); - // Add control for the "Min Z" - auto temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.first), size); + auto temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.first), + [layer](coordf_t min_z) { + wxGetApp().obj_list()->edit_layer_range(layer.first, { min_z, layer.first.second }); + }); + m_grid_sizer->Add(temp); // Add control for the "Max Z" - temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.second), size); + temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.second), + [layer](coordf_t max_z) { + wxGetApp().obj_list()->edit_layer_range(layer.first, { layer.first.first, max_z }); + }); + m_grid_sizer->Add(temp); // Add control for the "Layer height" - auto sizer = new wxBoxSizer(wxHORIZONTAL); - - const wxString text_value = double_to_string(layer.second.option("layer_height")->getFloat()); - - temp = new LayerRangeEditor(m_parent, text_value, size, [temp, layer](coordf_t layer_height) { + temp = new LayerRangeEditor(m_parent, + double_to_string(layer.second.option("layer_height")->getFloat()), + [layer](coordf_t layer_height) { wxGetApp().obj_list()->edit_layer_range(layer.first, layer_height); - } ); - sizer->Add(temp); + }, false ); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(temp); m_grid_sizer->Add(sizer); return sizer; @@ -164,25 +169,28 @@ void ObjectLayers::msw_rescale() LayerRangeEditor::LayerRangeEditor( wxWindow* parent, const wxString& value, - const wxSize& size, - std::function edit_fn + std::function edit_fn, + const bool deletable_after_change ) : - wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, size, wxTE_PROCESS_ENTER) + wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, + wxSize(field_width * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) { this->SetFont(wxGetApp().normal_font()); this->Bind(wxEVT_TEXT_ENTER, ([this, edit_fn](wxEvent& e) { - edit_fn(get_value()); m_enter_pressed = true; + edit_fn(get_value()); }), this->GetId()); - this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn](wxEvent& e) + this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn, deletable_after_change](wxEvent& e) { - e.Skip(); - if (!m_enter_pressed) + if (!deletable_after_change) + e.Skip(); + if (!m_enter_pressed) { + m_enter_pressed = false; edit_fn(get_value()); - m_enter_pressed = false; + } }), this->GetId()); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 3aa3cb967..f34dd1314 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -18,8 +18,8 @@ class LayerRangeEditor : public wxTextCtrl public: LayerRangeEditor( wxWindow* parent, const wxString& value = wxEmptyString, - const wxSize& size = wxDefaultSize, - std::function edit_fn = [](coordf_t) {; } + std::function edit_fn = [](coordf_t) {}, + const bool deletable_after_change = true ); ~LayerRangeEditor() {} diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 25df5c4fb..96d071d54 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2265,6 +2265,9 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) ++it; } + if (selected_range->first.second > next_range->first.first) + return; // range devision has no mean + if (selected_range->first.second == next_range->first.first) { const coordf_t delta = (next_range->first.second - next_range->first.first); @@ -2323,6 +2326,31 @@ void ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t la config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); } +void ObjectList::edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range) +{ + const int obj_idx = get_selected_obj_idx(); + if (obj_idx < 0) return; + + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; + + const DynamicPrintConfig config = ranges[range]; + + ranges.erase(range); + ranges[new_range] = config; + + wxDataViewItem root_item = m_objects_model->GetLayerRootItem(m_objects_model->GetItemById(obj_idx)); + m_objects_model->DeleteChildren(root_item); + + if (root_item.IsOk()) + // create Layer item(s) according to the layer_config_ranges + for (const auto r : ranges) + add_layer_item(r.first, root_item); + + // To update(recreate) layers sizer call select_item for LayerRoot item expand + select_item(root_item); + Expand(root_item); +} + void ObjectList::init_objects() { m_objects = wxGetApp().model_objects(); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 5e24b9659..c970a23a0 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -277,6 +277,8 @@ public: const wxDataViewItem layers_item, const int layer_idx = -1); void edit_layer_range(const std::pair& range, coordf_t layer_height); + void edit_layer_range(const std::pair& range, + const std::pair& new_range); void init_objects(); bool multiple_selection() const ; -- cgit v1.2.3 From 567f382938b7939c4266b2ffcc3e14d91f9a80a1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 5 Jun 2019 11:03:46 +0200 Subject: Implemented focusing of the last edited range --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 73 +++++++++++++++++++++++++++++-------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 19 +++++++--- src/slic3r/GUI/GUI_ObjectList.cpp | 8 ++-- 3 files changed, 76 insertions(+), 24 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index de1c95fc9..1f0511acb 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -43,28 +43,67 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges::value_type& layer) { + const bool is_last_edited_range = layer.first == m_last_edited_range; + // Add control for the "Min Z" + auto temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.first), - [layer](coordf_t min_z) { - wxGetApp().obj_list()->edit_layer_range(layer.first, { min_z, layer.first.second }); - }); + [layer, this](coordf_t min_z) + { + if (fabs(min_z - layer.first.first) < EPSILON) { + m_selection_type = sitUndef; + return false; // LayersList would not be updated/recreated + } + + // data for next focusing + m_last_edited_range = { min_z, layer.first.second }; + m_selection_type = sitMinZ; + + wxGetApp().obj_list()->edit_layer_range(layer.first, m_last_edited_range); + return true; // LayersList will be updated/recreated + } ); + + if (is_last_edited_range && m_selection_type == sitMinZ) { + temp->SetFocus(); + temp->SetInsertionPointEnd(); + } m_grid_sizer->Add(temp); // Add control for the "Max Z" + temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.second), - [layer](coordf_t max_z) { - wxGetApp().obj_list()->edit_layer_range(layer.first, { layer.first.first, max_z }); + [layer, this](coordf_t max_z) + { + if (fabs(max_z - layer.first.second) < EPSILON) { + m_selection_type = sitUndef; + return false; // LayersList would not be updated/recreated + } + + // data for next focusing + m_last_edited_range = { layer.first.first, max_z }; + m_selection_type = sitMaxZ; + + wxGetApp().obj_list()->edit_layer_range(layer.first, m_last_edited_range); + return true; // LayersList will not be updated/recreated }); + + if (is_last_edited_range && m_selection_type == sitMaxZ) { + temp->SetFocus(); + temp->SetInsertionPointEnd(); + } m_grid_sizer->Add(temp); // Add control for the "Layer height" + temp = new LayerRangeEditor(m_parent, double_to_string(layer.second.option("layer_height")->getFloat()), - [layer](coordf_t layer_height) { + [layer, this](coordf_t layer_height) + { wxGetApp().obj_list()->edit_layer_range(layer.first, layer_height); - }, false ); + return false; // LayersList would not be updated/recreated + }); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(temp); @@ -169,8 +208,7 @@ void ObjectLayers::msw_rescale() LayerRangeEditor::LayerRangeEditor( wxWindow* parent, const wxString& value, - std::function edit_fn, - const bool deletable_after_change + std::function edit_fn ) : wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, wxSize(field_width * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) @@ -179,18 +217,23 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, this->Bind(wxEVT_TEXT_ENTER, ([this, edit_fn](wxEvent& e) { - m_enter_pressed = true; - edit_fn(get_value()); + m_enter_pressed = true; + // If LayersList wasn't updated/recreated, we can call wxEVT_KILL_FOCUS.Skip() + if ( !edit_fn(get_value()) ) + m_call_kill_focus = true; }), this->GetId()); - this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn, deletable_after_change](wxEvent& e) + this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn](wxEvent& e) { - if (!deletable_after_change) - e.Skip(); if (!m_enter_pressed) { m_enter_pressed = false; - edit_fn(get_value()); + + // If LayersList wasn't updated/recreated, we should call e.Skip() + if ( !edit_fn(get_value()) ) + e.Skip(); } + else if (m_call_kill_focus) + e.Skip(); }), this->GetId()); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index f34dd1314..e69a6173a 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -14,16 +14,16 @@ class ConfigOptionsGroup; class LayerRangeEditor : public wxTextCtrl { - bool m_enter_pressed { false }; + bool m_enter_pressed { false }; + bool m_call_kill_focus { false }; + public: LayerRangeEditor( wxWindow* parent, const wxString& value = wxEmptyString, - std::function edit_fn = [](coordf_t) {}, - const bool deletable_after_change = true + std::function edit_fn = [](coordf_t) {return false; } ); ~LayerRangeEditor() {} - private: coordf_t get_value(); }; @@ -34,7 +34,16 @@ class ObjectLayers : public OG_Settings ScalableBitmap m_bmp_add; ModelObject* m_object {nullptr}; - wxFlexGridSizer* m_grid_sizer; + wxFlexGridSizer* m_grid_sizer; + std::pair m_last_edited_range; + + enum SelectedItemType + { + sitUndef, + sitMinZ, + sitMaxZ, + sitLayerHeight, + } m_selection_type {sitUndef}; public: ObjectLayers(wxWindow* parent); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 96d071d54..04423e359 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2212,7 +2212,7 @@ void ObjectList::del_layer_range(const std::pair& range) const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return; - t_layer_height_ranges& ranges = object(obj_idx)->layer_height_ranges; + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; wxDataViewItem selectable_item = GetSelection(); int layer_idx = 0; @@ -2221,10 +2221,10 @@ void ObjectList::del_layer_range(const std::pair& range) selectable_item = m_objects_model->GetParent(selectable_item); else { // May be not a best solution #ys_FIXME - t_layer_height_ranges::iterator layer_selected = ranges.find(range); - t_layer_height_ranges::iterator it = ranges.begin(); + t_layer_config_ranges::iterator layer_selected = ranges.find(range); + t_layer_config_ranges::iterator it = ranges.begin(); while (it != layer_selected) { - it++; + ++it; layer_idx++; } } -- cgit v1.2.3 From 1090105b6879b0f0212abd4259bd54e86471e60f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 5 Jun 2019 11:50:59 +0200 Subject: Experiments with updating layer_config_ranges from UI + Fixed OSX build --- src/slic3r/GUI/GUI_ObjectLayers.hpp | 10 +++++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 15 +++++++++------ src/slic3r/GUI/Selection.cpp | 3 ++- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index e69a6173a..aa09e64a6 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -12,6 +12,10 @@ class ModelObject; namespace GUI { class ConfigOptionsGroup; +typedef double coordf_t; +typedef std::pair t_layer_height_range; +typedef std::map t_layer_config_ranges; + class LayerRangeEditor : public wxTextCtrl { bool m_enter_pressed { false }; @@ -34,8 +38,8 @@ class ObjectLayers : public OG_Settings ScalableBitmap m_bmp_add; ModelObject* m_object {nullptr}; - wxFlexGridSizer* m_grid_sizer; - std::pair m_last_edited_range; + wxFlexGridSizer* m_grid_sizer; + t_layer_height_range m_last_edited_range; enum SelectedItemType { @@ -49,7 +53,7 @@ public: ObjectLayers(wxWindow* parent); ~ObjectLayers() {} - wxSizer* create_layer_without_buttons(const std::map, DynamicPrintConfig>::value_type& layer); + wxSizer* create_layer_without_buttons(const t_layer_config_ranges::value_type& layer); void create_layer(int id); void create_layers_list(); void update_layers_list(); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index c970a23a0..24c9f65b2 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -33,6 +33,9 @@ typedef std::map< std::string, std::vector< std::pair typedef std::vector ModelVolumePtrs; +typedef double coordf_t; +typedef std::pair t_layer_height_range; + namespace GUI { wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent); @@ -271,14 +274,14 @@ public: // Remove objects/sub-object from the list void remove(); - void del_layer_range(const std::pair& range); - void add_layer_range(const std::pair& range); - void add_layer_item (const std::pair& range, + void del_layer_range(const t_layer_height_range& range); + void add_layer_range(const t_layer_height_range& range); + void add_layer_item (const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx = -1); - void edit_layer_range(const std::pair& range, coordf_t layer_height); - void edit_layer_range(const std::pair& range, - const std::pair& new_range); + void edit_layer_range(const t_layer_height_range& range, coordf_t layer_height); + void edit_layer_range(const t_layer_height_range& range, + const t_layer_height_range& new_range); void init_objects(); bool multiple_selection() const ; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index ff994c32d..0f364f8a1 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1126,7 +1126,8 @@ void Selection::copy_to_clipboard() dst_object->config = src_object->config; dst_object->sla_support_points = src_object->sla_support_points; dst_object->sla_points_status = src_object->sla_points_status; - dst_object->layer_height_ranges = src_object->layer_height_ranges; +// dst_object->layer_height_ranges = src_object->layer_height_ranges; + dst_object->layer_config_ranges = src_object->layer_config_ranges; // #ys_FIXME_experiment dst_object->layer_height_profile = src_object->layer_height_profile; dst_object->origin_translation = src_object->origin_translation; -- cgit v1.2.3 From 401999b68b3e8e625356a9fc017427aa0903432f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 5 Jun 2019 12:32:59 +0200 Subject: Next try to fix OSX build --- src/slic3r/GUI/GUI_ObjectLayers.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index aa09e64a6..0b404be4f 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -9,13 +9,13 @@ class wxBoxSizer; namespace Slic3r { class ModelObject; -namespace GUI { -class ConfigOptionsGroup; - typedef double coordf_t; typedef std::pair t_layer_height_range; typedef std::map t_layer_config_ranges; +namespace GUI { +class ConfigOptionsGroup; + class LayerRangeEditor : public wxTextCtrl { bool m_enter_pressed { false }; -- cgit v1.2.3 From 67ed89c2405a242370066993c16e26fa26fdb6c4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 5 Jun 2019 13:52:53 +0200 Subject: Fixed OSX build and a bug when for part is able to add "layer_height" option --- src/slic3r/GUI/GUI_ObjectLayers.hpp | 10 +++++++--- src/slic3r/GUI/GUI_ObjectList.cpp | 12 +++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 0b404be4f..bec2a1f49 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -4,18 +4,22 @@ #include "GUI_ObjectSettings.hpp" #include "wxExtensions.hpp" +#ifdef __WXOSX__ +#include "..\libslic3r\PrintConfig.hpp" +#endif + class wxBoxSizer; namespace Slic3r { class ModelObject; +namespace GUI { +class ConfigOptionsGroup; + typedef double coordf_t; typedef std::pair t_layer_height_range; typedef std::map t_layer_config_ranges; -namespace GUI { -class ConfigOptionsGroup; - class LayerRangeEditor : public wxTextCtrl { bool m_enter_pressed { false }; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 04423e359..b7a582062 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1035,7 +1035,17 @@ void ObjectList::get_settings_choice(const wxString& category_name) void ObjectList::get_freq_settings_choice(const wxString& bundle_name) { - const std::vector& options = get_options_for_bundle(bundle_name); + std::vector options = get_options_for_bundle(bundle_name); + + /* Because of we couldn't edited layer_height for ItVolume and itLayer from settings list, + * correct options according to the selected item type : + * remove "layer_height" option + */ + if (m_objects_model->GetItemType(GetSelection()) & (itVolume | itLayer) && bundle_name == _("Layers and Perimeters")) { + const auto layer_height_it = std::find(options.begin(), options.end(), "layer_height"); + if (layer_height_it != options.end()) + options.erase(layer_height_it); + } assert(m_config); auto opt_keys = m_config->keys(); -- cgit v1.2.3 From 44c05fa2099b3c0a7daa96181d07a8d61e8f6397 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 5 Jun 2019 16:47:09 +0200 Subject: Implemented additional settings for layers range (except of "extruder") --- src/slic3r/GUI/GUI_ObjectLayers.hpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 80 +++++++++++++++++++++++++++-------- src/slic3r/GUI/GUI_ObjectList.hpp | 2 + src/slic3r/GUI/GUI_ObjectSettings.cpp | 11 +++-- 4 files changed, 72 insertions(+), 23 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index bec2a1f49..55002ff35 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -5,7 +5,7 @@ #include "wxExtensions.hpp" #ifdef __WXOSX__ -#include "..\libslic3r\PrintConfig.hpp" +#include "../libslic3r/PrintConfig.hpp" #endif class wxBoxSizer; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b7a582062..f68130ddd 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -360,6 +360,21 @@ DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) cons (*m_objects)[obj_idx]->config; } +const t_layer_height_range& ObjectList::get_layer_range_from_item(const wxDataViewItem layer_item, const int obj_idx) const +{ + ModelObject* object = (*m_objects)[obj_idx]; + t_layer_config_ranges::iterator layer_range = object->layer_config_ranges.begin(); + int id = m_objects_model->GetLayerIdByItem(layer_item); + + // May be not a best solution #ys_FIXME + while (id > 0 && layer_range != object->layer_config_ranges.end()) { + ++layer_range; + id--; + } + + return layer_range->first; +} + wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count) { wxArrayString choices; @@ -1037,11 +1052,11 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name) { std::vector options = get_options_for_bundle(bundle_name); - /* Because of we couldn't edited layer_height for ItVolume and itLayer from settings list, + /* Because of we couldn't edited layer_height for ItVolume from settings list, * correct options according to the selected item type : * remove "layer_height" option */ - if (m_objects_model->GetItemType(GetSelection()) & (itVolume | itLayer) && bundle_name == _("Layers and Perimeters")) { + if ((m_objects_model->GetItemType(GetSelection()) & itVolume) && bundle_name == _("Layers and Perimeters")) { const auto layer_height_it = std::find(options.begin(), options.end(), "layer_height"); if (layer_height_it != options.end()) options.erase(layer_height_it); @@ -1833,7 +1848,7 @@ void ObjectList::layers_editing() t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; if (ranges.empty()) - ranges[{ 0.0f, 0.2f }] = *DynamicPrintConfig::new_from_defaults_keys({"layer_height"});// some default value + ranges[{ 0.0f, 0.6f }] = get_default_layer_config(obj_idx); // and create Layer item(s) according to the layer_config_ranges for (const auto range : ranges) @@ -1845,6 +1860,18 @@ void ObjectList::layers_editing() Expand(layers_item); } +DynamicPrintConfig ObjectList::get_default_layer_config(const int obj_idx) +{ + DynamicPrintConfig config; + coordf_t layer_height = object(obj_idx)->config.has("layer_height") ? + object(obj_idx)->config.opt_float("layer_height") : + wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("layer_height"); + config.set_key_value("layer_height",new ConfigOptionFloat(layer_height)); + config.set_key_value("extruder", new ConfigOptionInt(0)); + + return config; +} + bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume) { auto obj_idx = get_selected_obj_idx(); @@ -1937,22 +1964,28 @@ void ObjectList::part_selection_changed() update_and_show_manipulations = true; } else { - auto parent = m_objects_model->GetParent(item); - // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene - obj_idx = m_objects_model->GetIdByItem(parent); + obj_idx = m_objects_model->GetObjectIdByItem(item); + const ItemType type = m_objects_model->GetItemType(item); if (type & itSettings) { - if (m_objects_model->GetParent(parent) == wxDataViewItem(0)) { + const auto parent = m_objects_model->GetParent(item); + const ItemType parent_type = m_objects_model->GetItemType(parent); + + if (parent_type & itObject) { og_name = _(L("Object Settings to modify")); m_config = &(*m_objects)[obj_idx]->config; } - else { + else if (parent_type & itVolume) { og_name = _(L("Part Settings to modify")); - auto main_parent = m_objects_model->GetParent(parent); - obj_idx = m_objects_model->GetIdByItem(main_parent); - const auto volume_id = m_objects_model->GetVolumeIdByItem(parent); + volume_id = m_objects_model->GetVolumeIdByItem(parent); m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; } + else if (parent_type & itLayer) { + og_name = _(L("Layer range Settings to modify")); + + const t_layer_height_range& layer_height_range = get_layer_range_from_item(parent, obj_idx); + m_config = &(*m_objects)[obj_idx]->layer_config_ranges[layer_height_range]; + } update_and_show_settings = true; } else if (type & itVolume) { @@ -1966,12 +1999,14 @@ void ObjectList::part_selection_changed() update_and_show_manipulations = true; // fill m_config by object's values - const int obj_idx_ = m_objects_model->GetObjectIdByItem(item); - m_config = &(*m_objects)[obj_idx_]->config; + m_config = &(*m_objects)[obj_idx]->config; } else if (type & (itLayerRoot|itLayer)) { og_name = type & itLayerRoot ? _(L("Layers Editing")) : _(L("Layer Editing")); update_and_show_layers = true; + + const t_layer_height_range& layer_height_range = get_layer_range_from_item(item, obj_idx); + m_config = &(*m_objects)[obj_idx]->layer_config_ranges[layer_height_range]; } } } @@ -2259,8 +2294,8 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) if (selected_range->first == last_range->first) { - const t_layer_height_range new_range = { last_range->first.second, last_range->first.second + 0.2f }; - ranges[new_range] = last_range->second; + const t_layer_height_range new_range = { last_range->first.second, last_range->first.second + 0.5f }; + ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item); } else @@ -2300,13 +2335,13 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) add_layer_item(new_range, layers_item, layer_idx); new_range = { selected_range->first.second, midl_layer }; - ranges[new_range] = selected_range->second; + ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item, layer_idx); } else { const t_layer_height_range new_range = { selected_range->first.second, next_range->first.first }; - ranges[new_range] = selected_range->second; + ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item, layer_idx); } } @@ -2322,7 +2357,16 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, const int layer_idx /* = -1*/) { const std::string label = (boost::format(" %.2f-%.2f ") % range.first % range.second).str(); - m_objects_model->AddLayersChild(layers_item, label, layer_idx); + const wxDataViewItem layer_item = m_objects_model->AddLayersChild(layers_item, label, layer_idx); + + const int obj_idx = get_selected_obj_idx(); + if (obj_idx < 0) return; + +// auto opt_keys = object(obj_idx)->layer_config_ranges[range].keys(); + const DynamicPrintConfig& config = object(obj_idx)->layer_config_ranges[range]; +// if (!opt_keys.empty() && !(opt_keys.size() == 2 && opt_keys[0] == "layer_height" && opt_keys[1] == "extruder")) + if (config.keys().size() > 2) + select_item(m_objects_model->AddSettingsChild(layer_item)); } void ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 24c9f65b2..ad7587a01 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -235,6 +235,7 @@ public: bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void split(); void layers_editing(); + DynamicPrintConfig get_default_layer_config(const int obj_idx); bool get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); bool is_splittable(); bool selected_instances_of_same_object(); @@ -244,6 +245,7 @@ public: wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; + const t_layer_height_range& get_layer_range_from_item(const wxDataViewItem layer_item, const int obj_idx) const; void changed_object(const int obj_idx = -1) const; void part_selection_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index a4aa7dec2..ab2614895 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -72,6 +72,8 @@ void ObjectSettings::update_settings_list() auto config = wxGetApp().obj_list()->config(); const auto item = objects_ctrl->GetSelection(); + const bool is_layers_range_settings = objects_model->GetItemType(objects_model->GetParent(item)) == itLayer; + if (item && !objects_ctrl->multiple_selection() && config && objects_model->IsSettingsItem(item)) { @@ -119,7 +121,8 @@ void ObjectSettings::update_settings_list() } for (auto& cat : cat_options) { - if (cat.second.size() == 1 && cat.second[0] == "extruder") + if (cat.second.size() == 1 && + (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) continue; auto optgroup = std::make_shared(m_og->ctrl_parent(), _(cat.first), config, false, extra_column); @@ -129,14 +132,14 @@ void ObjectSettings::update_settings_list() optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { wxGetApp().obj_list()->changed_object(); }; - const bool is_extriders_cat = cat.first == "Extruders"; + const bool is_extruders_cat = cat.first == "Extruders"; for (auto& opt : cat.second) { - if (opt == "extruder") + if (opt == "extruder" || is_layers_range_settings && opt == "layer_height") continue; Option option = optgroup->get_option(opt); option.opt.width = 12; - if (is_extriders_cat) + if (is_extruders_cat) option.opt.max = wxGetApp().extruders_cnt(); optgroup->append_single_option_line(option); } -- cgit v1.2.3 From 71cc0fdb535bdf1cb4c35429655ed75debf0afce Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 6 Jun 2019 14:14:29 +0200 Subject: Some code refactoring and improvements --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 79 ++++++++---------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 8 +- src/slic3r/GUI/GUI_ObjectList.cpp | 157 +++++++++++++++++------------------- src/slic3r/GUI/GUI_ObjectList.hpp | 6 +- src/slic3r/GUI/Tab.cpp | 7 +- src/slic3r/GUI/wxExtensions.cpp | 61 +++++++++++--- src/slic3r/GUI/wxExtensions.hpp | 11 ++- 7 files changed, 171 insertions(+), 158 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 1f0511acb..ba0012a2b 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -16,8 +16,6 @@ namespace Slic3r namespace GUI { -#define field_width 8 - ObjectLayers::ObjectLayers(wxWindow* parent) : OG_Settings(parent, true) { @@ -41,27 +39,27 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_bmp_add = ScalableBitmap(parent, "add_copies"); } -wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges::value_type& layer) +wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) { - const bool is_last_edited_range = layer.first == m_last_edited_range; + const bool is_last_edited_range = range == m_last_edited_range; // Add control for the "Min Z" - auto temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.first), - [layer, this](coordf_t min_z) + auto temp = new LayerRangeEditor(m_parent, double_to_string(range.first), + [range, this](coordf_t min_z) { - if (fabs(min_z - layer.first.first) < EPSILON) { - m_selection_type = sitUndef; + if (fabs(min_z - range.first) < EPSILON) { + m_selection_type = sitUndef; return false; // LayersList would not be updated/recreated } // data for next focusing - m_last_edited_range = { min_z, layer.first.second }; + m_last_edited_range = { min_z, range.second }; m_selection_type = sitMinZ; - wxGetApp().obj_list()->edit_layer_range(layer.first, m_last_edited_range); + wxGetApp().obj_list()->edit_layer_range(range, m_last_edited_range); return true; // LayersList will be updated/recreated - } ); + }); if (is_last_edited_range && m_selection_type == sitMinZ) { temp->SetFocus(); @@ -72,19 +70,19 @@ wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges: // Add control for the "Max Z" - temp = new LayerRangeEditor(m_parent, double_to_string(layer.first.second), - [layer, this](coordf_t max_z) + temp = new LayerRangeEditor(m_parent, double_to_string(range.second), + [range, this](coordf_t max_z) { - if (fabs(max_z - layer.first.second) < EPSILON) { + if (fabs(max_z - range.second) < EPSILON) { m_selection_type = sitUndef; return false; // LayersList would not be updated/recreated } // data for next focusing - m_last_edited_range = { layer.first.first, max_z }; + m_last_edited_range = { range.first, max_z }; m_selection_type = sitMaxZ; - wxGetApp().obj_list()->edit_layer_range(layer.first, m_last_edited_range); + wxGetApp().obj_list()->edit_layer_range(range, m_last_edited_range); return true; // LayersList will not be updated/recreated }); @@ -92,20 +90,20 @@ wxSizer* ObjectLayers::create_layer_without_buttons(const t_layer_config_ranges: temp->SetFocus(); temp->SetInsertionPointEnd(); } - + m_grid_sizer->Add(temp); // Add control for the "Layer height" - temp = new LayerRangeEditor(m_parent, - double_to_string(layer.second.option("layer_height")->getFloat()), - [layer, this](coordf_t layer_height) + temp = new LayerRangeEditor(m_parent, + double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), + [range, this](coordf_t layer_height) { - wxGetApp().obj_list()->edit_layer_range(layer.first, layer_height); + wxGetApp().obj_list()->edit_layer_range(range, layer_height); return false; // LayersList would not be updated/recreated }); - auto sizer = new wxBoxSizer(wxHORIZONTAL); + auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(temp); m_grid_sizer->Add(sizer); @@ -116,42 +114,29 @@ void ObjectLayers::create_layers_list() { for (const auto layer : m_object->layer_config_ranges) { - auto sizer = create_layer_without_buttons(layer); + const t_layer_height_range& range = layer.first; + auto sizer = create_layer(range); - wxWindow* parent = m_parent; - auto del_btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + auto del_btn = new ScalableButton(m_parent, wxID_ANY, m_bmp_delete); del_btn->SetToolTip(_(L("Remove layer"))); - sizer->Add(del_btn, 0, wxRIGHT | wxLEFT, em_unit(parent)); + sizer->Add(del_btn, 0, wxRIGHT | wxLEFT, em_unit(m_parent)); - del_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { - wxGetApp().obj_list()->del_layer_range(layer.first); + del_btn->Bind(wxEVT_BUTTON, [this, range](wxEvent &event) { + wxGetApp().obj_list()->del_layer_range(range); }); - auto add_btn = new ScalableButton(parent, wxID_ANY, m_bmp_add); + auto add_btn = new ScalableButton(m_parent, wxID_ANY, m_bmp_add); add_btn->SetToolTip(_(L("Add layer"))); - sizer->Add(add_btn, 0, wxRIGHT, em_unit(parent)); + sizer->Add(add_btn, 0, wxRIGHT, em_unit(m_parent)); - add_btn->Bind(wxEVT_BUTTON, [this, layer](wxEvent &event) { - wxGetApp().obj_list()->add_layer_range(layer.first); + add_btn->Bind(wxEVT_BUTTON, [this, range](wxEvent &event) { + wxGetApp().obj_list()->add_layer_range_after_current(range); }); } } -void ObjectLayers::create_layer(int id) -{ - t_layer_config_ranges::iterator layer_range = m_object->layer_config_ranges.begin(); - - // May be not a best solution #ys_FIXME - while (id > 0 && layer_range != m_object->layer_config_ranges.end()) { - ++layer_range; - id--; - } - - create_layer_without_buttons(*layer_range); -} - void ObjectLayers::update_layers_list() { ObjectList* objects_ctrl = wxGetApp().obj_list(); @@ -187,7 +172,7 @@ void ObjectLayers::update_layers_list() if (type & itLayerRoot) create_layers_list(); else - create_layer(objects_ctrl->GetModel()->GetLayerIdByItem(item)); + create_layer(objects_ctrl->GetModel()->GetLayerRangeByItem(item)); m_parent->Layout(); } @@ -211,7 +196,7 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, std::function edit_fn ) : wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, - wxSize(field_width * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) + wxSize(8 * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) { this->SetFont(wxGetApp().normal_font()); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 55002ff35..562e04972 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -16,9 +16,8 @@ class ModelObject; namespace GUI { class ConfigOptionsGroup; -typedef double coordf_t; -typedef std::pair t_layer_height_range; -typedef std::map t_layer_config_ranges; +typedef double coordf_t; +typedef std::pair t_layer_height_range; class LayerRangeEditor : public wxTextCtrl { @@ -57,8 +56,7 @@ public: ObjectLayers(wxWindow* parent); ~ObjectLayers() {} - wxSizer* create_layer_without_buttons(const t_layer_config_ranges::value_type& layer); - void create_layer(int id); + wxSizer* create_layer(const t_layer_height_range& range); // without_buttons void create_layers_list(); void update_layers_list(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index f68130ddd..3060a166d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -351,30 +351,16 @@ DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) cons 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)); + m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1; assert(obj_idx >= 0 || ((type & itVolume) && vol_idx >=0)); return type & itVolume ?(*m_objects)[obj_idx]->volumes[vol_idx]->config : + type & itLayer ?(*m_objects)[obj_idx]->layer_config_ranges[m_objects_model->GetLayerRangeByItem(item)] : (*m_objects)[obj_idx]->config; } -const t_layer_height_range& ObjectList::get_layer_range_from_item(const wxDataViewItem layer_item, const int obj_idx) const -{ - ModelObject* object = (*m_objects)[obj_idx]; - t_layer_config_ranges::iterator layer_range = object->layer_config_ranges.begin(); - int id = m_objects_model->GetLayerIdByItem(layer_item); - - // May be not a best solution #ys_FIXME - while (id > 0 && layer_range != object->layer_config_ranges.end()) { - ++layer_range; - id--; - } - - return layer_range->first; -} - wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count) { wxArrayString choices; @@ -457,16 +443,23 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item) { if (m_prevent_update_extruder_in_config) return; - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + + const ItemType item_type = m_objects_model->GetItemType(item); + if (item_type & itObject) { const int obj_idx = m_objects_model->GetIdByItem(item); m_config = &(*m_objects)[obj_idx]->config; } else { - const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item)); + const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); + if (item_type & itVolume) + { const int volume_id = m_objects_model->GetVolumeIdByItem(item); if (obj_idx < 0 || volume_id < 0) return; m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; + } + else if (item_type & itLayer) + m_config = &get_item_config(item); } wxVariant variant; @@ -669,7 +662,7 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) const wxPoint pt = get_mouse_position_in_control(); HitTest(pt, item, col); if (!item) -#ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX +#ifdef __WXOSX__ // temporary workaround for OSX // after Yosemite OS X version, HitTest return undefined item item = GetSelection(); if (item) @@ -1668,40 +1661,52 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) ItemType type; m_objects_model->GetItemInfo(item, type, obj_idx, idx); - if (type == itUndef) + if (type & itUndef) return; - if (type == itSettings) - del_settings_from_config(); - else if (type == itInstanceRoot && obj_idx != -1) + if (type & itSettings) + del_settings_from_config(m_objects_model->GetParent(item)); + else if (type & itInstanceRoot && obj_idx != -1) del_instances_from_object(obj_idx); - else if ((type & itLayerRoot) && obj_idx != -1) + else if (type & itLayerRoot && obj_idx != -1) del_layers_from_object(obj_idx); + else if (type & itLayer && obj_idx != -1) + del_layer_from_object(obj_idx, m_objects_model->GetLayerRangeByItem(item)); else if (idx == -1) return; else if (!del_subobject_from_object(obj_idx, idx, type)) return; // If last volume item with warning was deleted, unmark object item - if (type == itVolume && (*m_objects)[obj_idx]->get_mesh_errors_count() == 0) + if (type & itVolume && (*m_objects)[obj_idx]->get_mesh_errors_count() == 0) m_objects_model->DeleteWarningIcon(m_objects_model->GetParent(item)); m_objects_model->Delete(item); } -void ObjectList::del_settings_from_config() +void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item) { - auto opt_keys = m_config->keys(); - if (opt_keys.size() == 1 && opt_keys[0] == "extruder") + const bool is_layer_settings = m_objects_model->GetItemType(parent_item) == itLayer; + + const int opt_cnt = m_config->keys().size(); + if (opt_cnt == 1 && m_config->has("extruder") || + is_layer_settings && opt_cnt == 2 && m_config->has("extruder") && m_config->has("layer_height")) return; + int extruder = -1; if (m_config->has("extruder")) extruder = m_config->option("extruder")->value; + coordf_t layer_height = 0.0; + if (is_layer_settings) + layer_height = m_config->opt_float("layer_height"); + m_config->clear(); if (extruder >= 0) m_config->set_key_value("extruder", new ConfigOptionInt(extruder)); + if (is_layer_settings) + m_config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); } void ObjectList::del_instances_from_object(const int obj_idx) @@ -1718,6 +1723,17 @@ void ObjectList::del_instances_from_object(const int obj_idx) changed_object(obj_idx); } +void ObjectList::del_layer_from_object(const int obj_idx, const t_layer_height_range& layer_range) +{ + const auto del_range = object(obj_idx)->layer_config_ranges.find(layer_range); + if (del_range == object(obj_idx)->layer_config_ranges.end()) + return; + + object(obj_idx)->layer_config_ranges.erase(del_range); + + changed_object(obj_idx); +} + void ObjectList::del_layers_from_object(const int obj_idx) { object(obj_idx)->layer_config_ranges.clear(); @@ -1764,15 +1780,6 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con } object->delete_instance(idx); } - else if (type == itLayer) { - t_layer_config_ranges::iterator layer_range = object->layer_config_ranges.begin(); - int id = idx; - while (id > 0 && layer_range != object->layer_config_ranges.end()) { - layer_range++; - id--; - } - object->layer_config_ranges.erase(layer_range); - } else return false; @@ -1982,9 +1989,7 @@ void ObjectList::part_selection_changed() } else if (parent_type & itLayer) { og_name = _(L("Layer range Settings to modify")); - - const t_layer_height_range& layer_height_range = get_layer_range_from_item(parent, obj_idx); - m_config = &(*m_objects)[obj_idx]->layer_config_ranges[layer_height_range]; + m_config = &get_item_config(parent); } update_and_show_settings = true; } @@ -2005,8 +2010,8 @@ void ObjectList::part_selection_changed() og_name = type & itLayerRoot ? _(L("Layers Editing")) : _(L("Layer Editing")); update_and_show_layers = true; - const t_layer_height_range& layer_height_range = get_layer_range_from_item(item, obj_idx); - m_config = &(*m_objects)[obj_idx]->layer_config_ranges[layer_height_range]; + if (type & itLayer) + m_config = &get_item_config(item); } } } @@ -2252,7 +2257,7 @@ void ObjectList::remove() } } -void ObjectList::del_layer_range(const std::pair& range) +void ObjectList::del_layer_range(const t_layer_height_range& range) { const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return; @@ -2260,73 +2265,58 @@ void ObjectList::del_layer_range(const std::pair& range) t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; wxDataViewItem selectable_item = GetSelection(); - int layer_idx = 0; if (ranges.size() == 1) selectable_item = m_objects_model->GetParent(selectable_item); - else { - // May be not a best solution #ys_FIXME - t_layer_config_ranges::iterator layer_selected = ranges.find(range); - t_layer_config_ranges::iterator it = ranges.begin(); - while (it != layer_selected) { - ++it; - layer_idx++; - } - } - wxDataViewItem layer_item = m_objects_model->GetItemByLayerId(obj_idx, layer_idx); + wxDataViewItem layer_item = m_objects_model->GetItemByLayerRange(obj_idx, range); del_subobject_item(layer_item); select_item(selectable_item); } -void ObjectList::add_layer_range(const t_layer_height_range& range) +void ObjectList::add_layer_range_after_current(const t_layer_height_range& current_range) { const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return; - wxDataViewItem layers_item = GetSelection(); + const wxDataViewItem layers_item = GetSelection(); t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; - const t_layer_config_ranges::iterator selected_range = ranges.find(range); - const t_layer_config_ranges::iterator last_range = --ranges.end(); + const t_layer_height_range& last_range = (--ranges.end())->first; - if (selected_range->first == last_range->first) + if (current_range == last_range) { - const t_layer_height_range new_range = { last_range->first.second, last_range->first.second + 0.5f }; + const t_layer_height_range& new_range = { last_range.second, last_range.second + 0.5f }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item); } else { - int layer_idx = 0; - t_layer_config_ranges::iterator next_range = ++ranges.find(range); - - // May be not a best solution #ys_FIXME - t_layer_config_ranges::iterator it = ranges.begin(); - while (it != next_range && it != ranges.end()) { - layer_idx++; - ++it; - } + const t_layer_height_range& next_range = (++ranges.find(current_range))->first; - if (selected_range->first.second > next_range->first.first) - return; // range devision has no mean + if (current_range.second > next_range.first) + return; // range division has no sense - if (selected_range->first.second == next_range->first.first) + const int layer_idx = m_objects_model->GetItemIdByLayerRange(obj_idx, next_range); + if (layer_idx < 0) + return; + + if (current_range.second == next_range.first) { - const coordf_t delta = (next_range->first.second - next_range->first.first); - if (delta < 0.05f) // next range devision has no mean + const coordf_t delta = (next_range.second - next_range.first); + if (delta < 0.05f) // next range division has no sense return; - const coordf_t midl_layer = next_range->first.first + 0.5f * delta; - // #ys_FIXME May be it should be copied just a "layer_height" option - const /*coordf_t*/auto old_config = next_range->second; - t_layer_height_range new_range = { midl_layer, next_range->first.second }; + const coordf_t midl_layer = next_range.first + 0.5f * delta; + + const auto old_config = ranges.at(next_range); + t_layer_height_range new_range = { midl_layer, next_range.second }; // delete old layer - wxDataViewItem layer_item = m_objects_model->GetItemByLayerId(obj_idx, layer_idx); + wxDataViewItem layer_item = m_objects_model->GetItemByLayerRange(obj_idx, next_range); del_subobject_item(layer_item); // create new 2 layers instead of deleted one @@ -2334,13 +2324,13 @@ void ObjectList::add_layer_range(const t_layer_height_range& range) ranges[new_range] = old_config; add_layer_item(new_range, layers_item, layer_idx); - new_range = { selected_range->first.second, midl_layer }; + new_range = { current_range.second, midl_layer }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item, layer_idx); } else { - const t_layer_height_range new_range = { selected_range->first.second, next_range->first.first }; + const t_layer_height_range new_range = { current_range.second, next_range.first }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item, layer_idx); } @@ -2356,15 +2346,12 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx /* = -1*/) { - const std::string label = (boost::format(" %.2f-%.2f ") % range.first % range.second).str(); - const wxDataViewItem layer_item = m_objects_model->AddLayersChild(layers_item, label, layer_idx); + const wxDataViewItem layer_item = m_objects_model->AddLayersChild(layers_item, range, layer_idx); const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return; -// auto opt_keys = object(obj_idx)->layer_config_ranges[range].keys(); const DynamicPrintConfig& config = object(obj_idx)->layer_config_ranges[range]; -// if (!opt_keys.empty() && !(opt_keys.size() == 2 && opt_keys[0] == "layer_height" && opt_keys[1] == "extruder")) if (config.keys().size() > 2) select_item(m_objects_model->AddSettingsChild(layer_item)); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index ad7587a01..455f9f7a1 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -229,8 +229,9 @@ public: void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void del_object(const int obj_idx); void del_subobject_item(wxDataViewItem& item); - void del_settings_from_config(); + void del_settings_from_config(const wxDataViewItem& parent_item); void del_instances_from_object(const int obj_idx); + void del_layer_from_object(const int obj_idx, const t_layer_height_range& layer_range); void del_layers_from_object(const int obj_idx); bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void split(); @@ -245,7 +246,6 @@ public: wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; - const t_layer_height_range& get_layer_range_from_item(const wxDataViewItem layer_item, const int obj_idx) const; void changed_object(const int obj_idx = -1) const; void part_selection_changed(); @@ -277,7 +277,7 @@ public: // Remove objects/sub-object from the list void remove(); void del_layer_range(const t_layer_height_range& range); - void add_layer_range(const t_layer_height_range& range); + void add_layer_range_after_current(const t_layer_height_range& current_range); void add_layer_item (const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx = -1); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6cd270e5b..045feb75a 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3442,9 +3442,9 @@ void TabSLAMaterial::reload_config() void TabSLAMaterial::update() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) - return; // #ys_FIXME + return; -// #ys_FIXME +// #ys_FIXME. Just a template for this function // m_update_cnt++; // ! something to update // m_update_cnt--; @@ -3542,9 +3542,8 @@ void TabSLAPrint::reload_config() void TabSLAPrint::update() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) - return; // #ys_FIXME + return; -// #ys_FIXME m_update_cnt++; double head_penetration = m_config->opt_float("support_head_penetration"); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index adc2e6d07..ed49c8513 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -464,12 +464,13 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent } ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, - const wxString& label_range, + const t_layer_height_range& layer_range, const int idx /*= -1 */, const wxString& extruder) : m_parent(parent), m_type(itLayer), m_idx(idx), + m_layer_range(layer_range), m_extruder(extruder) { const int children_cnt = parent->GetChildCount(); @@ -481,7 +482,7 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent for (int i = m_idx; i < children_cnt; i++) parent->GetNthChild(i)->SetIdx(i + 1); } -// m_name = wxString::Format(_(L("Layer %s (mm)")), label_range); + const std::string label_range = (boost::format(" %.2f-%.2f ") % layer_range.first % layer_range.second).str(); m_name = _(L("Range")) + label_range + "(" + _(L("mm")) + ")"; m_bmp = create_scaled_bitmap(nullptr, "layers_white"); // FIXME: pass window ptr @@ -751,7 +752,7 @@ wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_i } wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, - const std::string& label_range, + const t_layer_height_range& layer_range, const int index /* = -1*/) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); @@ -773,7 +774,7 @@ wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_ } // Add layer node - ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, label_range, index); + ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, layer_range, index); if (index < 0) layer_root_node->Append(layer_node); else @@ -1122,7 +1123,7 @@ wxDataViewItem ObjectDataViewModel::GetItemById(const int obj_idx, const int sub if (!item) return wxDataViewItem(0); - auto parent = (ObjectDataViewModelNode*)item.GetID();; + auto parent = (ObjectDataViewModelNode*)item.GetID(); for (size_t i = 0; i < parent->GetChildCount(); i++) if (parent->GetNthChild(i)->m_idx == sub_obj_idx) return wxDataViewItem(parent->GetNthChild(i)); @@ -1140,6 +1141,34 @@ wxDataViewItem ObjectDataViewModel::GetItemByLayerId(int obj_idx, int layer_idx) return GetItemById(obj_idx, layer_idx, itLayerRoot); } +wxDataViewItem ObjectDataViewModel::GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range) +{ + if (obj_idx >= m_objects.size() || obj_idx < 0) { + printf("Error! Out of objects range.\n"); + return wxDataViewItem(0); + } + + auto item = GetItemByType(wxDataViewItem(m_objects[obj_idx]), itLayerRoot); + if (!item) + return wxDataViewItem(0); + + auto parent = (ObjectDataViewModelNode*)item.GetID(); + for (size_t i = 0; i < parent->GetChildCount(); i++) + if (parent->GetNthChild(i)->m_layer_range == layer_range) + return wxDataViewItem(parent->GetNthChild(i)); + + return wxDataViewItem(0); +} + +int ObjectDataViewModel::GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range) +{ + wxDataViewItem item = GetItemByLayerRange(obj_idx, layer_range); + if (!item) + return -1; + + return GetLayerIdByItem(item); +} + int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const { wxASSERT(item.IsOk()); @@ -1182,6 +1211,16 @@ int ObjectDataViewModel::GetLayerIdByItem(const wxDataViewItem& item) const return GetIdByItemAndType(item, itLayer); } +t_layer_height_range ObjectDataViewModel::GetLayerRangeByItem(const wxDataViewItem& item) const +{ + wxASSERT(item.IsOk()); + + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); + if (!node || node->m_type != itLayer) + return { 0.0f, 0.0f }; + return node->GetLayerRange(); +} + void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx) { wxASSERT(item.IsOk()); @@ -1196,9 +1235,10 @@ void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type ObjectDataViewModelNode *parent_node = node->GetParent(); if (!parent_node) return; - if (type & (itInstance | itLayer)) - parent_node = node->GetParent()->GetParent(); - if (!parent_node || parent_node->m_type != itObject) { type = itUndef; return; } + + // get top parent (Object) node + while (parent_node->m_type != itObject) + parent_node = parent_node->GetParent(); auto it = find(m_objects.begin(), m_objects.end(), parent_node); if (it != m_objects.end()) @@ -1366,10 +1406,7 @@ wxDataViewItem ObjectDataViewModel::GetTopParent(const wxDataViewItem &item) con ObjectDataViewModelNode *parent_node = node->GetParent(); while (parent_node->m_type != itObject) - { - node = parent_node; - parent_node = node->GetParent(); - } + parent_node = parent_node->GetParent(); return wxDataViewItem((void*)parent_node); } diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 775d89a3b..3f43b0882 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -20,6 +20,8 @@ namespace Slic3r { enum class ModelVolumeType : int; }; +typedef std::pair t_layer_height_range; + #ifdef __WXMSW__ void msw_rescale_menu(wxMenu* menu); #else /* __WXMSW__ */ @@ -179,6 +181,7 @@ class ObjectDataViewModelNode wxBitmap m_empty_bmp; size_t m_volumes_cnt = 0; std::vector< std::string > m_opt_categories; + t_layer_height_range m_layer_range = { 0.0f, 0.0f }; wxString m_name; wxBitmap& m_bmp = m_empty_bmp; @@ -232,7 +235,7 @@ public: } ObjectDataViewModelNode(ObjectDataViewModelNode* parent, - const wxString& label_range, + const t_layer_height_range& layer_range, const int idx = -1, const wxString& extruder = wxEmptyString ); @@ -325,6 +328,7 @@ public: ItemType GetType() const { return m_type; } void SetIdx(const int& idx); int GetIdx() const { return m_idx; } + t_layer_height_range GetLayerRange() const { return m_layer_range; } // use this function only for childrens void AssignAllVal(ObjectDataViewModelNode& from_node) @@ -397,7 +401,7 @@ public: wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, - const std::string& label_range, + const t_layer_height_range& layer_range, const int index = -1); wxDataViewItem Delete(const wxDataViewItem &item); wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); @@ -410,6 +414,8 @@ public: wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx); + wxDataViewItem GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); + int GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); int GetIdByItem(const wxDataViewItem& item) const; int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; int GetObjectIdByItem(const wxDataViewItem& item) const; @@ -480,6 +486,7 @@ public: wxBitmap GetVolumeIcon(const Slic3r::ModelVolumeType vol_type, const bool is_marked = false); void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false); + t_layer_height_range GetLayerRangeByItem(const wxDataViewItem& item) const; }; // ---------------------------------------------------------------------------- -- cgit v1.2.3 From 446e37b1512e507d3f99526e0572c7aacb1c406c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 7 Jun 2019 11:32:46 +0200 Subject: Implemented extruder selection for Layers --- src/slic3r/GUI/GUI_ObjectList.cpp | 10 ++++++++-- src/slic3r/GUI/wxExtensions.cpp | 7 +++++-- src/slic3r/GUI/wxExtensions.hpp | 3 ++- 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 3060a166d..85195f87d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2346,12 +2346,18 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx /* = -1*/) { - const wxDataViewItem layer_item = m_objects_model->AddLayersChild(layers_item, range, layer_idx); - const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return; const DynamicPrintConfig& config = object(obj_idx)->layer_config_ranges[range]; + if (!config.has("extruder")) + return; + + const auto layer_item = m_objects_model->AddLayersChild(layers_item, + range, + config.opt_int("extruder"), + layer_idx); + if (config.keys().size() > 2) select_item(m_objects_model->AddSettingsChild(layer_item)); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index ed49c8513..05cc265c3 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -752,12 +752,15 @@ wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_i } wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, - const t_layer_height_range& layer_range, + const t_layer_height_range& layer_range, + const int extruder/* = 0*/, const int index /* = -1*/) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); + wxString extruder_str = extruder == 0 ? _(L("default")) : wxString::Format("%d", extruder); + // get LayerRoot node ObjectDataViewModelNode *layer_root_node; wxDataViewItem layer_root_item; @@ -774,7 +777,7 @@ wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_ } // Add layer node - ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, layer_range, index); + ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, layer_range, index, extruder_str); if (index < 0) layer_root_node->Append(layer_node); else diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 3f43b0882..8ade7af07 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -401,7 +401,8 @@ public: wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, - const t_layer_height_range& layer_range, + const t_layer_height_range& layer_range, + const int extruder = 0, const int index = -1); wxDataViewItem Delete(const wxDataViewItem &item); wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); -- cgit v1.2.3 From 2fa87044be0796625691702485344059b1832d9f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 10 Jun 2019 10:48:43 +0200 Subject: Implemented update_object_list_by_printer_technology() --- src/slic3r/GUI/GUI_ObjectList.cpp | 118 +++++++++++++++++++++++++++++++++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 5 ++ src/slic3r/GUI/Plater.cpp | 8 ++- 3 files changed, 121 insertions(+), 10 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 85195f87d..dfdaa7171 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1849,24 +1849,41 @@ void ObjectList::layers_editing() // if it doesn't exist now if (!layers_item.IsOk()) { - // create LayerRoot item - layers_item = m_objects_model->AddLayersRoot(obj_item); - t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; - + + // set some default value if (ranges.empty()) ranges[{ 0.0f, 0.6f }] = get_default_layer_config(obj_idx); - // and create Layer item(s) according to the layer_config_ranges - for (const auto range : ranges) - add_layer_item(range.first, layers_item); + // create layer root item + layers_item = add_layer_root_item(obj_item); } + if (!layers_item.IsOk()) + return; // select LayerRoor item and expand select_item(layers_item); Expand(layers_item); } +wxDataViewItem ObjectList::add_layer_root_item(const wxDataViewItem obj_item) +{ + const int obj_idx = m_objects_model->GetIdByItem(obj_item); + if (obj_idx < 0 || + object(obj_idx)->layer_config_ranges.empty() || + printer_technology() == ptSLA) + return wxDataViewItem(0); + + // create LayerRoot item + wxDataViewItem layers_item = m_objects_model->AddLayersRoot(obj_item); + + // and create Layer item(s) according to the layer_config_ranges + for (const auto range : object(obj_idx)->layer_config_ranges) + add_layer_item(range.first, layers_item); + + return layers_item; +} + DynamicPrintConfig ObjectList::get_default_layer_config(const int obj_idx) { DynamicPrintConfig config; @@ -2031,7 +2048,9 @@ void ObjectList::part_selection_changed() if (update_and_show_settings) wxGetApp().obj_settings()->get_og()->set_name(" " + og_name + " "); - if (update_and_show_layers) + if (printer_technology() == ptSLA) + update_and_show_layers = false; + else if (update_and_show_layers) wxGetApp().obj_layers()->get_og()->set_name(" " + og_name + " "); Sidebar& panel = wxGetApp().sidebar(); @@ -2346,7 +2365,7 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx /* = -1*/) { - const int obj_idx = get_selected_obj_idx(); + const int obj_idx = m_objects_model->GetObjectIdByItem(layers_item); if (obj_idx < 0) return; const DynamicPrintConfig& config = object(obj_idx)->layer_config_ranges[range]; @@ -2908,6 +2927,87 @@ void ObjectList::update_settings_items() m_prevent_canvas_selection_update = false; } +// Update settings item for item had it +void ObjectList::update_settings_item_for_item(wxDataViewItem item, wxDataViewItemArray& selections) +{ + const wxDataViewItem& settings_item = m_objects_model->GetSettingsItem(item); + select_item(settings_item ? settings_item : m_objects_model->AddSettingsChild(item)); + + // If settings item was deleted from the list, + // it's need to be deleted from selection array, if it was there + if (settings_item != m_objects_model->GetSettingsItem(item) && + selections.Index(settings_item) != wxNOT_FOUND) { + selections.Remove(settings_item); + + // Select item, if settings_item doesn't exist for item anymore, but was selected + if (selections.Index(item) == wxNOT_FOUND) + selections.Add(item); + } +} + +void ObjectList::update_object_list_by_printer_technology() +{ + m_prevent_canvas_selection_update = true; + wxDataViewItemArray sel; + GetSelections(sel); // stash selection + + wxDataViewItemArray object_items; + m_objects_model->GetChildren(wxDataViewItem(0), object_items); + + for (auto& object_item : object_items) { + // Update Settings Item for object + update_settings_item_for_item(object_item, sel); + + // Update settings for Volumes + wxDataViewItemArray all_object_subitems; + m_objects_model->GetChildren(object_item, all_object_subitems); + for (auto item : all_object_subitems) + if (m_objects_model->GetItemType(item) & itVolume) + // update settings for volume + update_settings_item_for_item(item, sel); + + // Update Layers Items + wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(object_item); + if (!layers_item) + layers_item = add_layer_root_item(object_item); + else if (printer_technology() == ptSLA) { + // If layers root item will be deleted from the list, so + // it's need to be deleted from selection array, if it was there + wxDataViewItemArray del_items; + bool some_layers_was_selected = false; + m_objects_model->GetAllChildren(layers_item, del_items); + for (auto& del_item:del_items) + if (sel.Index(del_item) != wxNOT_FOUND) { + some_layers_was_selected = true; + sel.Remove(del_item); + } + if (sel.Index(layers_item) != wxNOT_FOUND) { + some_layers_was_selected = true; + sel.Remove(layers_item); + } + + // delete all "layers" items + m_objects_model->Delete(layers_item); + + // Select object_item, if layers_item doesn't exist for item anymore, but was some of layer items was/were selected + if (some_layers_was_selected) + sel.Add(object_item); + } + else { + wxDataViewItemArray all_obj_layers; + m_objects_model->GetChildren(layers_item, all_obj_layers); + + for (auto item : all_obj_layers) + // update settings for layer + update_settings_item_for_item(item, sel); + } + } + + // restore selection: + SetSelections(sel); + m_prevent_canvas_selection_update = false; +} + void ObjectList::update_object_menu() { append_menu_items_add_volume(&m_menu_object); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 455f9f7a1..29a8096d4 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -236,6 +236,9 @@ public: bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void split(); void layers_editing(); + + wxDataViewItem add_layer_root_item(const wxDataViewItem obj_item); + DynamicPrintConfig get_default_layer_config(const int obj_idx); bool get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); bool is_splittable(); @@ -305,6 +308,8 @@ public: void last_volume_is_deleted(const int obj_idx); bool has_multi_part_objects(); void update_settings_items(); + void update_settings_item_for_item(wxDataViewItem item, wxDataViewItemArray& selections); + void update_object_list_by_printer_technology(); void update_object_menu(); void instances_to_separated_object(const int obj_idx, const std::set& inst_idx); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cba15d7a9..8e2764bb3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2733,8 +2733,14 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) // update plater with new config wxGetApp().plater()->on_config_change(wxGetApp().preset_bundle->full_config()); + /* Settings list can be changed after printer preset changing, so + * update all settings items for all item had it. + * Furthermore, Layers editing is implemented only for FFF printers + * and for SLA presets they should be deleted + */ if (preset_type == Preset::TYPE_PRINTER) - wxGetApp().obj_list()->update_settings_items(); +// wxGetApp().obj_list()->update_settings_items(); + wxGetApp().obj_list()->update_object_list_by_printer_technology(); } void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) -- cgit v1.2.3 From 2b6e5a0a7077b2d759ced0a551ba482f6e0469dd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 10 Jun 2019 15:22:09 +0200 Subject: Implemented Copy/Paste for Layers. + improved selection (in respect to the Layers) --- src/slic3r/GUI/GUI_ObjectList.cpp | 144 +++++++++++++++++++++++++++----------- src/slic3r/GUI/GUI_ObjectList.hpp | 20 ++++-- src/slic3r/GUI/wxExtensions.cpp | 3 +- 3 files changed, 120 insertions(+), 47 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dfdaa7171..f6dd6c591 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -581,6 +581,56 @@ void ObjectList::selection_changed() part_selection_changed(); } +void ObjectList::fill_layer_config_ranges_cache() +{ + wxDataViewItemArray sel_layers; + GetSelections(sel_layers); + + const int obj_idx = m_objects_model->GetObjectIdByItem(sel_layers[0]); + if (obj_idx < 0 || (int)m_objects->size() <= obj_idx) + return; + + const t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; + m_layer_config_ranges_cache.clear(); + + for (const auto layer_item : sel_layers) + if (m_objects_model->GetItemType(layer_item) & itLayer) { + auto range = m_objects_model->GetLayerRangeByItem(layer_item); + auto it = ranges.find(range); + if (it != ranges.end()) + m_layer_config_ranges_cache[it->first] = it->second; + } +} + +void ObjectList::paste_layers_into_list() +{ + const int obj_idx = m_objects_model->GetObjectIdByItem(GetSelection()); + + if (obj_idx < 0 || (int)m_objects->size() <= obj_idx || + m_layer_config_ranges_cache.empty() || printer_technology() == ptSLA) + return; + + const wxDataViewItem object_item = m_objects_model->GetItemById(obj_idx); + wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(object_item); + if (layers_item) + m_objects_model->Delete(layers_item); + + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; + + // and create Layer item(s) according to the layer_config_ranges + for (const auto range : m_layer_config_ranges_cache) + ranges.emplace(range); + + layers_item = add_layer_root_item(object_item); + + changed_object(obj_idx); + + select_item(layers_item); +#ifndef __WXOSX__ + selection_changed(); +#endif //no __WXOSX__ +} + void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes) { if ((obj_idx < 0) || ((int)m_objects->size() <= obj_idx)) @@ -737,10 +787,18 @@ void ObjectList::key_event(wxKeyEvent& event) } else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/)) select_item_all_children(); - else if (wxGetKeyState(wxKeyCode('C')) && wxGetKeyState(WXK_CONTROL)) - wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY)); - else if (wxGetKeyState(wxKeyCode('V')) && wxGetKeyState(WXK_CONTROL)) - wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); + else if (wxGetKeyState(wxKeyCode('C')) && wxGetKeyState(WXK_CONTROL)) { + if (m_selection_mode & smLayer) + fill_layer_config_ranges_cache(); + else + wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY)); + } + else if (wxGetKeyState(wxKeyCode('V')) && wxGetKeyState(WXK_CONTROL)) { + if (!m_layer_config_ranges_cache.empty()) + paste_layers_into_list(); + else + wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); + } else event.Skip(); } @@ -2104,6 +2162,9 @@ void ObjectList::add_object_to_list(size_t obj_idx) Expand(item); } + // Add layers if it has + add_layer_root_item(item); + #ifndef __WXOSX__ selection_changed(); #endif //__WXMSW__ @@ -2568,22 +2629,18 @@ void ObjectList::update_selections_on_canvas() auto add_to_selection = [this](const wxDataViewItem& item, Selection& selection, int instance_idx, bool as_single_selection) { const ItemType& type = m_objects_model->GetItemType(item); - if ( type == itLayerRoot || m_objects_model->GetParent(item) == wxDataViewItem(0) ) { - wxDataViewItem obj_item = type == itLayerRoot ? m_objects_model->GetParent(item) : item; - selection.add_object(m_objects_model->GetIdByItem(obj_item), as_single_selection); - return; - } + const int obj_idx = m_objects_model->GetObjectIdByItem(item); if (type == itVolume) { - const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item)); const int vol_idx = m_objects_model->GetVolumeIdByItem(item); selection.add_volume(obj_idx, vol_idx, std::max(instance_idx, 0), as_single_selection); } else if (type == itInstance) { - const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); const int inst_idx = m_objects_model->GetInstanceIdByItem(item); selection.add_instance(obj_idx, inst_idx, as_single_selection); } + else + selection.add_object(obj_idx, as_single_selection); }; // stores current instance idx before to clear the selection @@ -2654,11 +2711,13 @@ void ObjectList::select_item_all_children() } else { const auto item = GetSelection(); - // Some volume(instance) is selected => select all volumes(instances) inside the current object - if (m_objects_model->GetItemType(item) & (itVolume | itInstance)) + const ItemType item_type = m_objects_model->GetItemType(item); + // Some volume/layer/instance is selected => select all volumes/layers/instances inside the current object + if (item_type & (itVolume | itInstance | itLayer)) m_objects_model->GetChildren(m_objects_model->GetParent(item), sels); - m_selection_mode = m_objects_model->GetItemType(item)&itVolume ? smVolume : smInstance; + m_selection_mode = item_type&itVolume ? smVolume : + item_type&itLayer ? smLayer : smInstance; } SetSelections(sels); @@ -2677,8 +2736,9 @@ void ObjectList::update_selection_mode() } const ItemType type = m_objects_model->GetItemType(GetSelection()); - m_selection_mode = type&itSettings ? smUndef : - type&itVolume ? smVolume : smInstance; + m_selection_mode = type & itSettings ? smUndef : + type & itLayer ? smLayer : + type & itVolume ? smVolume : smInstance; } // check last selected item. If is it possible to select it @@ -2689,33 +2749,37 @@ bool ObjectList::check_last_selection(wxString& msg_str) const bool is_shift_pressed = wxGetKeyState(WXK_SHIFT); - /* We can't mix Parts and Objects/Instances. + /* We can't mix Volumes, Layers and Objects/Instances. * So, show information about it */ const ItemType type = m_objects_model->GetItemType(m_last_selected_item); - // check a case of a selection of the Parts from different Objects - bool impossible_multipart_selection = false; - if (type & itVolume && m_selection_mode == smVolume) - { + // check a case of a selection of the same type items from different Objects + auto impossible_multi_selection = [type, this](const ItemType item_type, const SELECTION_MODE selection_mode) { + if (!(type & item_type && m_selection_mode & selection_mode)) + return false; + wxDataViewItemArray sels; GetSelections(sels); - for (const auto& sel: sels) - if (sel != m_last_selected_item && - m_objects_model->GetParent(sel) != m_objects_model->GetParent(m_last_selected_item)) - { - impossible_multipart_selection = true; - break; - } - } + for (const auto& sel : sels) + if (sel != m_last_selected_item && + m_objects_model->GetTopParent(sel) != m_objects_model->GetTopParent(m_last_selected_item)) + return true; - if (impossible_multipart_selection || + return false; + }; + + if (impossible_multi_selection(itVolume, smVolume) || + impossible_multi_selection(itLayer, smLayer ) || type & itSettings || - type & itVolume && m_selection_mode == smInstance || - !(type & itVolume) && m_selection_mode == smVolume) + type & itVolume && !(m_selection_mode & smVolume ) || + type & itLayer && !(m_selection_mode & smLayer ) || + type & itInstance && !(m_selection_mode & smInstance) + ) { // Inform user why selection isn't complited - const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part")); + const wxString item_type = m_selection_mode & smInstance ? _(L("Object or Instance")) : + m_selection_mode & smVolume ? _(L("Part")) : _(L("Layer")); msg_str = wxString::Format( _(L("Unsupported selection")) + "\n\n" + _(L("You started your selection with %s Item.")) + "\n" + @@ -2752,7 +2816,7 @@ void ObjectList::fix_multiselection_conflicts() wxDataViewItemArray sels; GetSelections(sels); - if (m_selection_mode == smVolume) + if (m_selection_mode & (smVolume|smLayer)) { // identify correct parent of the initial selected item const wxDataViewItem& parent = m_objects_model->GetParent(m_last_selected_item == sels.front() ? sels.back() : sels.front()); @@ -2761,8 +2825,10 @@ void ObjectList::fix_multiselection_conflicts() wxDataViewItemArray children; // selected volumes from current parent m_objects_model->GetChildren(parent, children); + const ItemType item_type = m_selection_mode & smVolume ? itVolume : itLayer; + for (const auto child : children) - if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume) + if (IsSelected(child) && m_objects_model->GetItemType(child) & item_type) sels.Add(child); // If some part is selected, unselect all items except of selected parts of the current object @@ -2928,7 +2994,7 @@ void ObjectList::update_settings_items() } // Update settings item for item had it -void ObjectList::update_settings_item_for_item(wxDataViewItem item, wxDataViewItemArray& selections) +void ObjectList::update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections) { const wxDataViewItem& settings_item = m_objects_model->GetSettingsItem(item); select_item(settings_item ? settings_item : m_objects_model->AddSettingsChild(item)); @@ -2956,7 +3022,7 @@ void ObjectList::update_object_list_by_printer_technology() for (auto& object_item : object_items) { // Update Settings Item for object - update_settings_item_for_item(object_item, sel); + update_settings_item_and_selection(object_item, sel); // Update settings for Volumes wxDataViewItemArray all_object_subitems; @@ -2964,7 +3030,7 @@ void ObjectList::update_object_list_by_printer_technology() for (auto item : all_object_subitems) if (m_objects_model->GetItemType(item) & itVolume) // update settings for volume - update_settings_item_for_item(item, sel); + update_settings_item_and_selection(item, sel); // Update Layers Items wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(object_item); @@ -2999,7 +3065,7 @@ void ObjectList::update_object_list_by_printer_technology() for (auto item : all_obj_layers) // update settings for layer - update_settings_item_for_item(item, sel); + update_settings_item_and_selection(item, sel); } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 29a8096d4..7c7046626 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -33,8 +33,9 @@ typedef std::map< std::string, std::vector< std::pair typedef std::vector ModelVolumePtrs; -typedef double coordf_t; -typedef std::pair t_layer_height_range; +typedef double coordf_t; +typedef std::pair t_layer_height_range; +typedef std::map t_layer_config_ranges; namespace GUI { @@ -67,9 +68,10 @@ class ObjectList : public wxDataViewCtrl { enum SELECTION_MODE { - smUndef, - smVolume, - smInstance + smUndef = 0, + smVolume = 1, + smInstance = 2, + smLayer = 4 } m_selection_mode {smUndef}; struct dragged_item_data @@ -130,7 +132,9 @@ class ObjectList : public wxDataViewCtrl DynamicPrintConfig *m_config {nullptr}; std::vector *m_objects{ nullptr }; - std::vector m_bmp_vector; + std::vector m_bmp_vector; + + t_layer_config_ranges m_layer_config_ranges_cache; int m_selected_object_id = -1; bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select() @@ -308,7 +312,7 @@ public: void last_volume_is_deleted(const int obj_idx); bool has_multi_part_objects(); void update_settings_items(); - void update_settings_item_for_item(wxDataViewItem item, wxDataViewItemArray& selections); + void update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections); void update_object_list_by_printer_technology(); void update_object_menu(); @@ -319,6 +323,8 @@ public: void fix_through_netfabb(); void update_item_error_icon(const int obj_idx, int vol_idx) const ; + void fill_layer_config_ranges_cache(); + void paste_layers_into_list(); void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes); void paste_objects_into_list(const std::vector& object_idxs); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 05cc265c3..c23caa6c8 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1174,7 +1174,8 @@ int ObjectDataViewModel::GetItemIdByLayerRange(const int obj_idx, const t_layer int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const { - wxASSERT(item.IsOk()); + if(!item.IsOk()) + return -1; ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); auto it = find(m_objects.begin(), m_objects.end(), node); -- cgit v1.2.3 From 72046598a966e04caf734867b99e8b360fb05aeb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 10 Jun 2019 15:49:41 +0200 Subject: Fixed OSX build --- src/slic3r/GUI/wxExtensions.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 8ade7af07..1ed5770bb 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -20,7 +20,8 @@ namespace Slic3r { enum class ModelVolumeType : int; }; -typedef std::pair t_layer_height_range; +typedef double coordf_t; +typedef std::pair t_layer_height_range; #ifdef __WXMSW__ void msw_rescale_menu(wxMenu* menu); -- cgit v1.2.3 From f0f608f247832b9f5ca3b1cd0a3bb03d148a7fad Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 11 Jun 2019 10:11:42 +0200 Subject: Copy/paste Layers for OSX --- src/slic3r/GUI/GUI_ObjectList.cpp | 40 +++++++++++++++++++++++---------------- src/slic3r/GUI/GUI_ObjectList.hpp | 3 +++ 2 files changed, 27 insertions(+), 16 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index f6dd6c591..23eb67c50 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -148,10 +148,10 @@ ObjectList::ObjectList(wxWindow* parent) : wxAcceleratorTable accel(6, entries); SetAcceleratorTable(accel); - this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY)); }, wxID_COPY); - this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); }, wxID_PASTE); - this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->select_item_all_children(); }, wxID_SELECTALL); - this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->remove(); }, wxID_DELETE); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->copy(); }, wxID_COPY); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->paste(); }, wxID_PASTE); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->select_item_all_children(); }, wxID_SELECTALL); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->remove(); }, wxID_DELETE); } #else __WXOSX__ Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX @@ -773,6 +773,22 @@ void ObjectList::show_context_menu() } } +void ObjectList::copy() +{ + if (m_selection_mode & smLayer) + fill_layer_config_ranges_cache(); + else + wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY)); +} + +void ObjectList::paste() +{ + if (!m_layer_config_ranges_cache.empty()) + paste_layers_into_list(); + else + wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); +} + #ifndef __WXOSX__ void ObjectList::key_event(wxKeyEvent& event) { @@ -787,18 +803,10 @@ void ObjectList::key_event(wxKeyEvent& event) } else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/)) select_item_all_children(); - else if (wxGetKeyState(wxKeyCode('C')) && wxGetKeyState(WXK_CONTROL)) { - if (m_selection_mode & smLayer) - fill_layer_config_ranges_cache(); - else - wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY)); - } - else if (wxGetKeyState(wxKeyCode('V')) && wxGetKeyState(WXK_CONTROL)) { - if (!m_layer_config_ranges_cache.empty()) - paste_layers_into_list(); - else - wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); - } + else if (wxGetKeyState(wxKeyCode('C')) && wxGetKeyState(WXK_CONTROL)) + copy(); + else if (wxGetKeyState(wxKeyCode('V')) && wxGetKeyState(WXK_CONTROL)) + paste(); else event.Skip(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 7c7046626..ed055a3a6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -202,6 +202,9 @@ public: void key_event(wxKeyEvent& event); #endif /* __WXOSX__ */ + void copy(); + void paste(); + void get_settings_choice(const wxString& category_name); void get_freq_settings_choice(const wxString& bundle_name); void update_settings_item(); -- cgit v1.2.3 From 6877c075dc14c24d8b036ade7cf540ce228dd061 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 11 Jun 2019 17:57:39 +0200 Subject: SPE-742: Parameter layer for zero elevation feature. --- src/slic3r/GUI/Preset.cpp | 4 ++ src/slic3r/GUI/Tab.cpp | 97 ++++++++++++++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 35 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 22ddf3449..86eee1902 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -461,6 +461,7 @@ const std::vector& Preset::sla_print_options() "support_pillar_widening_factor", "support_base_diameter", "support_base_height", + "support_base_safety_distance", "support_critical_angle", "support_max_bridge_length", "support_max_pillar_link_distance", @@ -474,6 +475,9 @@ const std::vector& Preset::sla_print_options() "pad_max_merge_distance", "pad_edge_radius", "pad_wall_slope", + "pad_object_connector_stride", + "pad_object_connector_width", + "pad_object_connector_penetration", "output_filename_format", "default_sla_print_profile", "compatible_printers", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6cd270e5b..8ca47f1b1 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3481,6 +3481,7 @@ void TabSLAPrint::build() // optgroup->append_single_option_line("support_pillar_widening_factor"); optgroup->append_single_option_line("support_base_diameter"); optgroup->append_single_option_line("support_base_height"); + optgroup->append_single_option_line("support_base_safety_distance"); optgroup->append_single_option_line("support_object_elevation"); optgroup = page->new_optgroup(_(L("Connection of the support sticks and junctions"))); @@ -3501,7 +3502,11 @@ void TabSLAPrint::build() // TODO: Disabling this parameter for the beta release // optgroup->append_single_option_line("pad_edge_radius"); optgroup->append_single_option_line("pad_wall_slope"); - + + optgroup->append_single_option_line("pad_object_connector_stride"); + optgroup->append_single_option_line("pad_object_connector_width"); + optgroup->append_single_option_line("pad_object_connector_penetration"); + page = add_options_page(_(L("Advanced")), "wrench"); optgroup = page->new_optgroup(_(L("Slicing"))); optgroup->append_single_option_line("slice_closing_radius"); @@ -3541,42 +3546,64 @@ void TabSLAPrint::reload_config() void TabSLAPrint::update() { - if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) + if (m_preset_bundle->printers.get_selected_preset().printer_technology() + == ptFFF) return; // #ys_FIXME -// #ys_FIXME - m_update_cnt++; - - double head_penetration = m_config->opt_float("support_head_penetration"); - double head_width = m_config->opt_float("support_head_width"); - if(head_penetration > head_width) { - wxString msg_text = _(L("Head penetration should not be greater than the head width.")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Invalid Head penetration")), wxICON_WARNING | wxOK); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_OK) { - new_conf.set_key_value("support_head_penetration", new ConfigOptionFloat(head_width)); - } - - load_config(new_conf); - } - - double pinhead_d = m_config->opt_float("support_head_front_diameter"); - double pillar_d = m_config->opt_float("support_pillar_diameter"); - if(pinhead_d > pillar_d) { - wxString msg_text = _(L("Pinhead diameter should be smaller than the pillar diameter.")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Invalid pinhead diameter")), wxICON_WARNING | wxOK); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_OK) { - new_conf.set_key_value("support_head_front_diameter", new ConfigOptionFloat(pillar_d / 2.0)); - } - - load_config(new_conf); - } - - m_update_cnt--; - - if (m_update_cnt == 0) - wxGetApp().mainframe->on_config_changed(m_config); + // #ys_FIXME + m_update_cnt++; + + double head_penetration = m_config->opt_float("support_head_penetration"); + double head_width = m_config->opt_float("support_head_width"); + if (head_penetration > head_width) { + wxString msg_text = _( + L("Head penetration should not be greater than the head width.")); + + auto dialog = new wxMessageDialog(parent(), + msg_text, + _(L("Invalid Head penetration")), + wxICON_WARNING | wxOK); + + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_OK) { + new_conf.set_key_value("support_head_penetration", + new ConfigOptionFloat(head_width)); + } + + load_config(new_conf); + } + + double pinhead_d = m_config->opt_float("support_head_front_diameter"); + double pillar_d = m_config->opt_float("support_pillar_diameter"); + if (pinhead_d > pillar_d) { + wxString msg_text = _(L( + "Pinhead diameter should be smaller than the pillar diameter.")); + + auto dialog = new wxMessageDialog(parent(), + msg_text, + _(L("Invalid pinhead diameter")), + wxICON_WARNING | wxOK); + + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_OK) { + new_conf.set_key_value("support_head_front_diameter", + new ConfigOptionFloat(pillar_d / 2.0)); + } + + load_config(new_conf); + } + + // if(m_config->opt_float("support_object_elevation") < EPSILON && + // m_config->opt_bool("pad_enable")) { + // // TODO: disable editding of: + // // pad_object_connector_stride + // // pad_object_connector_width + // // pad_object_connector_penetration + // } + + m_update_cnt--; + + if (m_update_cnt == 0) wxGetApp().mainframe->on_config_changed(m_config); } } // GUI -- cgit v1.2.3 From 12396c3051a7abe26d33afe244bcabc938653e3e Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 12 Jun 2019 13:15:42 +0200 Subject: Fine tuning parameters and fixing pad wings when greater gaps are used. --- src/slic3r/GUI/Preset.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 86eee1902..4b4597033 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -475,6 +475,7 @@ const std::vector& Preset::sla_print_options() "pad_max_merge_distance", "pad_edge_radius", "pad_wall_slope", + "pad_object_gap", "pad_object_connector_stride", "pad_object_connector_width", "pad_object_connector_penetration", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8ca47f1b1..032bf95df 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3503,6 +3503,7 @@ void TabSLAPrint::build() // optgroup->append_single_option_line("pad_edge_radius"); optgroup->append_single_option_line("pad_wall_slope"); + optgroup->append_single_option_line("pad_object_gap"); optgroup->append_single_option_line("pad_object_connector_stride"); optgroup->append_single_option_line("pad_object_connector_width"); optgroup->append_single_option_line("pad_object_connector_penetration"); -- cgit v1.2.3 From 1694204687ca93e7bd831cf5a5598bc1acfce658 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 12 Jun 2019 16:28:25 +0200 Subject: Added some logic to layers editor selection --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 126 +++++++++++++++++++++++------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 26 +++++--- src/slic3r/GUI/GUI_ObjectList.cpp | 44 ++++++++++--- src/slic3r/GUI/GUI_ObjectList.hpp | 4 +- 4 files changed, 136 insertions(+), 64 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index ba0012a2b..5f0ec259d 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -39,72 +39,83 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_bmp_add = ScalableBitmap(parent, "add_copies"); } +void ObjectLayers::select_editor(LayerRangeEditor* editor, const bool is_last_edited_range) +{ + if (is_last_edited_range && m_selection_type == editor->type()) { + editor->SetFocus(); + editor->SetInsertionPointEnd(); + } +} + wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) { const bool is_last_edited_range = range == m_last_edited_range; + auto set_focus_fn = [range, this](const EditorType type) + { + m_last_edited_range = range; + m_selection_type = type; + }; + // Add control for the "Min Z" - auto temp = new LayerRangeEditor(m_parent, double_to_string(range.first), - [range, this](coordf_t min_z) + auto editor = new LayerRangeEditor(m_parent, double_to_string(range.first), etMinZ, + set_focus_fn, [range, this](coordf_t min_z, bool enter_pressed) { - if (fabs(min_z - range.first) < EPSILON) { - m_selection_type = sitUndef; - return false; // LayersList would not be updated/recreated + if (fabs(min_z - range.first) < EPSILON || min_z > range.second) { + m_selection_type = etUndef; + return false; } // data for next focusing - m_last_edited_range = { min_z, range.second }; - m_selection_type = sitMinZ; + const t_layer_height_range& new_range = { min_z, range.second }; + if (enter_pressed) { + m_last_edited_range = new_range; + m_selection_type = etMinZ; + } - wxGetApp().obj_list()->edit_layer_range(range, m_last_edited_range); - return true; // LayersList will be updated/recreated + return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); - if (is_last_edited_range && m_selection_type == sitMinZ) { - temp->SetFocus(); - temp->SetInsertionPointEnd(); - } - - m_grid_sizer->Add(temp); + select_editor(editor, is_last_edited_range); + m_grid_sizer->Add(editor); // Add control for the "Max Z" - temp = new LayerRangeEditor(m_parent, double_to_string(range.second), - [range, this](coordf_t max_z) + editor = new LayerRangeEditor(m_parent, double_to_string(range.second), etMaxZ, + set_focus_fn, [range, this](coordf_t max_z, bool enter_pressed) { - if (fabs(max_z - range.second) < EPSILON) { - m_selection_type = sitUndef; + if (fabs(max_z - range.second) < EPSILON || range.first > max_z) { + m_selection_type = etUndef; return false; // LayersList would not be updated/recreated } // data for next focusing - m_last_edited_range = { range.first, max_z }; - m_selection_type = sitMaxZ; + const t_layer_height_range& new_range = { range.first, max_z }; + if (enter_pressed) { + m_last_edited_range = new_range; + m_selection_type = etMaxZ; + } - wxGetApp().obj_list()->edit_layer_range(range, m_last_edited_range); - return true; // LayersList will not be updated/recreated + return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); - if (is_last_edited_range && m_selection_type == sitMaxZ) { - temp->SetFocus(); - temp->SetInsertionPointEnd(); - } - - m_grid_sizer->Add(temp); + select_editor(editor, is_last_edited_range); + m_grid_sizer->Add(editor); // Add control for the "Layer height" - temp = new LayerRangeEditor(m_parent, + editor = new LayerRangeEditor(m_parent, double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), - [range, this](coordf_t layer_height) + etLayerHeight, set_focus_fn, [range, this](coordf_t layer_height, bool) { - wxGetApp().obj_list()->edit_layer_range(range, layer_height); - return false; // LayersList would not be updated/recreated + return wxGetApp().obj_list()->edit_layer_range(range, layer_height); }); + select_editor(editor, is_last_edited_range); + auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(temp); + sizer->Add(editor); m_grid_sizer->Add(sizer); return sizer; @@ -193,34 +204,61 @@ void ObjectLayers::msw_rescale() LayerRangeEditor::LayerRangeEditor( wxWindow* parent, const wxString& value, - std::function edit_fn + EditorType type, + std::function set_focus_fn, + std::function edit_fn ) : + m_valid_value(value), + m_type(type), wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, wxSize(8 * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) { this->SetFont(wxGetApp().normal_font()); - this->Bind(wxEVT_TEXT_ENTER, ([this, edit_fn](wxEvent& e) + this->Bind(wxEVT_TEXT_ENTER, [this, edit_fn](wxEvent&) { m_enter_pressed = true; // If LayersList wasn't updated/recreated, we can call wxEVT_KILL_FOCUS.Skip() - if ( !edit_fn(get_value()) ) + if (m_type&etLayerHeight) { + if (!edit_fn(get_value(), true)) + SetValue(m_valid_value); + else + m_valid_value = double_to_string(get_value()); m_call_kill_focus = true; - }), this->GetId()); + } + else if (!edit_fn(get_value(), true)) { + SetValue(m_valid_value); + m_call_kill_focus = true; + } + }, this->GetId()); - this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn](wxEvent& e) + this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e) { if (!m_enter_pressed) { - m_enter_pressed = false; - // If LayersList wasn't updated/recreated, we should call e.Skip() - if ( !edit_fn(get_value()) ) + if (m_type & etLayerHeight) { + if (!edit_fn(get_value(), false)) + SetValue(m_valid_value); + else + m_valid_value = double_to_string(get_value()); + e.Skip(); + } + else if (!edit_fn(get_value(), false)) { + SetValue(m_valid_value); e.Skip(); + } } - else if (m_call_kill_focus) + else if (m_call_kill_focus) { + m_call_kill_focus = false; e.Skip(); - }), this->GetId()); + } + }, this->GetId()); + this->Bind(wxEVT_LEFT_DOWN, ([this, set_focus_fn](wxEvent& e) + { + set_focus_fn(m_type); + e.Skip(); + })); this->Bind(wxEVT_CHAR, ([this](wxKeyEvent& event) { diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 562e04972..9c2af20e5 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -19,18 +19,32 @@ class ConfigOptionsGroup; typedef double coordf_t; typedef std::pair t_layer_height_range; +enum EditorType +{ + etUndef = 0, + etMinZ = 1, + etMaxZ = 2, + etLayerHeight = 4, +}; + class LayerRangeEditor : public wxTextCtrl { bool m_enter_pressed { false }; bool m_call_kill_focus { false }; + wxString m_valid_value; + EditorType m_type; public: LayerRangeEditor( wxWindow* parent, const wxString& value = wxEmptyString, - std::function edit_fn = [](coordf_t) {return false; } + EditorType type = etUndef, + std::function set_focus_fn = [](EditorType) {;}, + std::function edit_fn = [](coordf_t, bool) {return false; } ); ~LayerRangeEditor() {} + EditorType type() const {return m_type;} + private: coordf_t get_value(); }; @@ -43,19 +57,13 @@ class ObjectLayers : public OG_Settings wxFlexGridSizer* m_grid_sizer; t_layer_height_range m_last_edited_range; - - enum SelectedItemType - { - sitUndef, - sitMinZ, - sitMaxZ, - sitLayerHeight, - } m_selection_type {sitUndef}; + EditorType m_selection_type {etUndef}; public: ObjectLayers(wxWindow* parent); ~ObjectLayers() {} + void select_editor(LayerRangeEditor* editor, const bool is_last_edited_range); wxSizer* create_layer(const t_layer_height_range& range); // without_buttons void create_layers_list(); void update_layers_list(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 23eb67c50..b1b57fcd6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2363,6 +2363,18 @@ void ObjectList::del_layer_range(const t_layer_height_range& range) select_item(selectable_item); } +double get_min_layer_height(const int extruder_idx) +{ + const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + return config.opt_float("min_layer_height", extruder_idx <= 0 ? 0 : extruder_idx-1); +} + +double get_max_layer_height(const int extruder_idx) +{ + const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + return config.opt_float("max_layer_height", extruder_idx <= 0 ? 0 : extruder_idx-1); +} + void ObjectList::add_layer_range_after_current(const t_layer_height_range& current_range) { const int obj_idx = get_selected_obj_idx(); @@ -2393,13 +2405,14 @@ void ObjectList::add_layer_range_after_current(const t_layer_height_range& curre if (current_range.second == next_range.first) { + const auto old_config = ranges.at(next_range); + const coordf_t delta = (next_range.second - next_range.first); - if (delta < 0.05f) // next range division has no sense + if (delta < get_min_layer_height(old_config.opt_int("extruder"))/*0.05f*/) // next range division has no sense return; const coordf_t midl_layer = next_range.first + 0.5f * delta; - const auto old_config = ranges.at(next_range); t_layer_height_range new_range = { midl_layer, next_range.second }; // delete old layer @@ -2450,21 +2463,32 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, select_item(m_objects_model->AddSettingsChild(layer_item)); } -void ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) +bool ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) { const int obj_idx = get_selected_obj_idx(); - if (obj_idx < 0) return; + if (obj_idx < 0) + return false; - t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; + DynamicPrintConfig* config = &object(obj_idx)->layer_config_ranges[range]; + if (fabs(layer_height - config->opt_float("layer_height")) < EPSILON) + return false; + + const int extruder_idx = config->opt_int("extruder"); - DynamicPrintConfig* config = &ranges[range]; - config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); + if (layer_height >= get_min_layer_height(extruder_idx) && + layer_height <= get_max_layer_height(extruder_idx)) + { + config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); + return true; + } + + return false; } -void ObjectList::edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range) +bool ObjectList::edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range) { const int obj_idx = get_selected_obj_idx(); - if (obj_idx < 0) return; + if (obj_idx < 0) return false; t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; @@ -2484,6 +2508,8 @@ void ObjectList::edit_layer_range(const t_layer_height_range& range, const t_lay // To update(recreate) layers sizer call select_item for LayerRoot item expand select_item(root_item); Expand(root_item); + + return true; } void ObjectList::init_objects() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index ed055a3a6..ed19edd62 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -291,8 +291,8 @@ public: void add_layer_item (const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx = -1); - void edit_layer_range(const t_layer_height_range& range, coordf_t layer_height); - void edit_layer_range(const t_layer_height_range& range, + bool edit_layer_range(const t_layer_height_range& range, coordf_t layer_height); + bool edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range); void init_objects(); -- cgit v1.2.3 From c9dd5f878699e79d64ccb4059f37b8967e872270 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 13 Jun 2019 11:37:03 +0200 Subject: Fixed updating of data for LayerEditors selection --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 39 ++++++++++++++++++++----------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 5 ++++- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 5f0ec259d..df0c4faeb 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -49,18 +49,27 @@ void ObjectLayers::select_editor(LayerRangeEditor* editor, const bool is_last_ed wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) { - const bool is_last_edited_range = range == m_last_edited_range; + const bool is_last_edited_range = range == m_selectable_range; auto set_focus_fn = [range, this](const EditorType type) { - m_last_edited_range = range; + m_selectable_range = range; m_selection_type = type; }; + auto set_focus = [range, this](const t_layer_height_range& new_range, EditorType type, bool enter_pressed) + { + // change selectable range for new one, if enter was pressed or if same range was selected + if (enter_pressed || m_selectable_range == range) + m_selectable_range = new_range; + if (enter_pressed) + m_selection_type = type; + }; + // Add control for the "Min Z" auto editor = new LayerRangeEditor(m_parent, double_to_string(range.first), etMinZ, - set_focus_fn, [range, this](coordf_t min_z, bool enter_pressed) + set_focus_fn, [range, set_focus, this](coordf_t min_z, bool enter_pressed) { if (fabs(min_z - range.first) < EPSILON || min_z > range.second) { m_selection_type = etUndef; @@ -69,10 +78,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // data for next focusing const t_layer_height_range& new_range = { min_z, range.second }; - if (enter_pressed) { - m_last_edited_range = new_range; - m_selection_type = etMinZ; - } + set_focus(new_range, etMinZ, enter_pressed); return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); @@ -83,7 +89,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // Add control for the "Max Z" editor = new LayerRangeEditor(m_parent, double_to_string(range.second), etMaxZ, - set_focus_fn, [range, this](coordf_t max_z, bool enter_pressed) + set_focus_fn, [range, set_focus, this](coordf_t max_z, bool enter_pressed) { if (fabs(max_z - range.second) < EPSILON || range.first > max_z) { m_selection_type = etUndef; @@ -92,10 +98,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // data for next focusing const t_layer_height_range& new_range = { range.first, max_z }; - if (enter_pressed) { - m_last_edited_range = new_range; - m_selection_type = etMaxZ; - } + set_focus(new_range, etMaxZ, enter_pressed); return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); @@ -210,6 +213,7 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, ) : m_valid_value(value), m_type(type), + m_set_focus(set_focus_fn), wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, wxSize(8 * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) { @@ -235,6 +239,11 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e) { if (!m_enter_pressed) { + // update data for next editor selection + LayerRangeEditor* new_editor = dynamic_cast(e.GetWindow()); + if (new_editor) + new_editor->set_focus(); + // If LayersList wasn't updated/recreated, we should call e.Skip() if (m_type & etLayerHeight) { if (!edit_fn(get_value(), false)) @@ -254,12 +263,6 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, } }, this->GetId()); - this->Bind(wxEVT_LEFT_DOWN, ([this, set_focus_fn](wxEvent& e) - { - set_focus_fn(m_type); - e.Skip(); - })); - this->Bind(wxEVT_CHAR, ([this](wxKeyEvent& event) { // select all text using Ctrl+A diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 9c2af20e5..e3366e03e 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -34,6 +34,8 @@ class LayerRangeEditor : public wxTextCtrl wxString m_valid_value; EditorType m_type; + std::function m_set_focus; + public: LayerRangeEditor( wxWindow* parent, const wxString& value = wxEmptyString, @@ -44,6 +46,7 @@ public: ~LayerRangeEditor() {} EditorType type() const {return m_type;} + void set_focus() const { m_set_focus(m_type);} private: coordf_t get_value(); @@ -56,7 +59,7 @@ class ObjectLayers : public OG_Settings ModelObject* m_object {nullptr}; wxFlexGridSizer* m_grid_sizer; - t_layer_height_range m_last_edited_range; + t_layer_height_range m_selectable_range; EditorType m_selection_type {etUndef}; public: -- cgit v1.2.3 From e00774d2e21319ddfacbad417f7dd7309e8f2f56 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 13 Jun 2019 13:00:46 +0200 Subject: Workarounds for selection under OSX and GTK --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index df0c4faeb..12c1022ce 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -42,8 +42,19 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : void ObjectLayers::select_editor(LayerRangeEditor* editor, const bool is_last_edited_range) { if (is_last_edited_range && m_selection_type == editor->type()) { + /* Workaround! Under OSX we should use CallAfter() for SetFocus() after LayerEditors "reorganizations", + * because of selected control's strange behavior: + * cursor is set to the control, but blue border - doesn't. + * And as a result we couldn't edit this control. + * */ +#ifdef __WXOSX__ + wxTheApp->CallAfter([editor]() { +#endif editor->SetFocus(); editor->SetInsertionPointEnd(); +#ifdef __WXOSX__ + }); +#endif } } @@ -239,11 +250,15 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e) { if (!m_enter_pressed) { - // update data for next editor selection +#ifndef __WXGTK__ + /* Update data for next editor selection. + * But under GTK it lucks like there is no information about selected control at e.GetWindow(), + * so we'll take it from wxEVT_LEFT_DOWN event + * */ LayerRangeEditor* new_editor = dynamic_cast(e.GetWindow()); if (new_editor) new_editor->set_focus(); - +#endif // not __WXGTK__ // If LayersList wasn't updated/recreated, we should call e.Skip() if (m_type & etLayerHeight) { if (!edit_fn(get_value(), false)) @@ -263,6 +278,14 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, } }, this->GetId()); +#ifdef __WXGTK__ // Workaround! To take information about selectable range + this->Bind(wxEVT_LEFT_DOWN, [this](wxEvent& e) + { + set_focus(); + e.Skip(); + }, this->GetId()); +#endif //__WXGTK__ + this->Bind(wxEVT_CHAR, ([this](wxKeyEvent& event) { // select all text using Ctrl+A -- cgit v1.2.3 From 86e7a07dd8130462771d91540cc3daa6e0a8bc9c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 13 Jun 2019 16:17:54 +0200 Subject: Fixed selection --- src/slic3r/GUI/GUI_ObjectList.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b1b57fcd6..31396b630 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2543,9 +2543,11 @@ void ObjectList::update_selections() if (GetSelectedItemsCount() == 1 && m_objects_model->GetItemType(GetSelection()) & (itSettings | itLayerRoot | itLayer)) { const auto item = GetSelection(); - if (selection.is_single_full_object() && - m_objects_model->GetIdByItem(m_objects_model->GetParent(item)) == selection.get_object_idx()) - return; + if (selection.is_single_full_object()) { + if (m_objects_model->GetObjectIdByItem(item) == selection.get_object_idx()) + return; + sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); + } if (selection.is_single_volume() || selection.is_any_modifier()) { const auto gl_vol = selection.get_volume(*selection.get_volume_idxs().begin()); if (m_objects_model->GetVolumeIdByItem(m_objects_model->GetParent(item)) == gl_vol->volume_idx()) -- cgit v1.2.3 From da1aea889f3cb0390b7a752b42065f6021829f84 Mon Sep 17 00:00:00 2001 From: Thomas Moore Date: Fri, 3 May 2019 00:17:24 -0400 Subject: Enable wipe tower for all multi-extruder configurations --- src/slic3r/GUI/GLCanvas3D.cpp | 5 ++--- src/slic3r/GUI/Tab.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 21f1d23cd..216848477 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2049,11 +2049,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // Should the wipe tower be visualized ? unsigned int extruders_count = (unsigned int)dynamic_cast(m_config->option("nozzle_diameter"))->values.size(); - bool semm = dynamic_cast(m_config->option("single_extruder_multi_material"))->value; bool wt = dynamic_cast(m_config->option("wipe_tower"))->value; bool co = dynamic_cast(m_config->option("complete_objects"))->value; - if ((extruders_count > 1) && semm && wt && !co) + if ((extruders_count > 1) && wt && !co) { // Height of a print (Show at least a slab) double height = std::max(m_model->bounding_box().max(2), 10.0); @@ -5466,7 +5465,7 @@ void GLCanvas3D::_load_fff_shells() double max_z = print->objects()[0]->model_object()->get_model()->bounding_box().max(2); const PrintConfig& config = print->config(); unsigned int extruders_count = config.nozzle_diameter.size(); - if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects) { + if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { float depth = print->get_wipe_tower_depth(); // Calculate wipe tower brim spacing. diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6cd32d397..078293d67 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -874,11 +874,10 @@ void Tab::update_wiping_button_visibility() { return; // ys_FIXME bool wipe_tower_enabled = dynamic_cast( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value; bool multiple_extruders = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1; - bool single_extruder_mm = dynamic_cast( (m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value; auto wiping_dialog_button = wxGetApp().sidebar().get_wiping_dialog_button(); if (wiping_dialog_button) { - wiping_dialog_button->Show(wipe_tower_enabled && multiple_extruders && single_extruder_mm); + wiping_dialog_button->Show(wipe_tower_enabled && multiple_extruders); wiping_dialog_button->GetParent()->Layout(); } } @@ -1557,6 +1556,9 @@ void TabFilament::build() }; optgroup->append_line(line); + optgroup = page->new_optgroup(_(L("Wipe tower parameters"))); + optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower"); + optgroup = page->new_optgroup(_(L("Toolchange parameters with single extruder MM printers"))); optgroup->append_single_option_line("filament_loading_speed_start"); optgroup->append_single_option_line("filament_loading_speed"); @@ -1568,7 +1570,6 @@ void TabFilament::build() optgroup->append_single_option_line("filament_cooling_moves"); optgroup->append_single_option_line("filament_cooling_initial_speed"); optgroup->append_single_option_line("filament_cooling_final_speed"); - optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower"); line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" }; line.widget = [this](wxWindow* parent) { -- cgit v1.2.3 From aee376762e508df543d9805f0233a3f987999b32 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 14 Jun 2019 12:28:24 +0200 Subject: Changed handling of priming extrusions to allow injection of filament and toolchange custom gcodes The priming extrusions were handled separately from the rest of the wipe tower toolchanges. In order to be able to use the logic from previous commit for them (custom toolchange gcodes etc), some unpleasant code shuffling was needed --- src/slic3r/GUI/GLCanvas3D.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 216848477..65e06e432 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4804,7 +4804,8 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ ctxt.print = print; ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; if (print->wipe_tower_data().priming && print->config().single_extruder_multi_material_priming) - ctxt.priming.emplace_back(*print->wipe_tower_data().priming.get()); + for (int i=0; iwipe_tower_data().priming.get()->size(); ++i) + ctxt.priming.emplace_back(print->wipe_tower_data().priming.get()->at(i)); if (print->wipe_tower_data().final_purge) ctxt.final.emplace_back(*print->wipe_tower_data().final_purge.get()); -- cgit v1.2.3 From 05e6dbbe4be46295533a36672718c5eef57847d6 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 17 Jun 2019 10:16:07 +0200 Subject: Wipe tower - refactoring (removed the abstract WipeTower class) - abstract class WipeTower and its descendant WipeTowerPrusaMM were merged into a single (non-abstract) WipeTower class - all uses of WipeTower::xy struct were replaced by Eigen Vec2f (it is no longer necessary to be independent on libraries that PrusaSlicer uses) - the WipeTowerPrusaMM.hpp/.cpp will be renamed in the next commit (hopefully it will retain its git history that way) --- src/slic3r/GUI/GLCanvas3D.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 65e06e432..6b55bd751 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4773,7 +4773,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ { const Print *print; const std::vector *tool_colors; - WipeTower::xy wipe_tower_pos; + Vec2f wipe_tower_pos; float wipe_tower_angle; // Number of vertices (each vertex is 6x4=24 bytes long) @@ -4810,7 +4810,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ ctxt.final.emplace_back(*print->wipe_tower_data().final_purge.get()); ctxt.wipe_tower_angle = ctxt.print->config().wipe_tower_rotation_angle.value/180.f * PI; - ctxt.wipe_tower_pos = WipeTower::xy(ctxt.print->config().wipe_tower_x.value, ctxt.print->config().wipe_tower_y.value); + ctxt.wipe_tower_pos = Vec2f(ctxt.print->config().wipe_tower_x.value, ctxt.print->config().wipe_tower_y.value); BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start"; @@ -4872,19 +4872,19 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ WipeTower::Extrusion e_prev = extrusions.extrusions[i-1]; if (!extrusions.priming) { // wipe tower extrusions describe the wipe tower at the origin with no rotation - e_prev.pos.rotate(ctxt.wipe_tower_angle); - e_prev.pos.translate(ctxt.wipe_tower_pos); + e_prev.pos = Eigen::Rotation2Df(ctxt.wipe_tower_angle) * e_prev.pos; + e_prev.pos += ctxt.wipe_tower_pos; } for (; i < j; ++i) { WipeTower::Extrusion e = extrusions.extrusions[i]; assert(e.width > 0.f); if (!extrusions.priming) { - e.pos.rotate(ctxt.wipe_tower_angle); - e.pos.translate(ctxt.wipe_tower_pos); + e.pos = Eigen::Rotation2Df(ctxt.wipe_tower_angle) * e.pos; + e.pos += ctxt.wipe_tower_pos; } - lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y)); + lines.emplace_back(Point::new_scale(e_prev.pos.x(), e_prev.pos.y()), Point::new_scale(e.pos.x(), e.pos.y())); widths.emplace_back(e.width); e_prev = e; -- cgit v1.2.3 From f394f84d51b8654b9008a11e773bdd04d75b979d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 17 Jun 2019 13:09:11 +0200 Subject: Fixed selection after layers deleting --- src/slic3r/GUI/GUI_ObjectList.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 31396b630..1d7d95b56 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2317,32 +2317,28 @@ void ObjectList::remove() wxDataViewItemArray sels; GetSelections(sels); + wxDataViewItem parent = wxDataViewItem(0); + for (auto& item : sels) { if (m_objects_model->GetParent(item) == wxDataViewItem(0)) delete_from_model_and_list(itObject, m_objects_model->GetIdByItem(item), -1); else { -// if (sels.size() == 1) -// select_item(m_objects_model->GetParent(item)); - wxDataViewItem parent = m_objects_model->GetParent(item); - if (sels.size() == 1) { - if (!(m_objects_model->GetItemType(item) & itLayer)) { - select_item(parent); - parent = wxDataViewItem(0); - } - else { - wxDataViewItemArray children; - if (m_objects_model->GetChildren(parent, children) == 1) - parent = m_objects_model->GetTopParent(item); - } + if (m_objects_model->GetItemType(item) & itLayer) { + parent = m_objects_model->GetParent(item); + wxDataViewItemArray children; + if (m_objects_model->GetChildren(parent, children) == 1) + parent = m_objects_model->GetTopParent(item); } + else if (sels.size() == 1) + select_item(m_objects_model->GetParent(item)); del_subobject_item(item); - - if (sels.size() == 1 && parent) - select_item(parent); } } + + if (parent) + select_item(parent); } void ObjectList::del_layer_range(const t_layer_height_range& range) -- cgit v1.2.3 From 5fd3cc267686c74e422a013e62bbae6aea588678 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 17 Jun 2019 13:46:56 +0200 Subject: Select edited layer after changing instead of "Layers" selection, if editing was in "Layer" mode --- src/slic3r/GUI/GUI_ObjectList.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 1d7d95b56..5539ee29a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2486,6 +2486,8 @@ bool ObjectList::edit_layer_range(const t_layer_height_range& range, const t_lay const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return false; + const ItemType sel_type = m_objects_model->GetItemType(GetSelection()); + t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; const DynamicPrintConfig config = ranges[range]; @@ -2501,8 +2503,7 @@ bool ObjectList::edit_layer_range(const t_layer_height_range& range, const t_lay for (const auto r : ranges) add_layer_item(r.first, root_item); - // To update(recreate) layers sizer call select_item for LayerRoot item expand - select_item(root_item); + select_item(sel_type&itLayer ? m_objects_model->GetItemByLayerRange(obj_idx, new_range) : root_item); Expand(root_item); return true; -- cgit v1.2.3 From 5a1e1bc10c887a3408194cd546b2a704b94d08f3 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Jun 2019 10:15:01 +0200 Subject: GUI_ObjectManipulation.cpp - Removed implicit capture by value in some of the lambdas --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 310000ecc..4ccaa6847 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -185,7 +185,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : unsigned int axis_idx = (axis[0] - 'x'); // 0, 1 or 2 // We will add a button to toggle mirroring to each axis: - auto mirror_button = [=](wxWindow* parent) { + auto mirror_button = [this, mirror_btn_width, axis_idx, &label](wxWindow* parent) { wxSize btn_size(em_unit(parent) * mirror_btn_width, em_unit(parent) * mirror_btn_width); auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off.png", wxEmptyString, btn_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); btn->SetToolTip(wxString::Format(_(L("Toggle %s axis mirroring")), label)); @@ -195,7 +195,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent &e) { Axis axis = (Axis)(axis_idx + X); if (m_mirror_buttons[axis_idx].second == mbHidden) return; @@ -258,13 +258,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : return btn; }; // Add reset scale button - auto reset_scale_button = [=](wxWindow* parent) { + auto reset_scale_button = [this](wxWindow* parent) { auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); btn->SetToolTip(_(L("Reset scale"))); m_reset_scale_button = btn; auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn, wxBU_EXACTFIT); - btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { change_scale_value(0, 100.); change_scale_value(1, 100.); change_scale_value(2, 100.); @@ -275,13 +275,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : } else if (option_name == "Rotation") { // Add reset rotation button - auto reset_rotation_button = [=](wxWindow* parent) { + auto reset_rotation_button = [this](wxWindow* parent) { auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); btn->SetToolTip(_(L("Reset rotation"))); m_reset_rotation_button = btn; auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn, wxBU_EXACTFIT); - btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); -- cgit v1.2.3 From 3d8c3804fab810568adedce76836ea97e7e1c71d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Jun 2019 10:46:42 +0200 Subject: Added 'drop to bed' button into object manipulation panel --- src/slic3r/GUI/3DScene.hpp | 2 ++ src/slic3r/GUI/GUI_ObjectManipulation.cpp | 57 ++++++++++++++++++++++++++++++- src/slic3r/GUI/GUI_ObjectManipulation.hpp | 1 + 3 files changed, 59 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 0414a1ed3..3090688e6 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -409,6 +409,8 @@ public: BoundingBoxf3 transformed_convex_hull_bounding_box(const Transform3d &trafo) const; // caching variant const BoundingBoxf3& transformed_convex_hull_bounding_box() const; + // convex hull + const TriangleMesh* convex_hull() const { return m_convex_hull.get(); } bool empty() const { return this->indexed_vertex_array.empty(); } bool indexed() const { return this->indexed_vertex_array.indexed(); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 4ccaa6847..7363b2c16 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -17,6 +17,28 @@ namespace Slic3r namespace GUI { + +// Helper function to be used by drop to bed button. Returns lowest point of this +// volume in world coordinate system. +static double get_volume_min_z(const GLVolume* volume) +{ + const Transform3f& world_matrix = volume->world_matrix().cast(); + + // need to get the ModelVolume pointer + const ModelObject* mo = wxGetApp().model_objects()->at(volume->composite_id.object_id); + const ModelVolume* mv = mo->volumes[volume->composite_id.volume_id]; + const TriangleMesh& hull = mv->get_convex_hull(); + + float min_z = std::numeric_limits::max(); + for (const stl_facet& facet : hull.stl.facet_start) { + for (int i = 0; i < 3; ++ i) + min_z = std::min(min_z, Vec3f::UnitZ().dot(world_matrix * facet.vertex[i])); + } + return min_z; +} + + + static wxBitmapComboBox* create_word_local_combo(wxWindow *parent) { wxSize size(15 * wxGetApp().em_unit(), -1); @@ -310,6 +332,33 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : }; line.append_widget(reset_rotation_button); } + else if (option_name == "Position") { + // Add drop to bed button + auto drop_to_bed_button = [=](wxWindow* parent) { + auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "drop_to_bed.png")); + btn->SetToolTip(_(L("Drop to bed"))); + m_drop_to_bed_button = btn; + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn, wxBU_EXACTFIT); + btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + // ??? + GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); + Selection& selection = canvas->get_selection(); + + if (selection.is_single_volume() || selection.is_single_modifier()) { + const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); + + Vec3d diff = m_cache.position - Vec3d(0., 0., get_volume_min_z(volume)); + + change_position_value(0, diff.x()); + change_position_value(1, diff.y()); + change_position_value(2, diff.z()); + } + }); + return sizer; + }; + line.append_widget(drop_to_bed_button); + } // Add empty bmp (Its size have to be equal to PrusaLockButton) in front of "Size" option to label alignment else if (option_name == "Size") { line.near_label_widget = [this](wxWindow* parent) { @@ -534,11 +583,13 @@ void ObjectManipulation::update_reset_buttons_visibility() bool show_rotation = false; bool show_scale = false; + bool show_drop_to_bed = false; if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); Vec3d rotation; Vec3d scale; + double min_z = 0.; if (selection.is_single_full_instance()) { rotation = volume->get_instance_rotation(); @@ -547,14 +598,17 @@ void ObjectManipulation::update_reset_buttons_visibility() else { rotation = volume->get_volume_rotation(); scale = volume->get_volume_scaling_factor(); + min_z = get_volume_min_z(volume); } show_rotation = !rotation.isApprox(Vec3d::Zero()); show_scale = !scale.isApprox(Vec3d::Ones()); + show_drop_to_bed = (std::abs(min_z) > EPSILON); } - wxGetApp().CallAfter([this, show_rotation, show_scale]{ + wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed]{ m_reset_rotation_button->Show(show_rotation); m_reset_scale_button->Show(show_scale); + m_drop_to_bed_button->Show(show_drop_to_bed); }); } @@ -867,6 +921,7 @@ void ObjectManipulation::msw_rescale() m_mirror_bitmap_hidden.msw_rescale(); m_reset_scale_button->msw_rescale(); m_reset_rotation_button->msw_rescale(); + m_drop_to_bed_button->msw_rescale(); get_og()->msw_rescale(); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index cc2154514..e4e190b5b 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -56,6 +56,7 @@ class ObjectManipulation : public OG_Settings // Non-owning pointers to the reset buttons, so we can hide and show them. ScalableButton* m_reset_scale_button = nullptr; ScalableButton* m_reset_rotation_button = nullptr; + ScalableButton* m_drop_to_bed_button = nullptr; // Mirroring buttons and their current state enum MirrorButtonState { -- cgit v1.2.3 From 0481f33ceb4dd64098e3b0c9c324bc32a82ba5f3 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Jun 2019 11:52:37 +0200 Subject: Drop to bed function now accounts for instance transformation --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 7363b2c16..d5445c6af 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -348,7 +348,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : if (selection.is_single_volume() || selection.is_single_modifier()) { const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); - Vec3d diff = m_cache.position - Vec3d(0., 0., get_volume_min_z(volume)); + const Geometry::Transformation& instance_trafo = volume->get_instance_transformation(); + Vec3d diff = m_cache.position - instance_trafo.get_matrix(true).inverse() * Vec3d(0., 0., get_volume_min_z(volume)); change_position_value(0, diff.x()); change_position_value(1, diff.y()); -- cgit v1.2.3 From 82de7bedb12e8d8d1c1d5f69e596bb44917f9ba4 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Jun 2019 14:51:17 +0200 Subject: WipeTowerDialog.cpp - wxEXPAND conflicted with wxALIGN_CENTER_HORIZONTAL (triggered a wxWidgets assert) --- src/slic3r/GUI/WipeTowerDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp index 4c2b2480e..894b1ee62 100644 --- a/src/slic3r/GUI/WipeTowerDialog.cpp +++ b/src/slic3r/GUI/WipeTowerDialog.cpp @@ -172,7 +172,7 @@ void WipingPanel::format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_ wxSize text_size = GetTextExtent(info); auto info_str = new wxStaticText(page, wxID_ANY, info ,wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); info_str->Wrap(int(0.6*text_size.x)); - sizer->Add( info_str, 0, wxALIGN_CENTER_HORIZONTAL | wxEXPAND); + sizer->Add( info_str, 0, wxEXPAND); auto table_sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(table_sizer, 0, wxALIGN_CENTER | wxCENTER, table_lshift); table_sizer->Add(new wxStaticText(page, wxID_ANY, table_title), 0, wxALIGN_CENTER | wxTOP, 50); -- cgit v1.2.3 From 35b3fd317623b98153a0b91d3f51c784d2cc0a20 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 20 Jun 2019 16:15:09 +0200 Subject: Integrated the new layer height spans with configs into the backend. Fixed some compiler warnings. --- src/slic3r/GUI/3DBed.cpp | 4 ++-- src/slic3r/GUI/Plater.cpp | 3 --- src/slic3r/GUI/Selection.cpp | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 8392e534a..d9bb67f57 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -600,12 +600,12 @@ void Bed3D::render_prusa_shader(bool transparent) const if (position_id != -1) { glsafe(::glEnableVertexAttribArray(position_id)); - glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)m_triangles.get_position_offset())); + glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_triangles.get_position_offset())); } if (tex_coords_id != -1) { glsafe(::glEnableVertexAttribArray(tex_coords_id)); - glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)m_triangles.get_tex_coords_offset())); + glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_triangles.get_tex_coords_offset())); } glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)m_triangles.get_vertices_count())); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e8973f6e3..84a4db965 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1922,9 +1922,6 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs &mode } object->ensure_on_bed(); - - // print.auto_assign_extruders(object); - // print.add_model_object(object); } #ifdef AUTOPLACEMENT_ON_LOAD diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 402b4248f..e681b8af1 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1129,7 +1129,6 @@ void Selection::copy_to_clipboard() dst_object->config = src_object->config; dst_object->sla_support_points = src_object->sla_support_points; dst_object->sla_points_status = src_object->sla_points_status; -// dst_object->layer_height_ranges = src_object->layer_height_ranges; dst_object->layer_config_ranges = src_object->layer_config_ranges; // #ys_FIXME_experiment dst_object->layer_height_profile = src_object->layer_height_profile; dst_object->origin_translation = src_object->origin_translation; -- cgit v1.2.3 From c198d826af9ead36c511b63b88363335e72487e0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 24 Jun 2019 15:43:16 +0200 Subject: Setting min_z bigger than max_z cause an increase of the max_z --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 12c1022ce..1426ccf02 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -82,13 +82,14 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) auto editor = new LayerRangeEditor(m_parent, double_to_string(range.first), etMinZ, set_focus_fn, [range, set_focus, this](coordf_t min_z, bool enter_pressed) { - if (fabs(min_z - range.first) < EPSILON || min_z > range.second) { + if (fabs(min_z - range.first) < EPSILON) { m_selection_type = etUndef; return false; } // data for next focusing - const t_layer_height_range& new_range = { min_z, range.second }; + coordf_t max_z = min_z < range.second ? range.second : min_z + 0.5; + const t_layer_height_range& new_range = { min_z, max_z/*range.second*/ }; set_focus(new_range, etMinZ, enter_pressed); return wxGetApp().obj_list()->edit_layer_range(range, new_range); -- cgit v1.2.3 From 4fb904357f9b3d727bb1dd8130cc7252f50e2e1e Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 25 Jun 2019 17:23:53 +0200 Subject: Warnings cleanup in BonjourDialog, ConfigWizard, FirmwareDialog, GLGizmoCut, ImGuiWrapper --- src/slic3r/GUI/BonjourDialog.cpp | 2 +- src/slic3r/GUI/ConfigWizard.cpp | 6 ++--- src/slic3r/GUI/FirmwareDialog.cpp | 3 +-- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 44 +----------------------------------- src/slic3r/GUI/ImGuiWrapper.cpp | 4 ++-- 5 files changed, 8 insertions(+), 51 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/BonjourDialog.cpp b/src/slic3r/GUI/BonjourDialog.cpp index 1885dda7b..0e05a517c 100644 --- a/src/slic3r/GUI/BonjourDialog.cpp +++ b/src/slic3r/GUI/BonjourDialog.cpp @@ -171,7 +171,7 @@ void BonjourDialog::on_reply(BonjourReplyEvent &e) // Filter replies based on selected technology const auto model = e.reply.txt_data.find("model"); const bool sl1 = model != e.reply.txt_data.end() && model->second == "SL1"; - if (tech == ptFFF && sl1 || tech == ptSLA && !sl1) { + if ((tech == ptFFF && sl1) || (tech == ptSLA && !sl1)) { return; } diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index aacbfdc52..8b08f6f7f 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -330,8 +330,8 @@ PagePrinters::PagePrinters(ConfigWizard *parent, wxString title, wxString shortn const auto families = vendor.families(); for (const auto &family : families) { const auto filter = [&](const VendorProfile::PrinterModel &model) { - return (model.technology == ptFFF && technology & T_FFF - || model.technology == ptSLA && technology & T_SLA) + return ((model.technology == ptFFF && technology & T_FFF) + || (model.technology == ptSLA && technology & T_SLA)) && model.family == family; }; @@ -810,7 +810,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) const Item& item = items[i]; unsigned x = em_w/2 + item.indent * em_w; - if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) { + if (i == item_active || (item_hover >= 0 && i == (size_t)item_hover)) { dc.DrawBitmap(bullet_blue.bmp(), x, y + yoff_icon, false); } else if (i < item_active) { dc.DrawBitmap(bullet_black.bmp(), x, y + yoff_icon, false); } diff --git a/src/slic3r/GUI/FirmwareDialog.cpp b/src/slic3r/GUI/FirmwareDialog.cpp index 15a09aa71..7865aecf2 100644 --- a/src/slic3r/GUI/FirmwareDialog.cpp +++ b/src/slic3r/GUI/FirmwareDialog.cpp @@ -442,8 +442,7 @@ void FirmwareDialog::priv::avr109_lookup_port(Avr109Pid usb_pid) auto ports = Utils::scan_serial_ports_extended(); ports.erase(std::remove_if(ports.begin(), ports.end(), [=](const SerialPortInfo &port ) { return port.id_vendor != USB_VID_PRUSA || - port.id_product != usb_pid.boot && - port.id_product != usb_pid.app; + (port.id_product != usb_pid.boot && port.id_product != usb_pid.app); }), ports.end()); if (ports.size() == 0) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 8934bc52b..17db953d4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -15,48 +15,6 @@ namespace Slic3r { namespace GUI { - -class GLGizmoCutPanel : public wxPanel -{ -public: - GLGizmoCutPanel(wxWindow *parent); - - void display(bool display); -private: - bool m_active; - wxCheckBox *m_cb_rotate; - wxButton *m_btn_cut; - wxButton *m_btn_cancel; -}; - -GLGizmoCutPanel::GLGizmoCutPanel(wxWindow *parent) - : wxPanel(parent) - , m_active(false) - , m_cb_rotate(new wxCheckBox(this, wxID_ANY, _(L("Rotate lower part upwards")))) - , m_btn_cut(new wxButton(this, wxID_OK, _(L("Perform cut")))) - , m_btn_cancel(new wxButton(this, wxID_CANCEL, _(L("Cancel")))) -{ - enum { MARGIN = 5 }; - - auto *sizer = new wxBoxSizer(wxHORIZONTAL); - - auto *label = new wxStaticText(this, wxID_ANY, _(L("Cut object:"))); - sizer->Add(label, 0, wxALL | wxALIGN_CENTER, MARGIN); - sizer->Add(m_cb_rotate, 0, wxALL | wxALIGN_CENTER, MARGIN); - sizer->AddStretchSpacer(); - sizer->Add(m_btn_cut, 0, wxALL | wxALIGN_CENTER, MARGIN); - sizer->Add(m_btn_cancel, 0, wxALL | wxALIGN_CENTER, MARGIN); - - SetSizer(sizer); -} - -void GLGizmoCutPanel::display(bool display) -{ - Show(display); - GetParent()->Layout(); -} - - const double GLGizmoCut::Offset = 10.0; const double GLGizmoCut::Margin = 20.0; const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 }; @@ -188,7 +146,7 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, co m_imgui->begin(_(L("Cut")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); ImGui::PushItemWidth(m_imgui->scaled(5.0f)); - bool _value_changed = ImGui::InputDouble("Z", &m_cut_z, 0.0f, 0.0f, "%.2f"); + ImGui::InputDouble("Z", &m_cut_z, 0.0f, 0.0f, "%.2f"); m_imgui->checkbox(_(L("Keep upper part")), m_keep_upper); m_imgui->checkbox(_(L("Keep lower part")), m_keep_lower); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index ca1538bf7..b6abf641a 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -326,9 +326,9 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector& int selection_out = -1; bool res = false; - const char *selection_str = selection < options.size() ? options[selection].c_str() : ""; + const char *selection_str = selection < (int)options.size() ? options[selection].c_str() : ""; if (ImGui::BeginCombo("", selection_str)) { - for (int i = 0; i < options.size(); i++) { + for (int i = 0; i < (int)options.size(); i++) { if (ImGui::Selectable(options[i].c_str(), i == selection)) { selection_out = i; } -- cgit v1.2.3 From d818d1b429044f547699f2625d2a74501528968f Mon Sep 17 00:00:00 2001 From: BeldrothTheGold Date: Sat, 15 Jun 2019 19:10:14 -0600 Subject: Add debug option to display picking pass to screen --- src/slic3r/GUI/GLCanvas3D.cpp | 2 ++ src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c828e0ec6..5d73c9248 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1625,6 +1625,7 @@ void GLCanvas3D::render() _picking_pass(); } +#if !ENABLE_RENDER_PICKING_PASS // draw scene glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); _render_background(); @@ -1654,6 +1655,7 @@ void GLCanvas3D::render() _render_current_gizmo(); _render_selection_sidebar_hints(); +#endif // !ENABLE_RENDER_PICKING_PASS #if ENABLE_SHOW_CAMERA_TARGET _render_camera_target(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index cfe07a61c..7e2b558d9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -259,6 +259,10 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const { +#if ENABLE_RENDER_PICKING_PASS + m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z(); +#endif + glsafe(::glEnable(GL_DEPTH_TEST)); render_points(selection, true); } -- cgit v1.2.3 From a710e7e7e4392e1be26db508784b2a35c1e75743 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 26 Jun 2019 13:26:49 +0200 Subject: WIP: Undo / Redo stack. Integration of the "cereal" serialization library. Serialization / deserialization of the DynamicConfig / DynamicPrintConfig. DynamicPrintConfig serializes ordinal identifiers instead of the option key strings to conserve space. --- src/slic3r/GUI/PresetBundle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index b28cb2eda..00c1f8168 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1366,7 +1366,7 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst continue; c << std::endl << "[" << presets->section_name() << ":" << preset.name << "]" << std::endl; for (const std::string &opt_key : preset.config.keys()) - c << opt_key << " = " << preset.config.serialize(opt_key) << std::endl; + c << opt_key << " = " << preset.config.opt_serialize(opt_key) << std::endl; } } -- cgit v1.2.3 From 104a289cfe48d20cfdea03cac0e10c1e7ca7beee Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 26 Jun 2019 13:30:20 +0200 Subject: Implemented interface for updating 3DScene after set a focus to some editor --- src/slic3r/GUI/GLCanvas3D.cpp | 5 ++++ src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ src/slic3r/GUI/GUI_ObjectLayers.cpp | 50 ++++++++++++++++++++++++------------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 16 ++++++++---- 4 files changed, 50 insertions(+), 23 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ffaa2d20c..138946166 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3310,6 +3310,11 @@ void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool foc } } +void GLCanvas3D::handle_layers_data_focus_event(const t_layer_height_range range, const EditorType type) +{ + printf("min_z = %.2f, max_z = %.2f, type=%d\n", range.first, range.second, type); +} + void GLCanvas3D::update_ui_from_settings() { #if ENABLE_RETINA_GL diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d39a910b3..95fd123eb 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -12,6 +12,7 @@ #include "Camera.hpp" #include "Selection.hpp" #include "Gizmos/GLGizmosManager.hpp" +#include "GUI_ObjectLayers.hpp" #include @@ -606,6 +607,7 @@ public: void reset_all_gizmos() { m_gizmos.reset_all_states(); } void handle_sidebar_focus_event(const std::string& opt_key, bool focus_on); + void handle_layers_data_focus_event(const t_layer_height_range range, const EditorType type); void update_ui_from_settings(); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 1426ccf02..d854e54b3 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -4,6 +4,7 @@ #include "OptionsGroup.hpp" #include "PresetBundle.hpp" #include "libslic3r/Model.hpp" +#include "GLCanvas3D.hpp" #include @@ -62,13 +63,13 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) { const bool is_last_edited_range = range == m_selectable_range; - auto set_focus_fn = [range, this](const EditorType type) + auto set_focus_data = [range, this](const EditorType type) { m_selectable_range = range; m_selection_type = type; }; - auto set_focus = [range, this](const t_layer_height_range& new_range, EditorType type, bool enter_pressed) + auto update_focus_data = [range, this](const t_layer_height_range& new_range, EditorType type, bool enter_pressed) { // change selectable range for new one, if enter was pressed or if same range was selected if (enter_pressed || m_selectable_range == range) @@ -79,8 +80,8 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // Add control for the "Min Z" - auto editor = new LayerRangeEditor(m_parent, double_to_string(range.first), etMinZ, - set_focus_fn, [range, set_focus, this](coordf_t min_z, bool enter_pressed) + auto editor = new LayerRangeEditor(this, double_to_string(range.first), etMinZ, + set_focus_data, [range, update_focus_data, this](coordf_t min_z, bool enter_pressed) { if (fabs(min_z - range.first) < EPSILON) { m_selection_type = etUndef; @@ -89,8 +90,8 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // data for next focusing coordf_t max_z = min_z < range.second ? range.second : min_z + 0.5; - const t_layer_height_range& new_range = { min_z, max_z/*range.second*/ }; - set_focus(new_range, etMinZ, enter_pressed); + const t_layer_height_range& new_range = { min_z, max_z }; + update_focus_data(new_range, etMinZ, enter_pressed); return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); @@ -100,8 +101,8 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // Add control for the "Max Z" - editor = new LayerRangeEditor(m_parent, double_to_string(range.second), etMaxZ, - set_focus_fn, [range, set_focus, this](coordf_t max_z, bool enter_pressed) + editor = new LayerRangeEditor(this, double_to_string(range.second), etMaxZ, + set_focus_data, [range, update_focus_data, this](coordf_t max_z, bool enter_pressed) { if (fabs(max_z - range.second) < EPSILON || range.first > max_z) { m_selection_type = etUndef; @@ -110,7 +111,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // data for next focusing const t_layer_height_range& new_range = { range.first, max_z }; - set_focus(new_range, etMaxZ, enter_pressed); + update_focus_data(new_range, etMaxZ, enter_pressed); return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); @@ -120,9 +121,9 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) // Add control for the "Layer height" - editor = new LayerRangeEditor(m_parent, + editor = new LayerRangeEditor(this, double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), - etLayerHeight, set_focus_fn, [range, this](coordf_t layer_height, bool) + etLayerHeight, set_focus_data, [range, this](coordf_t layer_height, bool) { return wxGetApp().obj_list()->edit_layer_range(range, layer_height); }); @@ -203,6 +204,12 @@ void ObjectLayers::update_layers_list() m_parent->Layout(); } +void ObjectLayers::update_scene_from_editor_selection() const +{ + // needed to show the visual hints in 3D scene + wxGetApp().plater()->canvas3D()->handle_layers_data_focus_event(m_selectable_range, m_selection_type); +} + void ObjectLayers::UpdateAndShow(const bool show) { if (show) @@ -217,17 +224,17 @@ void ObjectLayers::msw_rescale() m_bmp_add.msw_rescale(); } -LayerRangeEditor::LayerRangeEditor( wxWindow* parent, +LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, const wxString& value, EditorType type, - std::function set_focus_fn, + std::function set_focus_data_fn, std::function edit_fn ) : m_valid_value(value), m_type(type), - m_set_focus(set_focus_fn), - wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, - wxSize(8 * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) + m_set_focus_data(set_focus_data_fn), + wxTextCtrl(parent->m_parent, wxID_ANY, value, wxDefaultPosition, + wxSize(8 * em_unit(parent->m_parent), wxDefaultCoord), wxTE_PROCESS_ENTER) { this->SetFont(wxGetApp().normal_font()); @@ -258,7 +265,7 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, * */ LayerRangeEditor* new_editor = dynamic_cast(e.GetWindow()); if (new_editor) - new_editor->set_focus(); + new_editor->set_focus_data(); #endif // not __WXGTK__ // If LayersList wasn't updated/recreated, we should call e.Skip() if (m_type & etLayerHeight) { @@ -279,10 +286,17 @@ LayerRangeEditor::LayerRangeEditor( wxWindow* parent, } }, this->GetId()); + this->Bind(wxEVT_SET_FOCUS, [this, parent](wxFocusEvent& e) + { + set_focus_data(); + parent->update_scene_from_editor_selection(); + e.Skip(); + }, this->GetId()); + #ifdef __WXGTK__ // Workaround! To take information about selectable range this->Bind(wxEVT_LEFT_DOWN, [this](wxEvent& e) { - set_focus(); + set_focus_data(); e.Skip(); }, this->GetId()); #endif //__WXGTK__ diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index e3366e03e..f19217fbe 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -19,6 +19,8 @@ class ConfigOptionsGroup; typedef double coordf_t; typedef std::pair t_layer_height_range; +class ObjectLayers; + enum EditorType { etUndef = 0, @@ -34,19 +36,19 @@ class LayerRangeEditor : public wxTextCtrl wxString m_valid_value; EditorType m_type; - std::function m_set_focus; + std::function m_set_focus_data; public: - LayerRangeEditor( wxWindow* parent, + LayerRangeEditor( ObjectLayers* parent, const wxString& value = wxEmptyString, EditorType type = etUndef, - std::function set_focus_fn = [](EditorType) {;}, - std::function edit_fn = [](coordf_t, bool) {return false; } + std::function set_focus_data_fn = [](EditorType) {;}, + std::function edit_fn = [](coordf_t, bool) {return false; } ); ~LayerRangeEditor() {} EditorType type() const {return m_type;} - void set_focus() const { m_set_focus(m_type);} + void set_focus_data() const { m_set_focus_data(m_type);} private: coordf_t get_value(); @@ -71,8 +73,12 @@ public: void create_layers_list(); void update_layers_list(); + void update_scene_from_editor_selection() const; + void UpdateAndShow(const bool show) override; void msw_rescale(); + + friend class LayerRangeEditor; }; }} -- cgit v1.2.3 From 27ee68d2f9666f5ad48d5ffacf1d6ea404156dda Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 27 Jun 2019 11:02:45 +0200 Subject: WIP Undo / Redo: ModelID / ModelBase renamed to ObjectID / ObjectBase --- src/slic3r/GUI/GLCanvas3D.cpp | 8 ++++---- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 +- src/slic3r/GUI/Selection.hpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cf8a49ea2..4116ac34b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1812,14 +1812,14 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re struct ModelVolumeState { ModelVolumeState(const GLVolume *volume) : model_volume(nullptr), geometry_id(volume->geometry_id), volume_idx(-1) {} - ModelVolumeState(const ModelVolume *model_volume, const ModelID &instance_id, const GLVolume::CompositeID &composite_id) : + ModelVolumeState(const ModelVolume *model_volume, const ObjectID &instance_id, const GLVolume::CompositeID &composite_id) : model_volume(model_volume), geometry_id(std::make_pair(model_volume->id().id, instance_id.id)), composite_id(composite_id), volume_idx(-1) {} - ModelVolumeState(const ModelID &volume_id, const ModelID &instance_id) : + ModelVolumeState(const ObjectID &volume_id, const ObjectID &instance_id) : model_volume(nullptr), geometry_id(std::make_pair(volume_id.id, instance_id.id)), volume_idx(-1) {} bool new_geometry() const { return this->volume_idx == size_t(-1); } const ModelVolume *model_volume; - // ModelID of ModelVolume + ModelID of ModelInstance - // or timestamp of an SLAPrintObjectStep + ModelID of ModelInstance + // ObjectID of ModelVolume + ObjectID of ModelInstance + // or timestamp of an SLAPrintObjectStep + ObjectID of ModelInstance std::pair geometry_id; GLVolume::CompositeID composite_id; // Volume index in the new GLVolume vector. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index cfe07a61c..9e703caaa 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -380,7 +380,7 @@ bool GLGizmoSlaSupports::is_point_clipped(const Vec3d& point) const bool GLGizmoSlaSupports::is_mesh_update_necessary() const { return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty()) - && ((m_model_object->id() != m_current_mesh_model_id) || m_its == nullptr); + && ((m_model_object->id() != m_current_mesh_object_id) || m_its == nullptr); } void GLGizmoSlaSupports::update_mesh() @@ -390,7 +390,7 @@ void GLGizmoSlaSupports::update_mesh() // This mesh does not account for the possible Z up SLA offset. m_mesh = &m_model_object->volumes.front()->mesh(); m_its = &m_mesh->its; - m_current_mesh_model_id = m_model_object->id(); + m_current_mesh_object_id = m_model_object->id(); m_editing_mode = false; m_AABB.deinit(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 30238cc9d..8a5cdf3ef 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -26,7 +26,7 @@ class GLGizmoSlaSupports : public GLGizmoBase { private: ModelObject* m_model_object = nullptr; - ModelID m_current_mesh_model_id = 0; + ObjectID m_current_mesh_object_id = 0; int m_active_instance = -1; float m_active_instance_bb_radius; // to cache the bb mutable float m_z_shift = 0.f; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 802f8d284..c23f23e6b 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -171,7 +171,7 @@ private: Vec3d dragging_center; // Map from indices of ModelObject instances in Model::objects // to a set of indices of ModelVolume instances in ModelObject::instances - // Here the index means a position inside the respective std::vector, not ModelID. + // Here the index means a position inside the respective std::vector, not ObjectID. ObjectIdxsToInstanceIdxsMap content; }; -- cgit v1.2.3 From 90d1ac2c8f67329ae2cfeee9bf8ce24086db923a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 27 Jun 2019 11:25:04 +0200 Subject: Tech ENABLE_RENDER_PICKING_PASS extended so that user can switch between picking pass texture rendering and regular rendering by pressing [T] key --- src/slic3r/GUI/GLCanvas3D.cpp | 20 ++++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 4 ++++ src/slic3r/GUI/KBShortcutsDialog.cpp | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c3fd020e0..9bb6f4553 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1224,6 +1224,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar , m_cursor_type(Standard) , m_color_by("volume") , m_reload_delayed(false) +#if ENABLE_RENDER_PICKING_PASS + , m_show_picking_texture(false) +#endif // ENABLE_RENDER_PICKING_PASS , m_render_sla_auxiliaries(true) { if (m_canvas != nullptr) { @@ -1627,7 +1630,10 @@ void GLCanvas3D::render() _picking_pass(); } -#if !ENABLE_RENDER_PICKING_PASS +#if ENABLE_RENDER_PICKING_PASS + if (!m_picking_enabled || !m_show_picking_texture) + { +#endif // ENABLE_RENDER_PICKING_PASS // draw scene glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); _render_background(); @@ -1657,7 +1663,9 @@ void GLCanvas3D::render() _render_current_gizmo(); _render_selection_sidebar_hints(); -#endif // !ENABLE_RENDER_PICKING_PASS +#if ENABLE_RENDER_PICKING_PASS + } +#endif // ENABLE_RENDER_PICKING_PASS #if ENABLE_SHOW_CAMERA_TARGET _render_camera_target(); @@ -2399,6 +2407,14 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'k': { m_camera.select_next_type(); m_dirty = true; break; } case 'O': case 'o': { set_camera_zoom(-1.0); break; } +#if ENABLE_RENDER_PICKING_PASS + case 'T': + case 't': { + m_show_picking_texture = !m_show_picking_texture; + m_dirty = true; + break; + } +#endif // ENABLE_RENDER_PICKING_PASS case 'Z': case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; } default: { evt.Skip(); break; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 5a4287903..c891ed06f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -477,6 +477,10 @@ private: GCodePreviewVolumeIndex m_gcode_preview_volume_index; +#if ENABLE_RENDER_PICKING_PASS + bool m_show_picking_texture; +#endif // ENABLE_RENDER_PICKING_PASS + #if ENABLE_RENDER_STATISTICS RenderStats m_render_stats; #endif // ENABLE_RENDER_STATISTICS diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 1af658ed3..955c4b60b 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -154,6 +154,9 @@ void KBShortcutsDialog::fill_shortcuts() plater_shortcuts.push_back(Shortcut("I", L("Zoom in"))); plater_shortcuts.push_back(Shortcut("O", L("Zoom out"))); plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo / Clear selection"))); +#if ENABLE_RENDER_PICKING_PASS + plater_shortcuts.push_back(Shortcut("T", L("Toggle picking pass texture rendering on/off"))); +#endif // ENABLE_RENDER_PICKING_PASS m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, szRight))); -- cgit v1.2.3 From 1058721dba84f0c7e35a34d7b7b23382004307c1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 27 Jun 2019 13:42:50 +0200 Subject: Added visual hints in 3D scene for layers editing --- src/slic3r/GUI/GLCanvas3D.cpp | 11 +-- src/slic3r/GUI/GUI_ObjectLayers.cpp | 2 + src/slic3r/GUI/Selection.cpp | 154 +++++++++++++++++++++++++++--------- src/slic3r/GUI/Selection.hpp | 5 +- 4 files changed, 126 insertions(+), 46 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 60afcb653..bdfd0507a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3307,7 +3307,8 @@ void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool foc void GLCanvas3D::handle_layers_data_focus_event(const t_layer_height_range range, const EditorType type) { - printf("min_z = %.2f, max_z = %.2f, type=%d\n", range.first, range.second, type); + std::string field = "layer_" + std::to_string(type) + "_" + std::to_string(range.first) + "_" + std::to_string(range.second); + handle_sidebar_focus_event(field, true); } void GLCanvas3D::update_ui_from_settings() @@ -4275,13 +4276,7 @@ void GLCanvas3D::_render_sla_slices() const void GLCanvas3D::_render_selection_sidebar_hints() const { - if (m_use_VBOs) - m_shader.start_using(); - - m_selection.render_sidebar_hints(m_sidebar_field); - - if (m_use_VBOs) - m_shader.stop_using(); + m_selection.render_sidebar_hints(m_sidebar_field, m_shader); } diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index d854e54b3..ff0f55aef 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -257,6 +257,8 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e) { + wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); + if (!m_enter_pressed) { #ifndef __WXGTK__ /* Update data for next editor selection. diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index c6c85e21f..82bc52d3a 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1070,62 +1070,69 @@ void Selection::render_center(bool gizmo_is_dragging) const } #endif // ENABLE_RENDER_SELECTION_CENTER -void Selection::render_sidebar_hints(const std::string& sidebar_field) const +void Selection::render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const { if (sidebar_field.empty()) return; - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_DEPTH_TEST)); + if (!boost::starts_with(sidebar_field, "layer")) + { + shader.start_using(); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_LIGHTING)); + } - glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glPushMatrix()); - const Vec3d& center = get_bounding_box().center(); - - if (is_single_full_instance() && ! wxGetApp().obj_manipul()->get_world_coordinates()) + if (!boost::starts_with(sidebar_field, "layer")) { - glsafe(::glTranslated(center(0), center(1), center(2))); - if (!boost::starts_with(sidebar_field, "position")) + const Vec3d& center = get_bounding_box().center(); + + if (is_single_full_instance() && !wxGetApp().obj_manipul()->get_world_coordinates()) { - Transform3d orient_matrix = Transform3d::Identity(); - if (boost::starts_with(sidebar_field, "scale")) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::starts_with(sidebar_field, "rotation")) + glsafe(::glTranslated(center(0), center(1), center(2))); + if (!boost::starts_with(sidebar_field, "position")) { - if (boost::ends_with(sidebar_field, "x")) + Transform3d orient_matrix = Transform3d::Identity(); + if (boost::starts_with(sidebar_field, "scale")) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::ends_with(sidebar_field, "y")) + else if (boost::starts_with(sidebar_field, "rotation")) { - const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); - if (rotation(0) == 0.0) + if (boost::ends_with(sidebar_field, "x")) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else - orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); + else if (boost::ends_with(sidebar_field, "y")) + { + const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); + if (rotation(0) == 0.0) + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + else + orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); + } } - } - glsafe(::glMultMatrixd(orient_matrix.data())); + glsafe(::glMultMatrixd(orient_matrix.data())); + } } - } - else if (is_single_volume() || is_single_modifier()) - { - glsafe(::glTranslated(center(0), center(1), center(2))); - Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - if (!boost::starts_with(sidebar_field, "position")) - orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true); - - glsafe(::glMultMatrixd(orient_matrix.data())); - } - else - { - glsafe(::glTranslated(center(0), center(1), center(2))); - if (requires_local_axes()) + else if (is_single_volume() || is_single_modifier()) { + glsafe(::glTranslated(center(0), center(1), center(2))); Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + if (!boost::starts_with(sidebar_field, "position")) + orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true); + glsafe(::glMultMatrixd(orient_matrix.data())); } + else + { + glsafe(::glTranslated(center(0), center(1), center(2))); + if (requires_local_axes()) + { + Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + glsafe(::glMultMatrixd(orient_matrix.data())); + } + } } if (boost::starts_with(sidebar_field, "position")) @@ -1136,10 +1143,16 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const render_sidebar_scale_hints(sidebar_field); else if (boost::starts_with(sidebar_field, "size")) render_sidebar_size_hints(sidebar_field); + else if (boost::starts_with(sidebar_field, "layer")) + render_sidebar_layers_hints(sidebar_field); glsafe(::glPopMatrix()); - glsafe(::glDisable(GL_LIGHTING)); + if (!boost::starts_with(sidebar_field, "layer")) + { + glsafe(::glDisable(GL_LIGHTING)); + shader.stop_using(); + } } bool Selection::requires_local_axes() const @@ -1709,6 +1722,75 @@ void Selection::render_sidebar_size_hints(const std::string& sidebar_field) cons render_sidebar_scale_hints(sidebar_field); } +void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) const +{ + static const double Margin = 10.0; + + std::string field = sidebar_field; + + // extract max_z + std::string::size_type pos = field.rfind("_"); + if (pos == std::string::npos) + return; + + double max_z = std::stod(field.substr(pos + 1)); + + // extract min_z + field = field.substr(0, pos); + pos = field.rfind("_"); + if (pos == std::string::npos) + return; + + double min_z = std::stod(field.substr(pos + 1)); + + // extract type + field = field.substr(0, pos); + pos = field.rfind("_"); + if (pos == std::string::npos) + return; + + int type = std::stoi(field.substr(pos + 1)); + + const BoundingBoxf3& box = get_bounding_box(); + + const float min_x = box.min(0) - Margin; + const float max_x = box.max(0) + Margin; + const float min_y = box.min(1) - Margin; + const float max_y = box.max(1) + Margin; + + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + // Draw the min_z plane + ::glBegin(GL_QUADS); + if (type == 1) + ::glColor4f(1.0f, 0.38f, 0.0f, 1.0f); + else + ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glVertex3f(min_x, min_y, min_z); + ::glVertex3f(max_x, min_y, min_z); + ::glVertex3f(max_x, max_y, min_z); + ::glVertex3f(min_x, max_y, min_z); + glsafe(::glEnd()); + + // Draw the max_z plane + ::glBegin(GL_QUADS); + if (type == 2) + ::glColor4f(1.0f, 0.38f, 0.0f, 1.0f); + else + ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glVertex3f(min_x, min_y, max_z); + ::glVertex3f(max_x, min_y, max_z); + ::glVertex3f(max_x, max_y, max_z); + ::glVertex3f(min_x, max_y, max_z); + glsafe(::glEnd()); + + glsafe(::glEnable(GL_CULL_FACE)); + glsafe(::glDisable(GL_BLEND)); +} + void Selection::render_sidebar_position_hint(Axis axis) const { m_arrow.set_color(AXES_COLOR[axis], 3); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 802f8d284..31b68917e 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -11,8 +11,8 @@ typedef class GLUquadric GLUquadricObj; #endif // ENABLE_RENDER_SELECTION_CENTER namespace Slic3r { +class Shader; namespace GUI { - class TransformationType { public: @@ -302,7 +302,7 @@ public: #if ENABLE_RENDER_SELECTION_CENTER void render_center(bool gizmo_is_dragging) const; #endif // ENABLE_RENDER_SELECTION_CENTER - void render_sidebar_hints(const std::string& sidebar_field) const; + void render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const; bool requires_local_axes() const; @@ -332,6 +332,7 @@ private: void render_sidebar_rotation_hints(const std::string& sidebar_field) const; void render_sidebar_scale_hints(const std::string& sidebar_field) const; void render_sidebar_size_hints(const std::string& sidebar_field) const; + void render_sidebar_layers_hints(const std::string& sidebar_field) const; void render_sidebar_position_hint(Axis axis) const; void render_sidebar_rotation_hint(Axis axis) const; void render_sidebar_scale_hint(Axis axis) const; -- cgit v1.2.3 From 26c8eed1ae9280e15bf6416a2aa88e0659e1a006 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 27 Jun 2019 14:42:55 +0200 Subject: Removed memory leaks due to GUI_App::app_config, GUI_App::preset_bundle and GUI_App::preset_updater not being deleted --- src/slic3r/GUI/GUI_App.cpp | 12 ++++++++++++ src/slic3r/GUI/GUI_App.hpp | 1 + 2 files changed, 13 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4f1c3adc8..0e79a3d02 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -141,6 +141,18 @@ GUI_App::GUI_App() , m_imgui(new ImGuiWrapper()) {} +GUI_App::~GUI_App() +{ + if (app_config != nullptr) + delete app_config; + + if (preset_bundle != nullptr) + delete preset_bundle; + + if (preset_updater != nullptr) + delete preset_updater; +} + bool GUI_App::OnInit() { try { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 3f8b23e2d..5a4da22d3 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -95,6 +95,7 @@ public: bool initialized() const { return m_initialized; } GUI_App(); + ~GUI_App(); static unsigned get_colour_approx_luma(const wxColour &colour); static bool dark_mode(); -- cgit v1.2.3 From 97bb4a80cc9dc3a16d940e51974b31fa17e9cc54 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 27 Jun 2019 15:16:36 +0200 Subject: Removed memory leaks due to Sidebar::priv::object_manipulation, Sidebar::priv::object_settings and Sidebar::priv::frequently_changed_parameters not being deleted --- src/slic3r/GUI/Plater.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 472394d43..65cf326df 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -614,10 +614,10 @@ struct Sidebar::priv PresetComboBox *combo_printer; wxBoxSizer *sizer_params; - FreqChangedParams *frequently_changed_parameters; - ObjectList *object_list; - ObjectManipulation *object_manipulation; - ObjectSettings *object_settings; + FreqChangedParams *frequently_changed_parameters{ nullptr }; + ObjectList *object_list{ nullptr }; + ObjectManipulation *object_manipulation{ nullptr }; + ObjectSettings *object_settings{ nullptr }; ObjectInfo *object_info; SlicedInfo *sliced_info; @@ -626,10 +626,23 @@ struct Sidebar::priv wxButton *btn_send_gcode; priv(Plater *plater) : plater(plater) {} + ~priv(); void show_preset_comboboxes(); }; +Sidebar::priv::~priv() +{ + if (object_manipulation != nullptr) + delete object_manipulation; + + if (object_settings != nullptr) + delete object_settings; + + if (frequently_changed_parameters != nullptr) + delete frequently_changed_parameters; +} + void Sidebar::priv::show_preset_comboboxes() { const bool showSLA = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; -- cgit v1.2.3 From 6cfb9bec363f6d485bcf8b5b73747df8c793e320 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 27 Jun 2019 15:23:03 +0200 Subject: Removed memory leaks due to Plater::priv::config not being deleted --- src/slic3r/GUI/Plater.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 65cf326df..a0deb52e3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1526,6 +1526,7 @@ struct Plater::priv static const std::regex pattern_prusa; priv(Plater *q, MainFrame *main_frame); + ~priv(); void update(bool force_full_scene_refresh = false); void select_view(const std::string& direction); @@ -1795,6 +1796,12 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) camera.set_type(get_config("use_perspective_camera")); } +Plater::priv::~priv() +{ + if (config != nullptr) + delete config; +} + void Plater::priv::update(bool force_full_scene_refresh) { // the following line, when enabled, causes flickering on NVIDIA graphics cards -- cgit v1.2.3 From 0b940ec0895cac520eea06c5e1582544a582c019 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 27 Jun 2019 15:57:29 +0200 Subject: Some code improvements --- src/slic3r/GUI/Selection.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 82bc52d3a..9939c291e 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -331,6 +331,9 @@ void Selection::clear() // resets the cache in the sidebar wxGetApp().obj_manipul()->reset_cache(); + + // #et_FIXME fake KillFocus from sidebar + wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); } // Update the selection based on the new instance IDs. -- cgit v1.2.3 From d7c418ef84eabacdb83171277098a6c769ea00d4 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 1 Jul 2019 08:33:40 +0200 Subject: Modified function thick_lines_to_indexed_vertex_array() to remove visual artifacts on paths in gcode preview --- src/slic3r/GUI/3DScene.cpp | 167 +++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 119 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index f9a79f2d8..5853ab712 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1020,8 +1020,8 @@ static void thick_lines_to_indexed_vertex_array( // right, left, top, bottom int idx_prev[4] = { -1, -1, -1, -1 }; double bottom_z_prev = 0.; - Vec2d b1_prev(Vec2d::Zero()); - Vec2d v_prev(Vec2d::Zero()); + Vec2d b1_prev(Vec2d::Zero()); + Vec2d v_prev(Vec2d::Zero()); int idx_initial[4] = { -1, -1, -1, -1 }; double width_initial = 0.; double bottom_z_initial = 0.0; @@ -1031,8 +1031,6 @@ static void thick_lines_to_indexed_vertex_array( for (size_t ii = 0; ii < lines_end; ++ ii) { size_t i = (ii == lines.size()) ? 0 : ii; const Line &line = lines[i]; - double len = unscale(line.length()); - double inv_len = 1.0 / len; double bottom_z = top_z - heights[i]; double middle_z = 0.5 * (top_z + bottom_z); double width = widths[i]; @@ -1041,8 +1039,7 @@ static void thick_lines_to_indexed_vertex_array( bool is_last = (ii == lines_end - 1); bool is_closing = closed && is_last; - Vec2d v = unscale(line.vector()); - v *= inv_len; + Vec2d v = unscale(line.vector()).normalized(); Vec2d a = unscale(line.a); Vec2d b = unscale(line.b); @@ -1061,9 +1058,7 @@ static void thick_lines_to_indexed_vertex_array( } // calculate new XY normals - Vector n = line.normal(); - Vec3d xy_right_normal = unscale(n(0), n(1), 0); - xy_right_normal *= inv_len; + Vec2d xy_right_normal = unscale(line.normal()).normalized(); int idx_a[4]; int idx_b[4]; @@ -1091,9 +1086,9 @@ static void thick_lines_to_indexed_vertex_array( idx_a[BOTTOM] = idx_last ++; volume.push_geometry(a(0), a(1), bottom_z, 0., 0., -1.); idx_a[LEFT ] = idx_last ++; - volume.push_geometry(a2(0), a2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), -xy_right_normal(2)); + volume.push_geometry(a2(0), a2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), 0.0); idx_a[RIGHT] = idx_last ++; - volume.push_geometry(a1(0), a1(1), middle_z, xy_right_normal(0), xy_right_normal(1), xy_right_normal(2)); + volume.push_geometry(a1(0), a1(1), middle_z, xy_right_normal(0), xy_right_normal(1), 0.0); } else { idx_a[BOTTOM] = idx_prev[BOTTOM]; @@ -1108,18 +1103,29 @@ static void thick_lines_to_indexed_vertex_array( // Continuing a previous segment. // Share left / right vertices if possible. double v_dot = v_prev.dot(v); - bool sharp = v_dot < 0.707; // sin(45 degrees) + bool sharp = v_dot < 0.9999; // v_dot < 0.9999; // cos(1 degree) if (sharp) { if (!bottom_z_different) { // Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn. idx_a[RIGHT] = idx_last++; - volume.push_geometry(a1(0), a1(1), middle_z, xy_right_normal(0), xy_right_normal(1), xy_right_normal(2)); + volume.push_geometry(a1(0), a1(1), middle_z, xy_right_normal(0), xy_right_normal(1), 0.0); idx_a[LEFT] = idx_last++; - volume.push_geometry(a2(0), a2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), -xy_right_normal(2)); + volume.push_geometry(a2(0), a2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), 0.0); + if (cross2(v_prev, v) > 0.) { + // Right turn. Fill in the right turn wedge. + volume.push_triangle(idx_prev[RIGHT], idx_a[RIGHT], idx_prev[TOP]); + volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a[RIGHT]); + } + else { + // Left turn. Fill in the left turn wedge. + volume.push_triangle(idx_prev[LEFT], idx_prev[TOP], idx_a[LEFT]); + volume.push_triangle(idx_prev[LEFT], idx_a[LEFT], idx_prev[BOTTOM]); + } } } - if (v_dot > 0.9) { + else + { if (!bottom_z_different) { // The two successive segments are nearly collinear. @@ -1127,45 +1133,6 @@ static void thick_lines_to_indexed_vertex_array( idx_a[RIGHT] = idx_prev[RIGHT]; } } - else if (!sharp) { - if (!bottom_z_different) - { - // Create a sharp corner with an overshot and average the left / right normals. - // At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc. - Vec2d intersection(Vec2d::Zero()); - Geometry::ray_ray_intersection(b1_prev, v_prev, a1, v, intersection); - a1 = intersection; - a2 = 2. * a - intersection; - assert((a - a1).norm() < width); - assert((a - a2).norm() < width); - float *n_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6; - float *p_left_prev = n_left_prev + 3; - float *n_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6; - float *p_right_prev = n_right_prev + 3; - p_left_prev [0] = float(a2(0)); - p_left_prev [1] = float(a2(1)); - p_right_prev[0] = float(a1(0)); - p_right_prev[1] = float(a1(1)); - xy_right_normal(0) += n_right_prev[0]; - xy_right_normal(1) += n_right_prev[1]; - xy_right_normal *= 1. / xy_right_normal.norm(); - n_left_prev [0] = float(-xy_right_normal(0)); - n_left_prev [1] = float(-xy_right_normal(1)); - n_right_prev[0] = float( xy_right_normal(0)); - n_right_prev[1] = float( xy_right_normal(1)); - idx_a[LEFT ] = idx_prev[LEFT ]; - idx_a[RIGHT] = idx_prev[RIGHT]; - } - } - else if (cross2(v_prev, v) > 0.) { - // Right turn. Fill in the right turn wedge. - volume.push_triangle(idx_prev[RIGHT], idx_a [RIGHT], idx_prev[TOP] ); - volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a [RIGHT] ); - } else { - // Left turn. Fill in the left turn wedge. - volume.push_triangle(idx_prev[LEFT], idx_prev[TOP], idx_a [LEFT] ); - volume.push_triangle(idx_prev[LEFT], idx_a [LEFT], idx_prev[BOTTOM]); - } if (is_closing) { if (!sharp) { if (!bottom_z_different) @@ -1204,9 +1171,9 @@ static void thick_lines_to_indexed_vertex_array( } // Generate new vertices for the end of this line segment. idx_b[LEFT ] = idx_last ++; - volume.push_geometry(b2(0), b2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), -xy_right_normal(2)); + volume.push_geometry(b2(0), b2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), 0.0); idx_b[RIGHT ] = idx_last ++; - volume.push_geometry(b1(0), b1(1), middle_z, xy_right_normal(0), xy_right_normal(1), xy_right_normal(2)); + volume.push_geometry(b1(0), b1(1), middle_z, xy_right_normal(0), xy_right_normal(1), 0.0); memcpy(idx_prev, idx_b, 4 * sizeof(int)); bottom_z_prev = bottom_z; @@ -1265,9 +1232,9 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, int idx_initial[4] = { -1, -1, -1, -1 }; int idx_prev[4] = { -1, -1, -1, -1 }; double z_prev = 0.0; - Vec3d n_right_prev = Vec3d::Zero(); - Vec3d n_top_prev = Vec3d::Zero(); - Vec3d unit_v_prev = Vec3d::Zero(); + Vec3d n_right_prev = Vec3d::Zero(); + Vec3d n_top_prev = Vec3d::Zero(); + Vec3d unit_v_prev = Vec3d::Zero(); double width_initial = 0.0; // new vertices around the line endpoints @@ -1289,18 +1256,19 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, Vec3d n_top = Vec3d::Zero(); Vec3d n_right = Vec3d::Zero(); - Vec3d unit_positive_z(0.0, 0.0, 1.0); - + if ((line.a(0) == line.b(0)) && (line.a(1) == line.b(1))) { // vertical segment - n_right = (line.a(2) < line.b(2)) ? Vec3d(-1.0, 0.0, 0.0) : Vec3d(1.0, 0.0, 0.0); - n_top = Vec3d(0.0, 1.0, 0.0); + n_top = Vec3d::UnitY(); + n_right = Vec3d::UnitX(); + if (line.a(2) < line.b(2)) + n_right = -n_right; } else { - // generic segment - n_right = unit_v.cross(unit_positive_z).normalized(); + // horizontal segment + n_right = unit_v.cross(Vec3d::UnitZ()).normalized(); n_top = n_right.cross(unit_v).normalized(); } @@ -1361,7 +1329,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, // Continuing a previous segment. // Share left / right vertices if possible. double v_dot = unit_v_prev.dot(unit_v); - bool is_sharp = v_dot < 0.707; // sin(45 degrees) + bool is_sharp = v_dot < 0.9999; // v_dot < 0.9999; // cos(1 degree) bool is_right_turn = n_top_prev.dot(unit_v_prev.cross(unit_v)) > 0.0; if (is_sharp) @@ -1371,65 +1339,26 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, volume.push_geometry(a[RIGHT], n_right); idx_a[LEFT] = idx_last++; volume.push_geometry(a[LEFT], n_left); - } - if (v_dot > 0.9) - { - // The two successive segments are nearly collinear. - idx_a[LEFT] = idx_prev[LEFT]; - idx_a[RIGHT] = idx_prev[RIGHT]; + if (is_right_turn) + { + // Right turn. Fill in the right turn wedge. + volume.push_triangle(idx_prev[RIGHT], idx_a[RIGHT], idx_prev[TOP]); + volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a[RIGHT]); + } + else + { + // Left turn. Fill in the left turn wedge. + volume.push_triangle(idx_prev[LEFT], idx_prev[TOP], idx_a[LEFT]); + volume.push_triangle(idx_prev[LEFT], idx_a[LEFT], idx_prev[BOTTOM]); + } } - else if (!is_sharp) + else { - // Create a sharp corner with an overshot and average the left / right normals. - // At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc. - - // averages normals - Vec3d average_n_right = 0.5 * (n_right + n_right_prev).normalized(); - Vec3d average_n_left = -average_n_right; - Vec3d average_rl_displacement = 0.5 * width * average_n_right; - - // updates vertices around a - a[RIGHT] = l_a + average_rl_displacement; - a[LEFT] = l_a - average_rl_displacement; - - // updates previous line normals - float* normal_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT] * 6; - normal_left_prev[0] = float(average_n_left(0)); - normal_left_prev[1] = float(average_n_left(1)); - normal_left_prev[2] = float(average_n_left(2)); - - float* normal_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6; - normal_right_prev[0] = float(average_n_right(0)); - normal_right_prev[1] = float(average_n_right(1)); - normal_right_prev[2] = float(average_n_right(2)); - - // updates previous line's vertices around b - float* b_left_prev = normal_left_prev + 3; - b_left_prev[0] = float(a[LEFT](0)); - b_left_prev[1] = float(a[LEFT](1)); - b_left_prev[2] = float(a[LEFT](2)); - - float* b_right_prev = normal_right_prev + 3; - b_right_prev[0] = float(a[RIGHT](0)); - b_right_prev[1] = float(a[RIGHT](1)); - b_right_prev[2] = float(a[RIGHT](2)); - + // The two successive segments are nearly collinear. idx_a[LEFT] = idx_prev[LEFT]; idx_a[RIGHT] = idx_prev[RIGHT]; } - else if (is_right_turn) - { - // Right turn. Fill in the right turn wedge. - volume.push_triangle(idx_prev[RIGHT], idx_a[RIGHT], idx_prev[TOP]); - volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a[RIGHT]); - } - else - { - // Left turn. Fill in the left turn wedge. - volume.push_triangle(idx_prev[LEFT], idx_prev[TOP], idx_a[LEFT]); - volume.push_triangle(idx_prev[LEFT], idx_a[LEFT], idx_prev[BOTTOM]); - } if (ii == lines.size()) { -- cgit v1.2.3 From 4269c8b23cb6878a20f468a916d0079ecaf647a0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 1 Jul 2019 12:28:16 +0200 Subject: Removed GLVolume non-VBO rendering --- src/slic3r/GUI/3DBed.cpp | 25 ++- src/slic3r/GUI/3DBed.hpp | 8 +- src/slic3r/GUI/3DScene.cpp | 313 +++++++++--------------------- src/slic3r/GUI/3DScene.hpp | 55 +++--- src/slic3r/GUI/GLCanvas3D.cpp | 185 +++++++----------- src/slic3r/GUI/GLCanvas3D.hpp | 3 +- src/slic3r/GUI/GLCanvas3DManager.cpp | 5 +- src/slic3r/GUI/GLCanvas3DManager.hpp | 1 - src/slic3r/GUI/GLToolbar.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 4 +- src/slic3r/GUI/Selection.cpp | 6 +- src/slic3r/GUI/Selection.hpp | 2 +- 12 files changed, 220 insertions(+), 389 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index d73e423e0..2b2631ab8 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -274,8 +274,8 @@ void Bed3D::Axes::render_axis(double length) const Bed3D::Bed3D() : m_type(Custom) - , m_requires_canvas_update(false) #if ENABLE_TEXTURES_FROM_SVG + , m_requires_canvas_update(false) , m_vbo_id(0) #endif // ENABLE_TEXTURES_FROM_SVG , m_scale_factor(1.0f) @@ -330,12 +330,11 @@ Point Bed3D::point_projection(const Point& point) const } #if ENABLE_TEXTURES_FROM_SVG -void Bed3D::render(GLCanvas3D* canvas, float theta, bool useVBOs, float scale_factor) const +void Bed3D::render(GLCanvas3D* canvas, float theta, float scale_factor) const { m_scale_factor = scale_factor; - EType type = useVBOs ? m_type : Custom; - switch (type) + switch (m_type) { case MK2: { @@ -361,7 +360,7 @@ void Bed3D::render(GLCanvas3D* canvas, float theta, bool useVBOs, float scale_fa } } #else -void Bed3D::render(GLCanvas3D* canvas, float theta, bool useVBOs, float scale_factor) const +void Bed3D::render(float theta, float scale_factor) const { m_scale_factor = scale_factor; @@ -372,17 +371,17 @@ void Bed3D::render(GLCanvas3D* canvas, float theta, bool useVBOs, float scale_fa { case MK2: { - render_prusa(canvas, "mk2", theta, useVBOs); + render_prusa("mk2", theta); break; } case MK3: { - render_prusa(canvas, "mk3", theta, useVBOs); + render_prusa("mk3", theta); break; } case SL1: { - render_prusa(canvas, "sl1", theta, useVBOs); + render_prusa("sl1", theta); break; } default: @@ -546,7 +545,7 @@ void Bed3D::render_prusa(GLCanvas3D* canvas, const std::string &key, bool bottom if (!bottom) { filename = model_path + "_bed.stl"; - if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, true)) { + if ((m_model.get_filename() != filename) && m_model.init_from_file(filename)) { Vec3d offset = m_bounding_box.center() - Vec3d(0.0, 0.0, 0.5 * m_model.get_bounding_box().size()(2)); if (key == "mk2") // hardcoded value to match the stl model @@ -651,7 +650,7 @@ void Bed3D::render_prusa_shader(bool transparent) const } } #else -void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) const +void Bed3D::render_prusa(const std::string& key, float theta) const { std::string tex_path = resources_dir() + "/icons/bed/" + key; @@ -677,7 +676,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons std::string filename = tex_path + "_top.png"; if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename)) { - if (!m_top_texture.load_from_file(filename, true)) + if (!m_top_texture.load_from_file(filename, true, true)) { render_custom(); return; @@ -694,7 +693,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons filename = tex_path + "_bottom.png"; if ((m_bottom_texture.get_id() == 0) || (m_bottom_texture.get_source() != filename)) { - if (!m_bottom_texture.load_from_file(filename, true)) + if (!m_bottom_texture.load_from_file(filename, true, true)) { render_custom(); return; @@ -711,7 +710,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons if (theta <= 90.0f) { filename = model_path + "_bed.stl"; - if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) { + if ((m_model.get_filename() != filename) && m_model.init_from_file(filename)) { Vec3d offset = m_bounding_box.center() - Vec3d(0.0, 0.0, 0.5 * m_model.get_bounding_box().size()(2)); if (key == "mk2") // hardcoded value to match the stl model diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 68a74f61c..f5491221a 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -128,7 +128,11 @@ public: bool contains(const Point& point) const; Point point_projection(const Point& point) const; - void render(GLCanvas3D* canvas, float theta, bool useVBOs, float scale_factor) const; +#if ENABLE_TEXTURES_FROM_SVG + void render(GLCanvas3D* canvas, float theta, float scale_factor) const; +#else + void render(float theta, float scale_factor) const; +#endif // ENABLE_TEXTURES_FROM_SVG void render_axes() const; private: @@ -140,7 +144,7 @@ private: void render_prusa(GLCanvas3D* canvas, const std::string& key, bool bottom) const; void render_prusa_shader(bool transparent) const; #else - void render_prusa(const std::string &key, float theta, bool useVBOs) const; + void render_prusa(const std::string& key, float theta) const; #endif // ENABLE_TEXTURES_FROM_SVG void render_custom() const; #if ENABLE_TEXTURES_FROM_SVG diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 5853ab712..417aaee4f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -55,21 +55,6 @@ void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char namespace Slic3r { -void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh) -{ - assert(triangle_indices.empty() && vertices_and_normals_interleaved_size == 0); - assert(quad_indices.empty() && triangle_indices_size == 0); - assert(vertices_and_normals_interleaved.size() % 6 == 0 && quad_indices_size == vertices_and_normals_interleaved.size()); - - this->vertices_and_normals_interleaved.reserve(this->vertices_and_normals_interleaved.size() + 3 * 3 * 2 * mesh.facets_count()); - - for (int i = 0; i < (int)mesh.stl.stats.number_of_facets; ++i) { - const stl_facet &facet = mesh.stl.facet_start[i]; - for (int j = 0; j < 3; ++ j) - this->push_geometry(facet.vertex[j](0), facet.vertex[j](1), facet.vertex[j](2), facet.normal(0), facet.normal(1), facet.normal(2)); - } -} - void GLIndexedVertexArray::load_mesh_full_shading(const TriangleMesh &mesh) { assert(triangle_indices.empty() && vertices_and_normals_interleaved_size == 0); @@ -89,7 +74,7 @@ void GLIndexedVertexArray::load_mesh_full_shading(const TriangleMesh &mesh) } } -void GLIndexedVertexArray::finalize_geometry(bool use_VBOs) +void GLIndexedVertexArray::finalize_geometry() { assert(this->vertices_and_normals_interleaved_VBO_id == 0); assert(this->triangle_indices_VBO_id == 0); @@ -97,28 +82,28 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs) this->setup_sizes(); - if (use_VBOs) { - if (! empty()) { - glsafe(::glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - this->vertices_and_normals_interleaved.clear(); - } - if (! this->triangle_indices.empty()) { - glsafe(::glGenBuffers(1, &this->triangle_indices_VBO_id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW)); - this->triangle_indices.clear(); - } - if (! this->quad_indices.empty()) { - glsafe(::glGenBuffers(1, &this->quad_indices_VBO_id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW)); - this->quad_indices.clear(); - } + if (! empty()) { + glsafe(::glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + this->vertices_and_normals_interleaved.clear(); + } + if (! this->triangle_indices.empty()) { + glsafe(::glGenBuffers(1, &this->triangle_indices_VBO_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + this->triangle_indices.clear(); } + if (! this->quad_indices.empty()) { + glsafe(::glGenBuffers(1, &this->quad_indices_VBO_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + this->quad_indices.clear(); + } + this->shrink_to_fit(); } @@ -423,7 +408,7 @@ void GLVolume::render() const glFrontFace(GL_CCW); } -void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const +void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const { if (!is_active) return; @@ -431,9 +416,6 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c if (!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id) return; - if (this->is_left_handed()) - glFrontFace(GL_CW); - GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first)); GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first)); if (n_triangles + n_quads == 0) @@ -464,6 +446,9 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c return; } + if (this->is_left_handed()) + glFrontFace(GL_CW); + if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)render_color)); else @@ -500,162 +485,114 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c glFrontFace(GL_CCW); } -void GLVolume::render_legacy() const -{ - assert(!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id); - if (!is_active) - return; - - if (this->is_left_handed()) - glFrontFace(GL_CW); - - GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first)); - GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first)); - if (n_triangles + n_quads == 0) - { - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glColor4fv(render_color)); - render(); - - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - - return; - } - - glsafe(::glColor4fv(render_color)); - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3)); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data())); - - glsafe(::glPushMatrix()); - - glsafe(::glMultMatrixd(world_matrix().data())); - - if (n_triangles > 0) - glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first)); - - if (n_quads > 0) - glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first)); - - glsafe(::glPopMatrix()); - - if (this->is_left_handed()) - glFrontFace(GL_CCW); -} - bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); } bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposBasePool); } std::vector GLVolumeCollection::load_object( - const ModelObject *model_object, + const ModelObject* model_object, int obj_idx, - const std::vector &instance_idxs, - const std::string &color_by, - bool use_VBOs) + const std::vector& instance_idxs, + const std::string& color_by) { std::vector volumes_idx; - for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++ volume_idx) + for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++volume_idx) for (int instance_idx : instance_idxs) - volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, color_by, use_VBOs)); - return volumes_idx; + volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, color_by)); + return volumes_idx; } int GLVolumeCollection::load_object_volume( - const ModelObject *model_object, + const ModelObject* model_object, int obj_idx, int volume_idx, int instance_idx, - const std::string &color_by, - bool use_VBOs) + const std::string& color_by) { - const ModelVolume *model_volume = model_object->volumes[volume_idx]; - const int extruder_id = model_volume->extruder_id(); - const ModelInstance *instance = model_object->instances[instance_idx]; + const ModelVolume* model_volume = model_object->volumes[volume_idx]; + const int extruder_id = model_volume->extruder_id(); + const ModelInstance* instance = model_object->instances[instance_idx]; const TriangleMesh& mesh = model_volume->mesh(); float color[4]; memcpy(color, GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3); -/* if (model_volume->is_support_blocker()) { - color[0] = 1.0f; - color[1] = 0.2f; - color[2] = 0.2f; - } else if (model_volume->is_support_enforcer()) { - color[0] = 0.2f; - color[1] = 0.2f; - color[2] = 1.0f; - } - color[3] = model_volume->is_model_part() ? 1.f : 0.5f; */ + /* if (model_volume->is_support_blocker()) { + color[0] = 1.0f; + color[1] = 0.2f; + color[2] = 0.2f; + } else if (model_volume->is_support_enforcer()) { + color[0] = 0.2f; + color[1] = 0.2f; + color[2] = 1.0f; + } + color[3] = model_volume->is_model_part() ? 1.f : 0.5f; */ color[3] = model_volume->is_model_part() ? 1.f : 0.5f; this->volumes.emplace_back(new GLVolume(color)); - GLVolume &v = *this->volumes.back(); + GLVolume& v = *this->volumes.back(); v.set_color_from_model_volume(model_volume); - v.indexed_vertex_array.load_mesh(mesh, use_VBOs); + v.indexed_vertex_array.load_mesh(mesh); // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). v.bounding_box = v.indexed_vertex_array.bounding_box(); - v.indexed_vertex_array.finalize_geometry(use_VBOs); - v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx); + v.indexed_vertex_array.finalize_geometry(); + v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx); if (model_volume->is_model_part()) { - // GLVolume will reference a convex hull from model_volume! + // GLVolume will reference a convex hull from model_volume! v.set_convex_hull(model_volume->get_convex_hull_shared_ptr()); if (extruder_id != -1) v.extruder_id = extruder_id; } - v.is_modifier = ! model_volume->is_model_part(); + v.is_modifier = !model_volume->is_model_part(); v.shader_outside_printer_detection_enabled = model_volume->is_model_part(); v.set_instance_transformation(instance->get_transformation()); v.set_volume_transformation(model_volume->get_transformation()); - return int(this->volumes.size() - 1); + return int(this->volumes.size() - 1); } // Load SLA auxiliary GLVolumes (for support trees or pad). // This function produces volumes for multiple instances in a single shot, // as some object specific mesh conversions may be expensive. void GLVolumeCollection::load_object_auxiliary( - const SLAPrintObject *print_object, + const SLAPrintObject* print_object, int obj_idx, // pairs of - const std::vector> &instances, + const std::vector>& instances, SLAPrintObjectStep milestone, // Timestamp of the last change of the milestone - size_t timestamp, - bool use_VBOs) + size_t timestamp) { assert(print_object->is_step_done(milestone)); Transform3d mesh_trafo_inv = print_object->trafo().inverse(); // Get the support mesh. TriangleMesh mesh = print_object->get_mesh(milestone); mesh.transform(mesh_trafo_inv); - // Convex hull is required for out of print bed detection. - TriangleMesh convex_hull = mesh.convex_hull_3d(); - for (const std::pair &instance_idx : instances) { - const ModelInstance &model_instance = *print_object->model_object()->instances[instance_idx.first]; + // Convex hull is required for out of print bed detection. + TriangleMesh convex_hull = mesh.convex_hull_3d(); + for (const std::pair& instance_idx : instances) { + const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; this->volumes.emplace_back(new GLVolume((milestone == slaposBasePool) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR)); - GLVolume &v = *this->volumes.back(); - v.indexed_vertex_array.load_mesh(mesh, use_VBOs); + GLVolume& v = *this->volumes.back(); + v.indexed_vertex_array.load_mesh(mesh); // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). v.bounding_box = v.indexed_vertex_array.bounding_box(); - v.indexed_vertex_array.finalize_geometry(use_VBOs); - v.composite_id = GLVolume::CompositeID(obj_idx, - int(milestone), (int)instance_idx.first); + v.indexed_vertex_array.finalize_geometry(); + v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first); v.geometry_id = std::pair(timestamp, model_instance.id().id); - // Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance. + // Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance. if (&instance_idx == &instances.back()) v.set_convex_hull(std::move(convex_hull)); else v.set_convex_hull(convex_hull); - v.is_modifier = false; + v.is_modifier = false; v.shader_outside_printer_detection_enabled = (milestone == slaposSupportTree); v.set_instance_transformation(model_instance.get_transformation()); - // Leave the volume transformation at identity. + // Leave the volume transformation at identity. // v.set_volume_transformation(model_volume->get_transformation()); } } int GLVolumeCollection::load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width) + int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width) { if (depth < 0.01f) return int(this->volumes.size() - 1); @@ -680,45 +617,45 @@ int GLVolumeCollection::load_wipe_tower_preview( { 38.453f, 0, 1 }, { 0, 0, 1 }, { 0, -depth, 1 }, { 100.0f, -depth, 1 }, { 100.0f, 0, 1 }, { 61.547f, 0, 1 }, { 55.7735f, -10.0f, 1 }, { 44.2265f, 10.0f, 1 } }; int out_facets_idx[][3] = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 5, 0 }, { 3, 5, 6 }, { 6, 2, 7 }, { 6, 0, 2 }, { 8, 9, 10 }, { 11, 12, 13 }, { 10, 11, 14 }, { 14, 11, 13 }, { 15, 8, 14 }, {8, 10, 14}, {3, 12, 4}, {3, 13, 12}, {6, 13, 3}, {6, 14, 13}, {7, 14, 6}, {7, 15, 14}, {2, 15, 7}, {2, 8, 15}, {1, 8, 2}, {1, 9, 8}, - {0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11}}; - for (int i=0;i<16;++i) - points.push_back(Vec3d(out_points_idx[i][0] / (100.f/min_width), out_points_idx[i][1] + depth, out_points_idx[i][2])); - for (int i=0;i<28;++i) + {0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11} }; + for (int i = 0; i < 16; ++i) + points.push_back(Vec3d(out_points_idx[i][0] / (100.f / min_width), out_points_idx[i][1] + depth, out_points_idx[i][2])); + for (int i = 0; i < 28; ++i) facets.push_back(Vec3crd(out_facets_idx[i][0], out_facets_idx[i][1], out_facets_idx[i][2])); TriangleMesh tooth_mesh(points, facets); // We have the mesh ready. It has one tooth and width of min_width. We will now append several of these together until we are close to // the required width of the block. Than we can scale it precisely. - size_t n = std::max(1, int(width/min_width)); // How many shall be merged? - for (size_t i=0;ivolumes.emplace_back(new GLVolume(color)); - GLVolume &v = *this->volumes.back(); - v.indexed_vertex_array.load_mesh(mesh, use_VBOs); + GLVolume& v = *this->volumes.back(); + v.indexed_vertex_array.load_mesh(mesh); v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0)); - v.set_volume_rotation(Vec3d(0., 0., (M_PI/180.) * rotation_angle)); + v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle)); // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). v.bounding_box = v.indexed_vertex_array.bounding_box(); - v.indexed_vertex_array.finalize_geometry(use_VBOs); - v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0); + v.indexed_vertex_array.finalize_geometry(); + v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0); v.geometry_id.first = 0; v.geometry_id.second = wipe_tower_instance_id().id; v.is_wipe_tower = true; - v.shader_outside_printer_detection_enabled = ! size_unknown; + v.shader_outside_printer_detection_enabled = !size_unknown; return int(this->volumes.size() - 1); } @@ -759,7 +696,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo return list; } -void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const +void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -797,7 +734,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithIdAndZ& volume : to_render) { volume.first->set_render_color(); - volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id); + volume.first->render(color_id, print_box_detection_id, print_box_worldmatrix_id); } glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); @@ -812,34 +749,6 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool glsafe(::glDisable(GL_BLEND)); } -void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const -{ - glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - - glsafe(::glCullFace(GL_BACK)); - if (disable_cullface) - glsafe(::glDisable(GL_CULL_FACE)); - - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - - GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); - for (GLVolumeWithIdAndZ& volume : to_render) - { - volume.first->set_render_color(); - volume.first->render_legacy(); - } - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - if (disable_cullface) - glsafe(::glEnable(GL_CULL_FACE)); - - glsafe(::glDisable(GL_BLEND)); -} - bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state) { if (config == nullptr) @@ -1623,8 +1532,7 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; GLModel::GLModel() - : m_useVBOs(false) - , m_filename("") + : m_filename("") { m_volume.shader_outside_printer_detection_enabled = false; } @@ -1677,14 +1585,6 @@ void GLModel::reset() } void GLModel::render() const -{ - if (m_useVBOs) - render_VBOs(); - else - render_legacy(); -} - -void GLModel::render_VBOs() const { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -1697,7 +1597,8 @@ void GLModel::render_VBOs() const glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; glcheck(); - m_volume.render_VBOs(color_id, -1, -1); + + m_volume.render(color_id, -1, -1); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); @@ -1708,26 +1609,7 @@ void GLModel::render_VBOs() const glsafe(::glDisable(GL_BLEND)); } -void GLModel::render_legacy() const -{ - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - - glsafe(::glCullFace(GL_BACK)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - - m_volume.render_legacy(); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisable(GL_BLEND)); - glsafe(::glDisable(GL_LIGHTING)); -} - -bool GLArrow::on_init(bool useVBOs) +bool GLArrow::on_init() { Pointf3s vertices; std::vector triangles; @@ -1780,9 +1662,8 @@ bool GLArrow::on_init(bool useVBOs) triangles.emplace_back(6, 0, 7); triangles.emplace_back(7, 13, 6); - m_useVBOs = useVBOs; - m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles), useVBOs); - m_volume.finalize_geometry(m_useVBOs); + m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles)); + m_volume.finalize_geometry(); return true; } @@ -1794,7 +1675,7 @@ GLCurvedArrow::GLCurvedArrow(unsigned int resolution) m_resolution = 1; } -bool GLCurvedArrow::on_init(bool useVBOs) +bool GLCurvedArrow::on_init() { Pointf3s vertices; std::vector triangles; @@ -1895,14 +1776,13 @@ bool GLCurvedArrow::on_init(bool useVBOs) triangles.emplace_back(vertices_per_level, vertices_per_level + 1, 0); triangles.emplace_back(vertices_per_level, 2 * vertices_per_level + 1, vertices_per_level + 1); - m_useVBOs = useVBOs; - m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles), useVBOs); + m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles)); m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); - m_volume.finalize_geometry(m_useVBOs); + m_volume.finalize_geometry(); return true; } -bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) +bool GLBed::on_init_from_file(const std::string& filename) { reset(); @@ -1923,7 +1803,6 @@ bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) } m_filename = filename; - m_useVBOs = useVBOs; ModelObject* model_object = model.objects.front(); model_object->center_around_origin(); @@ -1931,13 +1810,13 @@ bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) TriangleMesh mesh = model.mesh(); mesh.repair(); - m_volume.indexed_vertex_array.load_mesh(mesh, useVBOs); + m_volume.indexed_vertex_array.load_mesh(mesh); float color[4] = { 0.235f, 0.235f, 0.235f, 1.0f }; set_color(color, 4); m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); - m_volume.finalize_geometry(m_useVBOs); + m_volume.finalize_geometry(); return true; } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index d197372ab..bfdce2daf 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -115,9 +115,8 @@ public: unsigned int triangle_indices_VBO_id; unsigned int quad_indices_VBO_id; - void load_mesh_flat_shading(const TriangleMesh &mesh); void load_mesh_full_shading(const TriangleMesh &mesh); - void load_mesh(const TriangleMesh &mesh, bool use_VBOs) { use_VBOs ? this->load_mesh_full_shading(mesh) : this->load_mesh_flat_shading(mesh); } + void load_mesh(const TriangleMesh& mesh) { this->load_mesh_full_shading(mesh); } inline bool has_VBOs() const { return vertices_and_normals_interleaved_VBO_id != 0; } @@ -166,7 +165,7 @@ public: // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects // and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs. - void finalize_geometry(bool use_VBOs); + void finalize_geometry(); // Release the geometry data, release OpenGL VBOs. void release_geometry(); // Render either using an immediate mode, or the VBOs. @@ -415,10 +414,9 @@ public: void set_range(coordf_t low, coordf_t high); void render() const; - void render_VBOs(int color_id, int detection_id, int worldmatrix_id) const; - void render_legacy() const; + void render(int color_id, int detection_id, int worldmatrix_id) const; - void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); } + void finalize_geometry() { this->indexed_vertex_array.finalize_geometry(); } void release_geometry() { this->indexed_vertex_array.release_geometry(); } void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; } @@ -459,42 +457,38 @@ public: ~GLVolumeCollection() { clear(); }; std::vector load_object( - const ModelObject *model_object, + const ModelObject* model_object, int obj_idx, - const std::vector &instance_idxs, - const std::string &color_by, - bool use_VBOs); + const std::vector& instance_idxs, + const std::string& color_by); int load_object_volume( - const ModelObject *model_object, + const ModelObject* model_object, int obj_idx, int volume_idx, int instance_idx, - const std::string &color_by, - bool use_VBOs); + const std::string& color_by); // Load SLA auxiliary GLVolumes (for support trees or pad). void load_object_auxiliary( - const SLAPrintObject *print_object, + const SLAPrintObject* print_object, int obj_idx, // pairs of - const std::vector> &instances, + const std::vector>& instances, SLAPrintObjectStep milestone, // Timestamp of the last change of the milestone - size_t timestamp, - bool use_VBOs); + size_t timestamp); int load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width); + int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); // Render the volumes by OpenGL. - void render_VBOs(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const; - void render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const; + void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const; // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects // and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs. - void finalize_geometry(bool use_VBOs) { for (auto *v : volumes) v->finalize_geometry(use_VBOs); } + void finalize_geometry() { for (auto* v : volumes) v->finalize_geometry(); } // Release the geometry data assigned to the volumes. // If OpenGL VBOs were allocated, an OpenGL context has to be active to release them. void release_geometry() { for (auto *v : volumes) v->release_geometry(); } @@ -533,15 +527,14 @@ class GLModel { protected: GLVolume m_volume; - bool m_useVBOs; std::string m_filename; public: GLModel(); virtual ~GLModel(); - bool init(bool useVBOs) { return on_init(useVBOs); } - bool init_from_file(const std::string& filename, bool useVBOs) { return on_init_from_file(filename, useVBOs); } + bool init() { return on_init(); } + bool init_from_file(const std::string& filename) { return on_init_from_file(filename); } void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box.center()); } void set_color(const float* color, unsigned int size); @@ -562,18 +555,14 @@ public: void render() const; protected: - virtual bool on_init(bool useVBOs) { return false; } - virtual bool on_init_from_file(const std::string& filename, bool useVBOs) { return false; } - -private: - void render_VBOs() const; - void render_legacy() const; + virtual bool on_init() { return false; } + virtual bool on_init_from_file(const std::string& filename) { return false; } }; class GLArrow : public GLModel { protected: - virtual bool on_init(bool useVBOs); + virtual bool on_init(); }; class GLCurvedArrow : public GLModel @@ -584,13 +573,13 @@ public: explicit GLCurvedArrow(unsigned int resolution); protected: - virtual bool on_init(bool useVBOs); + virtual bool on_init(); }; class GLBed : public GLModel { protected: - virtual bool on_init_from_file(const std::string& filename, bool useVBOs); + virtual bool on_init_from_file(const std::string& filename); }; class _3DScene diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9bb6f4553..ab08aa0a7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1211,7 +1211,6 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar , m_model(nullptr) , m_dirty(true) , m_initialized(false) - , m_use_VBOs(false) , m_apply_zoom_to_volumes_filter(false) , m_legend_texture_enabled(false) , m_picking_enabled(false) @@ -1252,7 +1251,7 @@ void GLCanvas3D::post_event(wxEvent &&event) wxPostEvent(m_canvas, event); } -bool GLCanvas3D::init(bool useVBOs) +bool GLCanvas3D::init() { if (m_initialized) return true; @@ -1303,30 +1302,30 @@ bool GLCanvas3D::init(bool useVBOs) if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); - if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs")) + if (!m_shader.init("gouraud.vs", "gouraud.fs")) + { + std::cout << "Unable to initialize gouraud shader: please, check that the files gouraud.vs and gouraud.fs are available" << std::endl; return false; + } - if (m_toolbar.is_enabled() && useVBOs && !m_layers_editing.init("variable_layer_height.vs", "variable_layer_height.fs")) + if (m_toolbar.is_enabled() && !m_layers_editing.init("variable_layer_height.vs", "variable_layer_height.fs")) + { + std::cout << "Unable to initialize variable_layer_height shader: please, check that the files variable_layer_height.vs and variable_layer_height.fs are available" << std::endl; return false; - - m_use_VBOs = useVBOs; + } // on linux the gl context is not valid until the canvas is not shown on screen // we defer the geometry finalization of volumes until the first call to render() if (!m_volumes.empty()) - m_volumes.finalize_geometry(m_use_VBOs); + m_volumes.finalize_geometry(); - if (m_gizmos.is_enabled()) { - if (! m_gizmos.init(*this)) { - std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl; - return false; - } - } + if (m_gizmos.is_enabled() && !m_gizmos.init(*this)) + std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl; if (!_init_toolbar()) return false; - if (m_selection.is_enabled() && !m_selection.init(m_use_VBOs)) + if (m_selection.is_enabled() && !m_selection.init()) return false; post_event(SimpleEvent(EVT_GLCANVAS_INIT)); @@ -1778,7 +1777,7 @@ std::vector GLCanvas3D::load_object(const ModelObject& model_object, int ob instance_idxs.push_back(i); } } - return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_color_by, m_use_VBOs && m_initialized); + return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_color_by); } std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) @@ -1966,8 +1965,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id); if (it->new_geometry()) { // New volume. - m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by, m_use_VBOs && m_initialized); - m_volumes.volumes.back()->geometry_id = key.geometry_id; + m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by); + m_volumes.volumes.back()->geometry_id = key.geometry_id; update_object_list = true; } else { // Recycling an old GLVolume. @@ -2031,7 +2030,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re for (size_t istep = 0; istep < sla_steps.size(); ++istep) if (!instances[istep].empty()) - m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_use_VBOs && m_initialized); + m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp); } // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed @@ -2068,9 +2067,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re float brim_spacing = print->config().nozzle_diameter.values[0] * 1.25f - first_layer_height * (1. - M_PI_4); if (!print->is_step_done(psWipeTower)) - depth = (900.f/w) * (float)(extruders_count - 1) ; + depth = (900.f/w) * (float)(extruders_count - 1); int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( - 1000, x, y, w, depth, (float)height, a, m_use_VBOs && m_initialized, !print->is_step_done(psWipeTower), + 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), brim_spacing * 4.5f); if (volume_idx_wipe_tower_old != -1) map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new; @@ -3821,7 +3820,11 @@ void GLCanvas3D::_render_bed(float theta) const #if ENABLE_RETINA_GL scale_factor = m_retina_helper->get_scale_factor(); #endif // ENABLE_RETINA_GL - m_bed.render(const_cast(this), theta, m_use_VBOs, scale_factor); +#if ENABLE_TEXTURES_FROM_SVG + m_bed.render(const_cast(this), theta, scale_factor); +#else + m_bed.render(theta, scale_factor); +#endif // ENABLE_TEXTURES_FROM_SVG } void GLCanvas3D::_render_axes() const @@ -3829,8 +3832,6 @@ void GLCanvas3D::_render_axes() const m_bed.render_axes(); } - - void GLCanvas3D::_render_objects() const { if (m_volumes.empty()) @@ -3841,75 +3842,44 @@ void GLCanvas3D::_render_objects() const m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane(); - if (m_use_VBOs) + if (m_picking_enabled) { - if (m_picking_enabled) - { - // Update the layer editing selection to the first object selected, update the current object maximum Z. - const_cast(m_layers_editing).select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1); - - if (m_config != nullptr) - { - const BoundingBoxf3& bed_bb = m_bed.get_bounding_box(false); - m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height")); - m_volumes.check_outside_state(m_config, nullptr); - } - } + // Update the layer editing selection to the first object selected, update the current object maximum Z. + const_cast(m_layers_editing).select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1); - if (m_use_clipping_planes) - m_volumes.set_z_range(-m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]); - else - m_volumes.set_z_range(-FLT_MAX, FLT_MAX); - - m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); - - m_shader.start_using(); - if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { - int object_id = m_layers_editing.last_object_id; - m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume &volume) { - // Which volume to paint without the layer height profile shader? - return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); - }); - // Let LayersEditing handle rendering of the active object using the layer height profile shader. - m_layers_editing.render_volumes(*this, this->m_volumes); - } else { - // do not cull backfaces to show broken geometry, if any - m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { - return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); - }); + if (m_config != nullptr) + { + const BoundingBoxf3& bed_bb = m_bed.get_bounding_box(false); + m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height")); + m_volumes.check_outside_state(m_config, nullptr); } - m_volumes.render_VBOs(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); - m_shader.stop_using(); } + + if (m_use_clipping_planes) + m_volumes.set_z_range(-m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]); else - { - ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data()); - ::glEnable(GL_CLIP_PLANE0); + m_volumes.set_z_range(-FLT_MAX, FLT_MAX); - if (m_use_clipping_planes) - { - glsafe(::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data())); - glsafe(::glEnable(GL_CLIP_PLANE1)); - glsafe(::glClipPlane(GL_CLIP_PLANE2, (GLdouble*)m_clipping_planes[1].get_data())); - glsafe(::glEnable(GL_CLIP_PLANE2)); - } - + m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); + m_shader.start_using(); + if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { + int object_id = m_layers_editing.last_object_id; + m_volumes.render(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume& volume) { + // Which volume to paint without the layer height profile shader? + return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); + }); + // Let LayersEditing handle rendering of the active object using the layer height profile shader. + m_layers_editing.render_volumes(*this, this->m_volumes); + } else { // do not cull backfaces to show broken geometry, if any - m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { + m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); }); - m_volumes.render_legacy(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); - - ::glDisable(GL_CLIP_PLANE0); - - if (m_use_clipping_planes) - { - glsafe(::glDisable(GL_CLIP_PLANE1)); - glsafe(::glDisable(GL_CLIP_PLANE2)); - } } - + m_volumes.render(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); + m_shader.stop_using(); + m_camera_clipping_plane = ClippingPlane::ClipsNothing(); glsafe(::glDisable(GL_LIGHTING)); } @@ -4025,6 +3995,7 @@ void GLCanvas3D::_render_current_gizmo() const void GLCanvas3D::_render_gizmos_overlay() const { +#if ENABLE_SVG_ICONS #if ENABLE_RETINA_GL // m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor()); const float scale = m_retina_helper->get_scale_factor()*wxGetApp().toolbar_icon_scale(); @@ -4035,6 +4006,7 @@ void GLCanvas3D::_render_gizmos_overlay() const const float size = int(GLGizmosManager::Default_Icons_Size*wxGetApp().toolbar_icon_scale()); m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment #endif /* __WXMSW__ */ +#endif // ENABLE_SVG_ICONS m_gizmos.render_overlay(*this, m_selection); } @@ -4288,13 +4260,9 @@ void GLCanvas3D::_render_sla_slices() const void GLCanvas3D::_render_selection_sidebar_hints() const { - if (m_use_VBOs) - m_shader.start_using(); - + m_shader.start_using(); m_selection.render_sidebar_hints(m_sidebar_field); - - if (m_use_VBOs) - m_shader.stop_using(); + m_shader.stop_using(); } @@ -4507,7 +4475,7 @@ void GLCanvas3D::_load_print_toolpaths() _3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), volume); } volume.bounding_box = volume.indexed_vertex_array.bounding_box(); - volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + volume.indexed_vertex_array.finalize_geometry(); } void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) @@ -4694,7 +4662,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c [](const GLVolume *volume) { return volume->empty(); }), m_volumes.volumes.end()); for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) - m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(); BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end"; } @@ -4865,7 +4833,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ [](const GLVolume *volume) { return volume->empty(); }), m_volumes.volumes.end()); for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) - m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(); BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end"; } @@ -5050,7 +5018,7 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat { GLVolume* volume = m_volumes.volumes[i]; volume->bounding_box = volume->indexed_vertex_array.bounding_box(); - volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + volume->indexed_vertex_array.finalize_geometry(); } } } @@ -5105,7 +5073,7 @@ void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data, { GLVolume* volume = m_volumes.volumes[i]; volume->bounding_box = volume->indexed_vertex_array.bounding_box(); - volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + volume->indexed_vertex_array.finalize_geometry(); } } } @@ -5339,7 +5307,7 @@ void GLCanvas3D::_load_gcode_retractions(const GCodePreviewData& preview_data) // finalize volumes and sends geometry to gpu volume->bounding_box = volume->indexed_vertex_array.bounding_box(); - volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + volume->indexed_vertex_array.finalize_geometry(); } } @@ -5370,7 +5338,7 @@ void GLCanvas3D::_load_gcode_unretractions(const GCodePreviewData& preview_data) // finalize volumes and sends geometry to gpu volume->bounding_box = volume->indexed_vertex_array.bounding_box(); - volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); + volume->indexed_vertex_array.finalize_geometry(); } } @@ -5396,7 +5364,7 @@ void GLCanvas3D::_load_fff_shells() instance_ids[i] = i; } - m_volumes.load_object(model_obj, object_id, instance_ids, "object", m_use_VBOs && m_initialized); + m_volumes.load_object(model_obj, object_id, instance_ids, "object"); ++object_id; } @@ -5416,9 +5384,9 @@ void GLCanvas3D::_load_fff_shells() float brim_spacing = print->config().nozzle_diameter.values[0] * 1.25f - first_layer_height * (1. - M_PI_4); if (!print->is_step_done(psWipeTower)) - depth = (900.f/config.wipe_tower_width) * (float)(extruders_count - 1) ; + depth = (900.f/config.wipe_tower_width) * (float)(extruders_count - 1); m_volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, - m_use_VBOs && m_initialized, !print->is_step_done(psWipeTower), brim_spacing * 4.5f); + !print->is_step_done(psWipeTower), brim_spacing * 4.5f); } } } @@ -5436,8 +5404,8 @@ void GLCanvas3D::_load_sla_shells() const TriangleMesh &mesh, const float color[4], bool outside_printer_detection_enabled) { m_volumes.volumes.emplace_back(new GLVolume(color)); GLVolume& v = *m_volumes.volumes.back(); - v.indexed_vertex_array.load_mesh(mesh, m_use_VBOs); - v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled; + v.indexed_vertex_array.load_mesh(mesh); + v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled; v.composite_id.volume_id = volume_id; v.set_instance_offset(unscale(instance.shift(0), instance.shift(1), 0)); v.set_instance_rotation(Vec3d(0.0, 0.0, (double)instance.rotation)); @@ -5464,7 +5432,7 @@ void GLCanvas3D::_load_sla_shells() GLVolume& v = *m_volumes.volumes[i]; // finalize volumes and sends geometry to gpu v.bounding_box = v.indexed_vertex_array.bounding_box(); - v.indexed_vertex_array.finalize_geometry(m_use_VBOs); + v.indexed_vertex_array.finalize_geometry(); // apply shift z v.set_sla_shift_z(shift_z); } @@ -5640,7 +5608,7 @@ bool GLCanvas3D::_is_any_volume_outside() const void GLCanvas3D::_resize_toolbars() const { Size cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); + float zoom = (float)m_camera.get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_RETINA_GL @@ -5690,19 +5658,16 @@ void GLCanvas3D::_resize_toolbars() const } } - if (m_view_toolbar != nullptr) - { #if ENABLE_RETINA_GL - m_view_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); + m_view_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); #else - m_view_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); + m_view_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); #endif /* __WXMSW__ */ - // places the toolbar on the bottom-left corner of the 3d scene - float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom; - float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; - m_view_toolbar.set_position(top, left); - } + // places the toolbar on the bottom-left corner of the 3d scene + float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom; + float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; + m_view_toolbar.set_position(top, left); } #endif // !ENABLE_SVG_ICONS diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index c891ed06f..722eafeef 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -452,7 +452,6 @@ private: // Screen is only refreshed from the OnIdle handler if it is dirty. bool m_dirty; bool m_initialized; - bool m_use_VBOs; bool m_apply_zoom_to_volumes_filter; mutable std::vector m_hover_volume_idxs; bool m_warning_texture_enabled; @@ -494,7 +493,7 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } - bool init(bool useVBOs); + bool init(); void post_event(wxEvent &&event); void set_as_dirty(); diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index a1430ef22..b2a3161e8 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -192,7 +192,6 @@ GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info; GLCanvas3DManager::GLCanvas3DManager() : m_context(nullptr) , m_gl_initialized(false) - , m_use_VBOs(false) { } @@ -266,8 +265,6 @@ void GLCanvas3DManager::init_gl() if (!m_gl_initialized) { glewInit(); - const AppConfig* config = GUI::get_app_config(); - m_use_VBOs = s_gl_info.is_version_greater_or_equal_to(2, 0); m_gl_initialized = true; if (GLEW_EXT_texture_compression_s3tc) s_compressed_textures_supported = true; @@ -323,7 +320,7 @@ bool GLCanvas3DManager::init(GLCanvas3D& canvas) if (!m_gl_initialized) init_gl(); - return canvas.init(m_use_VBOs); + return canvas.init(); } void GLCanvas3DManager::detect_multisample(int* attribList) diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index 7a600dcbd..c0e0df622 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -75,7 +75,6 @@ private: wxGLContext* m_context; static GLInfo s_gl_info; bool m_gl_initialized; - bool m_use_VBOs; static EMultisampleState s_multisample; static bool s_compressed_textures_supported; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index f8082ad7e..a927eba9b 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -188,7 +188,7 @@ bool GLToolbar::init(const ItemsIconsTexture::Metadata& icons_texture, const Bac return true; std::string path = resources_dir() + "/icons/"; - bool res = !icons_texture.filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture.filename, false); + bool res = !icons_texture.filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture.filename, false, true); if (res) m_icons_texture.metadata = icons_texture; #endif // ENABLE_SVG_ICONS diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c7435636d..c9005807d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -49,7 +49,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) if (!m_icons_texture.metadata.filename.empty()) { - if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false)) + if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false, true)) { reset(); return false; @@ -1072,7 +1072,7 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio #if ENABLE_SVG_ICONS it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); #else - it->second->render_input_window(2.0f * m_overlay_border + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); + it->second->render_input_window(2.0f * m_overlay_border + scaled_icons_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); #endif // ENABLE_SVG_ICONS } #if ENABLE_SVG_ICONS diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 97168ee04..ccc4176fd 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -99,14 +99,14 @@ void Selection::set_volumes(GLVolumePtrs* volumes) update_valid(); } -bool Selection::init(bool useVBOs) +bool Selection::init() { - if (!m_arrow.init(useVBOs)) + if (!m_arrow.init()) return false; m_arrow.set_scale(5.0 * Vec3d::Ones()); - if (!m_curved_arrow.init(useVBOs)) + if (!m_curved_arrow.init()) return false; m_curved_arrow.set_scale(5.0 * Vec3d::Ones()); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 802f8d284..482a8309f 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -212,7 +212,7 @@ public: #endif // ENABLE_RENDER_SELECTION_CENTER void set_volumes(GLVolumePtrs* volumes); - bool init(bool useVBOs); + bool init(); bool is_enabled() const { return m_enabled; } void set_enabled(bool enable) { m_enabled = enable; } -- cgit v1.2.3 From 2356fe5a1329170dbb97e727388517458f65e400 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 1 Jul 2019 13:26:06 +0200 Subject: Added member BoundingBoxf3 m_bounding_box to GLIndexedVertexArray and removed member BoundingBoxf3 bounding_box from GLVolume --- src/slic3r/GUI/3DScene.cpp | 18 +++++--------- src/slic3r/GUI/3DScene.hpp | 40 ++++++++++++------------------- src/slic3r/GUI/GLCanvas3D.cpp | 20 ++++------------ src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 ++--- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 4 ++-- 5 files changed, 30 insertions(+), 58 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 417aaee4f..c483f0ec3 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -328,11 +328,12 @@ bool GLVolume::is_left_handed() const const BoundingBoxf3& GLVolume::transformed_bounding_box() const { - assert(bounding_box.defined || bounding_box.min(0) >= bounding_box.max(0) || bounding_box.min(1) >= bounding_box.max(1) || bounding_box.min(2) >= bounding_box.max(2)); + const BoundingBoxf3& box = bounding_box(); + assert(box.defined || box.min(0) >= box.max(0) || box.min(1) >= box.max(1) || box.min(2) >= box.max(2)); if (m_transformed_bounding_box_dirty) { - m_transformed_bounding_box = bounding_box.transformed(world_matrix()); + m_transformed_bounding_box = box.transformed(world_matrix()); m_transformed_bounding_box_dirty = false; } @@ -350,9 +351,10 @@ BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d & { return (m_convex_hull && m_convex_hull->stl.stats.number_of_facets > 0) ? m_convex_hull->transformed_bounding_box(trafo) : - bounding_box.transformed(trafo); + bounding_box().transformed(trafo); } + void GLVolume::set_range(double min_z, double max_z) { this->qverts_range.first = 0; @@ -530,8 +532,6 @@ int GLVolumeCollection::load_object_volume( v.set_color_from_model_volume(model_volume); v.indexed_vertex_array.load_mesh(mesh); - // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). - v.bounding_box = v.indexed_vertex_array.bounding_box(); v.indexed_vertex_array.finalize_geometry(); v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx); if (model_volume->is_model_part()) @@ -573,8 +573,6 @@ void GLVolumeCollection::load_object_auxiliary( this->volumes.emplace_back(new GLVolume((milestone == slaposBasePool) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR)); GLVolume& v = *this->volumes.back(); v.indexed_vertex_array.load_mesh(mesh); - // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). - v.bounding_box = v.indexed_vertex_array.bounding_box(); v.indexed_vertex_array.finalize_geometry(); v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first); v.geometry_id = std::pair(timestamp, model_instance.id().id); @@ -648,8 +646,6 @@ int GLVolumeCollection::load_wipe_tower_preview( v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0)); v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle)); - // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). - v.bounding_box = v.indexed_vertex_array.bounding_box(); v.indexed_vertex_array.finalize_geometry(); v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0); v.geometry_id.first = 0; @@ -679,7 +675,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo { for (GLVolumeWithIdAndZ& volume : list) { - volume.second.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2); + volume.second.second = volume.first->bounding_box().transformed(view_matrix * volume.first->world_matrix()).max(2); } std::sort(list.begin(), list.end(), @@ -1777,7 +1773,6 @@ bool GLCurvedArrow::on_init() triangles.emplace_back(vertices_per_level, 2 * vertices_per_level + 1, vertices_per_level + 1); m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles)); - m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); m_volume.finalize_geometry(); return true; } @@ -1815,7 +1810,6 @@ bool GLBed::on_init_from_file(const std::string& filename) float color[4] = { 0.235f, 0.235f, 0.235f, 1.0f }; set_color(color, 4); - m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); m_volume.finalize_geometry(); return true; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index bfdce2daf..f3db00462 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -82,6 +82,7 @@ public: this->vertices_and_normals_interleaved = rhs.vertices_and_normals_interleaved; this->triangle_indices = rhs.triangle_indices; this->quad_indices = rhs.quad_indices; + this->m_bounding_box = rhs.m_bounding_box; this->setup_sizes(); return *this; } @@ -94,6 +95,7 @@ public: this->vertices_and_normals_interleaved = std::move(rhs.vertices_and_normals_interleaved); this->triangle_indices = std::move(rhs.triangle_indices); this->quad_indices = std::move(rhs.quad_indices); + this->m_bounding_box = std::move(rhs.m_bounding_box); this->setup_sizes(); return *this; } @@ -110,7 +112,7 @@ public: size_t quad_indices_size; // IDs of the Vertex Array Objects, into which the geometry has been loaded. - // Zero if the VBOs are not used. + // Zero if the VBOs are not sent to GPU yet. unsigned int vertices_and_normals_interleaved_VBO_id; unsigned int triangle_indices_VBO_id; unsigned int quad_indices_VBO_id; @@ -135,6 +137,8 @@ public: this->vertices_and_normals_interleaved.push_back(x); this->vertices_and_normals_interleaved.push_back(y); this->vertices_and_normals_interleaved.push_back(z); + + m_bounding_box.merge(Vec3f(x, y, z).cast()); }; inline void push_geometry(double x, double y, double z, double nx, double ny, double nz) { @@ -168,7 +172,7 @@ public: void finalize_geometry(); // Release the geometry data, release OpenGL VBOs. void release_geometry(); - // Render either using an immediate mode, or the VBOs. + void render() const; void render(const std::pair &tverts_range, const std::pair &qverts_range) const; @@ -182,6 +186,7 @@ public: this->vertices_and_normals_interleaved.clear(); this->triangle_indices.clear(); this->quad_indices.clear(); + this->m_bounding_box.reset(); this->setup_sizes(); } @@ -194,27 +199,11 @@ public: this->quad_indices.shrink_to_fit(); } - BoundingBoxf3 bounding_box() const { - BoundingBoxf3 bbox; - if (! this->vertices_and_normals_interleaved.empty()) { - bbox.defined = true; - bbox.min(0) = bbox.max(0) = this->vertices_and_normals_interleaved[3]; - bbox.min(1) = bbox.max(1) = this->vertices_and_normals_interleaved[4]; - bbox.min(2) = bbox.max(2) = this->vertices_and_normals_interleaved[5]; - for (size_t i = 9; i < this->vertices_and_normals_interleaved.size(); i += 6) { - const float *verts = this->vertices_and_normals_interleaved.data() + i; - bbox.min(0) = std::min(bbox.min(0), verts[0]); - bbox.min(1) = std::min(bbox.min(1), verts[1]); - bbox.min(2) = std::min(bbox.min(2), verts[2]); - bbox.max(0) = std::max(bbox.max(0), verts[0]); - bbox.max(1) = std::max(bbox.max(1), verts[1]); - bbox.max(2) = std::max(bbox.max(2), verts[2]); - } - } - return bbox; - } + const BoundingBoxf3& bounding_box() const { return m_bounding_box; } private: + BoundingBoxf3 m_bounding_box; + inline void setup_sizes() { vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size(); triangle_indices_size = this->triangle_indices.size(); @@ -262,8 +251,6 @@ private: mutable bool m_transformed_convex_hull_bounding_box_dirty; public: - // Bounding box of this volume, in unscaled coordinates. - BoundingBoxf3 bounding_box; // Color of the triangles / quads held by this volume. float color[4]; // Color used to render this volume. @@ -328,6 +315,9 @@ public: // Offset into qverts & tverts, or offsets into indices stored into an OpenGL name_index_buffer. std::vector offsets; + // Bounding box of this volume, in unscaled coordinates. + const BoundingBoxf3& bounding_box() const { return this->indexed_vertex_array.bounding_box(); } + void set_render_color(float r, float g, float b, float a); void set_render_color(const float* rgba, unsigned int size); // Sets render color in dependence of current state @@ -536,7 +526,7 @@ public: bool init() { return on_init(); } bool init_from_file(const std::string& filename) { return on_init_from_file(filename); } - void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box.center()); } + void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box().center()); } void set_color(const float* color, unsigned int size); const Vec3d& get_offset() const; @@ -547,7 +537,7 @@ public: void set_scale(const Vec3d& scale); const std::string& get_filename() const { return m_filename; } - const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box; } + const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box(); } const BoundingBoxf3& get_transformed_bounding_box() const { return m_volume.transformed_bounding_box(); } void reset(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ab08aa0a7..5655390ec 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3355,7 +3355,7 @@ arr::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const wti.pos = Vec2d(m_config->opt_float("wipe_tower_x"), m_config->opt_float("wipe_tower_y")); wti.rotation = (M_PI/180.) * m_config->opt_float("wipe_tower_rotation_angle"); - const BoundingBoxf3& bb = vol->bounding_box; + const BoundingBoxf3& bb = vol->bounding_box(); wti.bb_size = Vec2d(bb.size()(0), bb.size()(1)); break; } @@ -4474,7 +4474,6 @@ void GLCanvas3D::_load_print_toolpaths() _3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), volume); } - volume.bounding_box = volume.indexed_vertex_array.bounding_box(); volume.indexed_vertex_array.finalize_geometry(); } @@ -4640,9 +4639,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array); // Copy the content back to the old GLVolume. vol.indexed_vertex_array = vol_new.indexed_vertex_array; - // Finalize a bounding box of the old GLVolume. - vol.bounding_box = vol.indexed_vertex_array.bounding_box(); - // Clear the buffers, but keep them pre-allocated. + // Clear the buffers, but keep them pre-allocated. vol_new.indexed_vertex_array.clear(); // Just make sure that clear did not clear the reserved memory. vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve()); @@ -4650,8 +4647,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } } for (GLVolume *vol : vols) { - vol->bounding_box = vol->indexed_vertex_array.bounding_box(); - vol->indexed_vertex_array.shrink_to_fit(); + vol->indexed_vertex_array.shrink_to_fit(); } }); @@ -4812,8 +4808,6 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array); // Copy the content back to the old GLVolume. vol.indexed_vertex_array = vol_new.indexed_vertex_array; - // Finalize a bounding box of the old GLVolume. - vol.bounding_box = vol.indexed_vertex_array.bounding_box(); // Clear the buffers, but keep them pre-allocated. vol_new.indexed_vertex_array.clear(); // Just make sure that clear did not clear the reserved memory. @@ -4821,7 +4815,6 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ } } for (GLVolume *vol : vols) { - vol->bounding_box = vol->indexed_vertex_array.bounding_box(); vol->indexed_vertex_array.shrink_to_fit(); } }); @@ -5017,7 +5010,6 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i) { GLVolume* volume = m_volumes.volumes[i]; - volume->bounding_box = volume->indexed_vertex_array.bounding_box(); volume->indexed_vertex_array.finalize_geometry(); } } @@ -5072,7 +5064,6 @@ void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data, for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i) { GLVolume* volume = m_volumes.volumes[i]; - volume->bounding_box = volume->indexed_vertex_array.bounding_box(); volume->indexed_vertex_array.finalize_geometry(); } } @@ -5306,7 +5297,6 @@ void GLCanvas3D::_load_gcode_retractions(const GCodePreviewData& preview_data) } // finalize volumes and sends geometry to gpu - volume->bounding_box = volume->indexed_vertex_array.bounding_box(); volume->indexed_vertex_array.finalize_geometry(); } } @@ -5337,7 +5327,6 @@ void GLCanvas3D::_load_gcode_unretractions(const GCodePreviewData& preview_data) } // finalize volumes and sends geometry to gpu - volume->bounding_box = volume->indexed_vertex_array.bounding_box(); volume->indexed_vertex_array.finalize_geometry(); } } @@ -5431,7 +5420,6 @@ void GLCanvas3D::_load_sla_shells() for (unsigned int i = initial_volumes_count; i < m_volumes.volumes.size(); ++ i) { GLVolume& v = *m_volumes.volumes[i]; // finalize volumes and sends geometry to gpu - v.bounding_box = v.indexed_vertex_array.bounding_box(); v.indexed_vertex_array.finalize_geometry(); // apply shift z v.set_sla_shift_z(shift_z); @@ -5523,7 +5511,7 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state() for (GLVolume* volume : m_volumes.volumes) { - volume->is_outside = ((print_volume.radius() > 0.0) && volume->is_extrusion_path) ? !print_volume.contains(volume->bounding_box) : false; + volume->is_outside = ((print_volume.radius() > 0.0) && volume->is_extrusion_path) ? !print_volume.contains(volume->bounding_box()) : false; } } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 372cd79ef..6affe6d3a 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -441,7 +441,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_position = volume->get_volume_offset(); m_new_rotation = volume->get_volume_rotation() * (180. / M_PI); m_new_scale = volume->get_volume_scaling_factor() * 100.; - m_new_size = volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box.size()); + m_new_size = volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box().size()); m_new_enabled = true; } else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) @@ -721,8 +721,8 @@ void ObjectManipulation::change_size_value(int axis, double value) Vec3d ref_size = m_cache.size; if (selection.is_single_volume() || selection.is_single_modifier()) - ref_size = selection.get_volume(*selection.get_volume_idxs().begin())->bounding_box.size(); - else if (selection.is_single_full_instance()) + ref_size = selection.get_volume(*selection.get_volume_idxs().begin())->bounding_box().size(); + else if (selection.is_single_full_instance()) ref_size = m_world_coordinates ? selection.get_unscaled_instance_bounding_box().size() : (*wxGetApp().model_objects())[selection.get_volume(*selection.get_volume_idxs().begin())->object_idx()]->raw_mesh_bounding_box().size(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index e8027c871..ca5383b0d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -136,7 +136,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const for (unsigned int idx : idxs) { const GLVolume* vol = selection.get_volume(idx); - m_box.merge(vol->bounding_box.transformed(vol->get_volume_transformation().get_matrix())); + m_box.merge(vol->bounding_box().transformed(vol->get_volume_transformation().get_matrix())); } // gets transform from first selected volume @@ -151,7 +151,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const else if (single_volume) { const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin()); - m_box = v->bounding_box; + m_box = v->bounding_box(); m_transform = v->world_matrix(); angles = Geometry::extract_euler_angles(m_transform); // consider rotation+mirror only components of the transform for offsets -- cgit v1.2.3 From a934c2e79c64273db45e7bc22835eb147488d81b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 1 Jul 2019 14:56:28 +0200 Subject: Changed a behavior logic of a value reverting for presets, derived from default. LOCKs and ARROWs work now in a same way like for presets, derived from system presets. --- src/slic3r/GUI/Preset.cpp | 20 +++++++++++++++--- src/slic3r/GUI/Tab.cpp | 52 ++++++++++++++++++----------------------------- src/slic3r/GUI/Tab.hpp | 6 ++++++ 3 files changed, 43 insertions(+), 35 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 7192d485c..b8add9fc7 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -824,11 +824,25 @@ const Preset* PresetCollection::get_selected_preset_parent() const if (this->get_selected_idx() == -1) // This preset collection has no preset activated yet. Only the get_edited_preset() is valid. return nullptr; - const std::string &inherits = this->get_edited_preset().inherits(); +// const std::string &inherits = this->get_edited_preset().inherits(); +// if (inherits.empty()) +// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; + + std::string inherits = this->get_edited_preset().inherits(); if (inherits.empty()) - return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; + { + if (this->get_selected_preset().is_system || this->get_selected_preset().is_default) + return &this->get_selected_preset(); + if (this->get_selected_preset().is_external) + return nullptr; + + inherits = m_type != Preset::Type::TYPE_PRINTER ? "- default -" : + this->get_edited_preset().printer_technology() == ptFFF ? + "- default FFF -" : "- default SLA -" ; + } + const Preset* preset = this->find_preset(inherits, false); - return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset; + return (preset == nullptr/* || preset->is_default*/ || preset->is_external) ? nullptr : preset; } const Preset* PresetCollection::get_preset_parent(const Preset& child) const diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6e8b8a471..cd43d95c4 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -423,7 +423,7 @@ void Tab::update_changed_ui() const ScalableBitmap *sys_icon = &m_bmp_value_lock; const ScalableBitmap *icon = &m_bmp_value_revert; - const wxColour *color = &m_sys_label_clr; + const wxColour *color = m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr; const wxString *sys_tt = &m_tt_value_lock; const wxString *tt = &m_tt_value_revert; @@ -590,7 +590,7 @@ void Tab::update_changed_tree_ui() } } - const wxColor *clr = sys_page ? &m_sys_label_clr : + const wxColor *clr = sys_page ? (m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr) : modified_page ? &m_modified_label_clr : &m_default_text_clr; @@ -2584,11 +2584,14 @@ void Tab::load_current_preset() // Reload preset pages with the new configuration values. reload_config(); - m_bmp_non_system = m_presets->get_selected_preset_parent() ? &m_bmp_value_unlock : &m_bmp_white_bullet; - m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; - m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; + const Preset* selected_preset_parent = m_presets->get_selected_preset_parent(); + m_is_default_preset = selected_preset_parent != nullptr && selected_preset_parent->is_default; - m_undo_to_sys_btn->Enable(!preset.is_default); + m_bmp_non_system = selected_preset_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet; + m_ttg_non_system = selected_preset_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; + m_tt_non_system = selected_preset_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; + +// m_undo_to_sys_btn->Enable(!preset.is_default); #if 0 // use CallAfter because some field triggers schedule on_change calls using CallAfter, @@ -3174,18 +3177,18 @@ void Tab::fill_icon_descriptions() { m_icon_descriptions.emplace_back(&m_bmp_value_lock, L("LOCKED LOCK"), // TRN Description for "LOCKED LOCK" - L("indicates that the settings are the same as the system values for the current option group")); + L("indicates that the settings are the same as the system (or default) values for the current option group")); m_icon_descriptions.emplace_back(&m_bmp_value_unlock, L("UNLOCKED LOCK"), // TRN Description for "UNLOCKED LOCK" - L("indicates that some settings were changed and are not equal to the system values for " + L("indicates that some settings were changed and are not equal to the system (or default) values for " "the current option group.\n" "Click the UNLOCKED LOCK icon to reset all settings for current option group to " - "the system values.")); + "the system (or default) values.")); m_icon_descriptions.emplace_back(&m_bmp_white_bullet, L("WHITE BULLET"), // TRN Description for "WHITE BULLET" - L("for the left button: \tindicates a non-system preset,\n" + L("for the left button: \tindicates a non-system (or non-default) preset,\n" "for the right button: \tindicates that the settings hasn't been modified.")); m_icon_descriptions.emplace_back(&m_bmp_value_revert, L("BACK ARROW"), @@ -3198,29 +3201,14 @@ void Tab::fill_icon_descriptions() void Tab::set_tooltips_text() { -// m_undo_to_sys_btn->SetToolTip(_(L( "LOCKED LOCK icon indicates that the settings are the same as the system values " -// "for the current option group.\n" -// "UNLOCKED LOCK icon indicates that some settings were changed and are not equal " -// "to the system values for the current option group.\n" -// "WHITE BULLET icon indicates a non system preset.\n\n" -// "Click the UNLOCKED LOCK icon to reset all settings for current option group to " -// "the system values."))); -// -// m_undo_btn->SetToolTip(_(L( "WHITE BULLET icon indicates that the settings are the same as in the last saved" -// "preset for the current option group.\n" -// "BACK ARROW icon indicates that the settings were changed and are not equal to " -// "the last saved preset for the current option group.\n\n" -// "Click the BACK ARROW icon to reset all settings for the current option group to " -// "the last saved preset."))); - // --- Tooltip text for reset buttons (for whole options group) // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - m_ttg_value_lock = _(L("LOCKED LOCK icon indicates that the settings are the same as the system values " + m_ttg_value_lock = _(L("LOCKED LOCK icon indicates that the settings are the same as the system (or default) values " "for the current option group")); m_ttg_value_unlock = _(L("UNLOCKED LOCK icon indicates that some settings were changed and are not equal " - "to the system values for the current option group.\n" - "Click to reset all settings for current option group to the system values.")); - m_ttg_white_bullet_ns = _(L("WHITE BULLET icon indicates a non system preset.")); + "to the system (or default) values for the current option group.\n" + "Click to reset all settings for current option group to the system (or default) values.")); + m_ttg_white_bullet_ns = _(L("WHITE BULLET icon indicates a non system (or non default) preset.")); m_ttg_non_system = &m_ttg_white_bullet_ns; // Text to be shown on the "Undo user changes" button next to each input field. m_ttg_white_bullet = _(L("WHITE BULLET icon indicates that the settings are the same as in the last saved " @@ -3231,10 +3219,10 @@ void Tab::set_tooltips_text() // --- Tooltip text for reset buttons (for each option in group) // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - m_tt_value_lock = _(L("LOCKED LOCK icon indicates that the value is the same as the system value.")); + m_tt_value_lock = _(L("LOCKED LOCK icon indicates that the value is the same as the system (or default) value.")); m_tt_value_unlock = _(L("UNLOCKED LOCK icon indicates that the value was changed and is not equal " - "to the system value.\n" - "Click to reset current value to the system value.")); + "to the system (or default) value.\n" + "Click to reset current value to the system (or default) value.")); // m_tt_white_bullet_ns= _(L("WHITE BULLET icon indicates a non system preset.")); m_tt_non_system = &m_ttg_white_bullet_ns; // Text to be shown on the "Undo user changes" button next to each input field. diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 6bbe15f7f..73b6bb08d 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -142,6 +142,12 @@ protected: PresetDependencies m_compatible_printers; PresetDependencies m_compatible_prints; + /* Indicates, that default preset or preset inherited from default is selected + * This value is used for a options color updating + * (use green color only for options, which values are equal to system values) + */ + bool m_is_default_preset {false}; + ScalableButton* m_undo_btn; ScalableButton* m_undo_to_sys_btn; ScalableButton* m_question_btn; -- cgit v1.2.3 From e5e7496cea88cd18afa9a83a95e1ed596c5a69c5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 1 Jul 2019 16:56:38 +0200 Subject: Some changes for options tooltips --- src/slic3r/GUI/Field.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 7f42db4d7..e84e9637f 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -113,11 +113,19 @@ wxString Field::get_tooltip_text(const wxString& default_string) wxString tooltip_text(""); wxString tooltip = _(m_opt.tooltip); edit_tooltip(tooltip); + + std::string opt_id = m_opt_id; + auto hash_pos = opt_id.find("#"); + if (hash_pos != std::string::npos) { + opt_id.replace(hash_pos, 1,"["); + opt_id += "]"; + } + if (tooltip.length() > 0) tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " + - (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string + - (boost::iends_with(m_opt_id, "_gcode") ? "" : "\n") + - _(L("parameter name")) + "\t: " + m_opt_id; + (boost::iends_with(opt_id, "_gcode") ? "\n" : "") + default_string + + (boost::iends_with(opt_id, "_gcode") ? "" : "\n") + + _(L("parameter name")) + "\t: " + opt_id; return tooltip_text; } -- cgit v1.2.3 From b835075fd64e82c36ea821cd326b3f3ecd005356 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 2 Jul 2019 10:34:30 +0200 Subject: Visual hints for layers editing enabled whenever a layer is selected into the objects list --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 20 +++++++++++++------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 5 ++++- src/slic3r/GUI/GUI_ObjectList.cpp | 1 + 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index ff0f55aef..f9d3a8956 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -197,17 +197,25 @@ void ObjectLayers::update_layers_list() // Add new control according to the selected item if (type & itLayerRoot) + { + wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); + m_selectable_range = { 0.0, 0.0 }; create_layers_list(); + } else - create_layer(objects_ctrl->GetModel()->GetLayerRangeByItem(item)); - + { + t_layer_height_range range = objects_ctrl->GetModel()->GetLayerRangeByItem(item); + create_layer(range); + update_scene_from_editor_selection(range, etLayerHeight); + } + m_parent->Layout(); } -void ObjectLayers::update_scene_from_editor_selection() const +void ObjectLayers::update_scene_from_editor_selection(const t_layer_height_range& range, EditorType type) const { // needed to show the visual hints in 3D scene - wxGetApp().plater()->canvas3D()->handle_layers_data_focus_event(m_selectable_range, m_selection_type); + wxGetApp().plater()->canvas3D()->handle_layers_data_focus_event(range, type); } void ObjectLayers::UpdateAndShow(const bool show) @@ -257,8 +265,6 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e) { - wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); - if (!m_enter_pressed) { #ifndef __WXGTK__ /* Update data for next editor selection. @@ -291,7 +297,7 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, this->Bind(wxEVT_SET_FOCUS, [this, parent](wxFocusEvent& e) { set_focus_data(); - parent->update_scene_from_editor_selection(); + parent->update_scene_from_editor_selection(parent->get_selectable_range(), parent->get_selection_type()); e.Skip(); }, this->GetId()); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index f19217fbe..253cbf0a4 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -73,11 +73,14 @@ public: void create_layers_list(); void update_layers_list(); - void update_scene_from_editor_selection() const; + void update_scene_from_editor_selection(const t_layer_height_range& range, EditorType type) const; void UpdateAndShow(const bool show) override; void msw_rescale(); + const t_layer_height_range& get_selectable_range() const { return m_selectable_range; } + EditorType get_selection_type() const { return m_selection_type; } + friend class LayerRangeEditor; }; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 03f9cd45f..af1a9908d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2067,6 +2067,7 @@ void ObjectList::part_selection_changed() Sidebar& panel = wxGetApp().sidebar(); panel.Freeze(); + wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); wxGetApp().obj_manipul() ->UpdateAndShow(update_and_show_manipulations); wxGetApp().obj_settings()->UpdateAndShow(update_and_show_settings); wxGetApp().obj_layers() ->UpdateAndShow(update_and_show_layers); -- cgit v1.2.3 From d15698e21e86a4e896bbb5f3c59440ec2dc721e9 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 2 Jul 2019 12:55:55 +0200 Subject: GLVolume and GLIndexedVertexArray refactored to send data to gpu at the first render call --- src/slic3r/GUI/3DScene.cpp | 207 +++++++++++++----------------------------- src/slic3r/GUI/3DScene.hpp | 74 +++++++++------ src/slic3r/GUI/GLCanvas3D.cpp | 61 +++---------- 3 files changed, 119 insertions(+), 223 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c483f0ec3..fe0cd9ffb 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -74,13 +74,13 @@ void GLIndexedVertexArray::load_mesh_full_shading(const TriangleMesh &mesh) } } -void GLIndexedVertexArray::finalize_geometry() +void GLIndexedVertexArray::finalize_geometry() const { assert(this->vertices_and_normals_interleaved_VBO_id == 0); assert(this->triangle_indices_VBO_id == 0); assert(this->quad_indices_VBO_id == 0); - this->setup_sizes(); + this->shrink_to_fit(); if (! empty()) { glsafe(::glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); @@ -103,8 +103,6 @@ void GLIndexedVertexArray::finalize_geometry() glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); this->quad_indices.clear(); } - - this->shrink_to_fit(); } void GLIndexedVertexArray::release_geometry() @@ -122,89 +120,78 @@ void GLIndexedVertexArray::release_geometry() this->quad_indices_VBO_id = 0; } this->clear(); - this->shrink_to_fit(); } void GLIndexedVertexArray::render() const { - if (this->vertices_and_normals_interleaved_VBO_id) { - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); - } else { - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); + if (this->vertices_and_normals_interleaved_VBO_id == 0) + { + // sends data to gpu, if not done yet + finalize_geometry(); + if (this->vertices_and_normals_interleaved_VBO_id == 0) + return; } + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - if (this->indexed()) { - if (this->vertices_and_normals_interleaved_VBO_id) { - // Render using the Vertex Buffer Objects. - if (this->triangle_indices_size > 0) { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); - glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr)); - } - if (this->quad_indices_size > 0) { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); - glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr)); - } - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } else { - // Render in an immediate mode. - if (! this->triangle_indices.empty()) - glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data())); - if (! this->quad_indices.empty()) - glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data())); - } - } else - glsafe(::glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6))); + // Render using the Vertex Buffer Objects. + if (this->triangle_indices_size > 0) { + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + if (this->quad_indices_size > 0) { + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } - if (this->vertices_and_normals_interleaved_VBO_id) - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } void GLIndexedVertexArray::render( - const std::pair &tverts_range, - const std::pair &qverts_range) const + const std::pair& tverts_range, + const std::pair& qverts_range) const { - assert(this->indexed()); - if (! this->indexed()) - return; + if (this->vertices_and_normals_interleaved_VBO_id == 0) + { + // sends data to gpu, if not done yet + finalize_geometry(); + if (this->vertices_and_normals_interleaved_VBO_id == 0) + return; + } - if (this->vertices_and_normals_interleaved_VBO_id) { - // Render using the Vertex Buffer Objects. - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - if (this->triangle_indices_size > 0) { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); - glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); - } - if (this->quad_indices_size > 0) { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); - glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); - } - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + // Render using the Vertex Buffer Objects. + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); + + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + + if (this->triangle_indices_size > 0) { + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + if (this->quad_indices_size > 0) { + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } else { - // Render in an immediate mode. - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - if (! this->triangle_indices.empty()) - glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first))); - if (! this->quad_indices.empty()) - glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first))); } glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; @@ -357,9 +344,9 @@ BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d & void GLVolume::set_range(double min_z, double max_z) { - this->qverts_range.first = 0; + this->qverts_range.first = 0; this->qverts_range.second = this->indexed_vertex_array.quad_indices_size; - this->tverts_range.first = 0; + this->tverts_range.first = 0; this->tverts_range.second = this->indexed_vertex_array.triangle_indices_size; if (! this->print_zs.empty()) { // The Z layer range is specified. @@ -399,12 +386,10 @@ void GLVolume::render() const glFrontFace(GL_CW); glsafe(::glCullFace(GL_BACK)); glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(world_matrix().data())); - if (this->indexed_vertex_array.indexed()) - this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); - else - this->indexed_vertex_array.render(); + + this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); + glsafe(::glPopMatrix()); if (this->is_left_handed()) glFrontFace(GL_CCW); @@ -412,45 +397,6 @@ void GLVolume::render() const void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const { - if (!is_active) - return; - - if (!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id) - return; - - GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first)); - GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first)); - if (n_triangles + n_quads == 0) - { - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - if (color_id >= 0) - { - float color[4]; - ::memcpy((void*)color, (const void*)render_color, 4 * sizeof(float)); - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color)); - } - else - glsafe(::glColor4fv(render_color)); - - if (detection_id != -1) - glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0)); - - if (worldmatrix_id != -1) - glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data())); - - render(); - - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - - return; - } - - if (this->is_left_handed()) - glFrontFace(GL_CW); - if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)render_color)); else @@ -462,29 +408,7 @@ void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const if (worldmatrix_id != -1) glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data())); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); - - glsafe(::glPushMatrix()); - - glsafe(::glMultMatrixd(world_matrix().data())); - - if (n_triangles > 0) - { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id)); - glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); - } - if (n_quads > 0) - { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id)); - glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); - } - - glsafe(::glPopMatrix()); - - if (this->is_left_handed()) - glFrontFace(GL_CCW); + render(); } bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); } @@ -531,8 +455,6 @@ int GLVolumeCollection::load_object_volume( GLVolume& v = *this->volumes.back(); v.set_color_from_model_volume(model_volume); v.indexed_vertex_array.load_mesh(mesh); - - v.indexed_vertex_array.finalize_geometry(); v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx); if (model_volume->is_model_part()) { @@ -573,7 +495,6 @@ void GLVolumeCollection::load_object_auxiliary( this->volumes.emplace_back(new GLVolume((milestone == slaposBasePool) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR)); GLVolume& v = *this->volumes.back(); v.indexed_vertex_array.load_mesh(mesh); - v.indexed_vertex_array.finalize_geometry(); v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first); v.geometry_id = std::pair(timestamp, model_instance.id().id); // Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance. @@ -645,8 +566,6 @@ int GLVolumeCollection::load_wipe_tower_preview( v.indexed_vertex_array.load_mesh(mesh); v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0)); v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle)); - - v.indexed_vertex_array.finalize_geometry(); v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0); v.geometry_id.first = 0; v.geometry_id.second = wipe_tower_instance_id().id; @@ -1576,7 +1495,9 @@ void GLModel::set_scale(const Vec3d& scale) void GLModel::reset() { - m_volume.release_geometry(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// m_volume.release_geometry(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_filename = ""; } @@ -1659,7 +1580,6 @@ bool GLArrow::on_init() triangles.emplace_back(7, 13, 6); m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles)); - m_volume.finalize_geometry(); return true; } @@ -1773,7 +1693,6 @@ bool GLCurvedArrow::on_init() triangles.emplace_back(vertices_per_level, 2 * vertices_per_level + 1, vertices_per_level + 1); m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles)); - m_volume.finalize_geometry(); return true; } @@ -1810,8 +1729,6 @@ bool GLBed::on_init_from_file(const std::string& filename) float color[4] = { 0.235f, 0.235f, 0.235f, 1.0f }; set_color(color, 4); - m_volume.finalize_geometry(); - return true; } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index f3db00462..bb629a1d8 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -56,7 +56,7 @@ public: vertices_and_normals_interleaved_VBO_id(0), triangle_indices_VBO_id(0), quad_indices_VBO_id(0) - { this->setup_sizes(); } + {} GLIndexedVertexArray(const GLIndexedVertexArray &rhs) : vertices_and_normals_interleaved(rhs.vertices_and_normals_interleaved), triangle_indices(rhs.triangle_indices), @@ -64,7 +64,7 @@ public: vertices_and_normals_interleaved_VBO_id(0), triangle_indices_VBO_id(0), quad_indices_VBO_id(0) - { this->setup_sizes(); } + {} GLIndexedVertexArray(GLIndexedVertexArray &&rhs) : vertices_and_normals_interleaved(std::move(rhs.vertices_and_normals_interleaved)), triangle_indices(std::move(rhs.triangle_indices)), @@ -72,7 +72,11 @@ public: vertices_and_normals_interleaved_VBO_id(0), triangle_indices_VBO_id(0), quad_indices_VBO_id(0) - { this->setup_sizes(); } + {} + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + ~GLIndexedVertexArray() { release_geometry(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLIndexedVertexArray& operator=(const GLIndexedVertexArray &rhs) { @@ -83,7 +87,9 @@ public: this->triangle_indices = rhs.triangle_indices; this->quad_indices = rhs.quad_indices; this->m_bounding_box = rhs.m_bounding_box; - this->setup_sizes(); + vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size; + triangle_indices_size = rhs.triangle_indices_size; + quad_indices_size = rhs.quad_indices_size; return *this; } @@ -96,26 +102,28 @@ public: this->triangle_indices = std::move(rhs.triangle_indices); this->quad_indices = std::move(rhs.quad_indices); this->m_bounding_box = std::move(rhs.m_bounding_box); - this->setup_sizes(); + vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size; + triangle_indices_size = rhs.triangle_indices_size; + quad_indices_size = rhs.quad_indices_size; return *this; } // Vertices and their normals, interleaved to be used by void glInterleavedArrays(GL_N3F_V3F, 0, x) - std::vector vertices_and_normals_interleaved; - std::vector triangle_indices; - std::vector quad_indices; + mutable std::vector vertices_and_normals_interleaved; + mutable std::vector triangle_indices; + mutable std::vector quad_indices; // When the geometry data is loaded into the graphics card as Vertex Buffer Objects, // the above mentioned std::vectors are cleared and the following variables keep their original length. - size_t vertices_and_normals_interleaved_size; - size_t triangle_indices_size; - size_t quad_indices_size; + size_t vertices_and_normals_interleaved_size{ 0 }; + size_t triangle_indices_size{ 0 }; + size_t quad_indices_size{ 0 }; // IDs of the Vertex Array Objects, into which the geometry has been loaded. // Zero if the VBOs are not sent to GPU yet. - unsigned int vertices_and_normals_interleaved_VBO_id; - unsigned int triangle_indices_VBO_id; - unsigned int quad_indices_VBO_id; + mutable unsigned int vertices_and_normals_interleaved_VBO_id{ 0 }; + mutable unsigned int triangle_indices_VBO_id{ 0 }; + mutable unsigned int quad_indices_VBO_id{ 0 }; void load_mesh_full_shading(const TriangleMesh &mesh); void load_mesh(const TriangleMesh& mesh) { this->load_mesh_full_shading(mesh); } @@ -129,6 +137,10 @@ public: } inline void push_geometry(float x, float y, float z, float nx, float ny, float nz) { + assert(this->vertices_and_normals_interleaved_VBO_id == 0); + if (this->vertices_and_normals_interleaved_VBO_id != 0) + return; + if (this->vertices_and_normals_interleaved.size() + 6 > this->vertices_and_normals_interleaved.capacity()) this->vertices_and_normals_interleaved.reserve(next_highest_power_of_2(this->vertices_and_normals_interleaved.size() + 6)); this->vertices_and_normals_interleaved.push_back(nx); @@ -138,6 +150,7 @@ public: this->vertices_and_normals_interleaved.push_back(y); this->vertices_and_normals_interleaved.push_back(z); + this->vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size(); m_bounding_box.merge(Vec3f(x, y, z).cast()); }; @@ -150,50 +163,57 @@ public: } inline void push_triangle(int idx1, int idx2, int idx3) { + assert(this->vertices_and_normals_interleaved_VBO_id == 0); + if (this->vertices_and_normals_interleaved_VBO_id != 0) + return; + if (this->triangle_indices.size() + 3 > this->vertices_and_normals_interleaved.capacity()) this->triangle_indices.reserve(next_highest_power_of_2(this->triangle_indices.size() + 3)); this->triangle_indices.push_back(idx1); this->triangle_indices.push_back(idx2); this->triangle_indices.push_back(idx3); + this->triangle_indices_size = this->triangle_indices.size(); }; inline void push_quad(int idx1, int idx2, int idx3, int idx4) { + assert(this->vertices_and_normals_interleaved_VBO_id == 0); + if (this->vertices_and_normals_interleaved_VBO_id != 0) + return; + if (this->quad_indices.size() + 4 > this->vertices_and_normals_interleaved.capacity()) this->quad_indices.reserve(next_highest_power_of_2(this->quad_indices.size() + 4)); this->quad_indices.push_back(idx1); this->quad_indices.push_back(idx2); this->quad_indices.push_back(idx3); this->quad_indices.push_back(idx4); + this->quad_indices_size = this->quad_indices.size(); }; // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects // and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs. - void finalize_geometry(); + void finalize_geometry() const; // Release the geometry data, release OpenGL VBOs. void release_geometry(); void render() const; - void render(const std::pair &tverts_range, const std::pair &qverts_range) const; + void render(const std::pair& tverts_range, const std::pair& qverts_range) const; // Is there any geometry data stored? bool empty() const { return vertices_and_normals_interleaved_size == 0; } - // Is this object indexed, or is it just a set of triangles? - bool indexed() const { return ! this->empty() && this->triangle_indices_size + this->quad_indices_size > 0; } - void clear() { this->vertices_and_normals_interleaved.clear(); this->triangle_indices.clear(); this->quad_indices.clear(); this->m_bounding_box.reset(); - this->setup_sizes(); + vertices_and_normals_interleaved_size = 0; + triangle_indices_size = 0; + quad_indices_size = 0; } // Shrink the internal storage to tighly fit the data stored. - void shrink_to_fit() { - if (! this->has_VBOs()) - this->setup_sizes(); + void shrink_to_fit() const { this->vertices_and_normals_interleaved.shrink_to_fit(); this->triangle_indices.shrink_to_fit(); this->quad_indices.shrink_to_fit(); @@ -203,12 +223,6 @@ public: private: BoundingBoxf3 m_bounding_box; - - inline void setup_sizes() { - vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size(); - triangle_indices_size = this->triangle_indices.size(); - quad_indices_size = this->quad_indices.size(); - } }; class GLVolume { @@ -400,9 +414,9 @@ public: const BoundingBoxf3& transformed_convex_hull_bounding_box() const; bool empty() const { return this->indexed_vertex_array.empty(); } - bool indexed() const { return this->indexed_vertex_array.indexed(); } void set_range(coordf_t low, coordf_t high); + void render() const; void render(int color_id, int detection_id, int worldmatrix_id) const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5655390ec..dbca770d6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -524,7 +524,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data())); glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4)); - for (const GLVolume *glvolume : volumes.volumes) { + for (const GLVolume* glvolume : volumes.volumes) { // Render the object using the layer editing shader and texture. if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) continue; @@ -543,8 +543,8 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G { // Something went wrong. Just render the object. assert(false); - for (const GLVolume *glvolume : volumes.volumes) { - // Render the object using the layer editing shader and texture. + for (const GLVolume* glvolume : volumes.volumes) { + // Render the object using the layer editing shader and texture. if (!glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) continue; glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); @@ -1314,10 +1314,10 @@ bool GLCanvas3D::init() return false; } - // on linux the gl context is not valid until the canvas is not shown on screen - // we defer the geometry finalization of volumes until the first call to render() - if (!m_volumes.empty()) - m_volumes.finalize_geometry(); +// // on linux the gl context is not valid until the canvas is not shown on screen +// // we defer the geometry finalization of volumes until the first call to render() +// if (!m_volumes.empty()) +// m_volumes.finalize_geometry(); if (m_gizmos.is_enabled() && !m_gizmos.init(*this)) std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl; @@ -1355,7 +1355,9 @@ void GLCanvas3D::reset_volumes() if (!m_volumes.empty()) { m_selection.clear(); - m_volumes.release_geometry(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// m_volumes.release_geometry(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_volumes.clear(); m_dirty = true; } @@ -1917,7 +1919,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re assert(volume_idx_wipe_tower_old == -1); volume_idx_wipe_tower_old = (int)volume_id; } - volume->release_geometry(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// volume->release_geometry(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (! m_reload_delayed) delete volume; } else { @@ -4474,7 +4478,6 @@ void GLCanvas3D::_load_print_toolpaths() _3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), volume); } - volume.indexed_vertex_array.finalize_geometry(); } void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) @@ -4646,9 +4649,6 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } } } - for (GLVolume *vol : vols) { - vol->indexed_vertex_array.shrink_to_fit(); - } }); BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results"; @@ -4657,8 +4657,6 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), [](const GLVolume *volume) { return volume->empty(); }), m_volumes.volumes.end()); - for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) - m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(); BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end"; } @@ -4814,9 +4812,6 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve()); } } - for (GLVolume *vol : vols) { - vol->indexed_vertex_array.shrink_to_fit(); - } }); BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results"; @@ -4825,8 +4820,6 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), [](const GLVolume *volume) { return volume->empty(); }), m_volumes.volumes.end()); - for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) - m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(); BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end"; } @@ -5003,16 +4996,6 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat } } } - - // finalize volumes and sends geometry to gpu - if (m_volumes.volumes.size() > initial_volumes_count) - { - for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i) - { - GLVolume* volume = m_volumes.volumes[i]; - volume->indexed_vertex_array.finalize_geometry(); - } - } } void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector& tool_colors) @@ -5057,16 +5040,6 @@ void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data, return; } - - // finalize volumes and sends geometry to gpu - if (m_volumes.volumes.size() > initial_volumes_count) - { - for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i) - { - GLVolume* volume = m_volumes.volumes[i]; - volume->indexed_vertex_array.finalize_geometry(); - } - } } bool GLCanvas3D::_travel_paths_by_type(const GCodePreviewData& preview_data) @@ -5295,9 +5268,6 @@ void GLCanvas3D::_load_gcode_retractions(const GCodePreviewData& preview_data) _3DScene::point3_to_verts(position.position, position.width, position.height, *volume); } - - // finalize volumes and sends geometry to gpu - volume->indexed_vertex_array.finalize_geometry(); } } @@ -5325,9 +5295,6 @@ void GLCanvas3D::_load_gcode_unretractions(const GCodePreviewData& preview_data) _3DScene::point3_to_verts(position.position, position.width, position.height, *volume); } - - // finalize volumes and sends geometry to gpu - volume->indexed_vertex_array.finalize_geometry(); } } @@ -5419,8 +5386,6 @@ void GLCanvas3D::_load_sla_shells() double shift_z = obj->get_current_elevation(); for (unsigned int i = initial_volumes_count; i < m_volumes.volumes.size(); ++ i) { GLVolume& v = *m_volumes.volumes[i]; - // finalize volumes and sends geometry to gpu - v.indexed_vertex_array.finalize_geometry(); // apply shift z v.set_sla_shift_z(shift_z); } -- cgit v1.2.3 From 136e5156bc0b9fcbeeda52dcbab8f9f993ba639e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 2 Jul 2019 13:13:17 +0200 Subject: Fixed colot_print issues: * Disabled color change information for the SLA and FFF-multimaterial presets * Corrected switch between "color print" and "feature type" on Preview --- src/slic3r/GUI/GLCanvas3D.cpp | 3 ++- src/slic3r/GUI/GUI_Preview.cpp | 51 ++++++++++++++++++++++++++--------------- src/slic3r/GUI/GUI_Preview.hpp | 2 ++ src/slic3r/GUI/Plater.cpp | 3 +++ src/slic3r/GUI/wxExtensions.cpp | 10 ++++++-- 5 files changed, 48 insertions(+), 21 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9bb6f4553..74b3e685a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -912,7 +912,8 @@ GLCanvas3D::LegendTexture::LegendTexture() void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, std::vector>& cp_legend_values) { - if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) + if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint && + wxGetApp().extruders_edited_cnt() == 1) // show color change legend only for single-material presets { auto& config = wxGetApp().preset_bundle->project_config; const std::vector& color_print_values = config.option("colorprint_heights")->values; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 671c49eef..0ba447c1b 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -541,6 +541,26 @@ void Preview::on_checkbox_shells(wxCommandEvent& evt) refresh_print(); } +void Preview::update_view_type() +{ + const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; + + const wxString& choice = !config.option("colorprint_heights")->values.empty() && + wxGetApp().extruders_edited_cnt()==1 ? + _(L("Color Print")) : + config.option("wiping_volumes_matrix")->values.size() > 1 ? + _(L("Tool")) : + _(L("Feature type")); + + int type = m_choice_view_type->FindString(choice); + if (m_choice_view_type->GetSelection() != type) { + m_choice_view_type->SetSelection(type); + if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types) + m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; + m_preferred_color_mode = "feature"; + } +} + void Preview::create_double_slider() { m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); @@ -553,23 +573,13 @@ void Preview::create_double_slider() Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { - auto& config = wxGetApp().preset_bundle->project_config; - ((config.option("colorprint_heights"))->values) = (m_slider->GetTicksValues()); - m_schedule_background_process(); - - const wxString& choise = !config.option("colorprint_heights")->values.empty() ? _(L("Color Print")) : - config.option("wiping_volumes_matrix")->values.size() > 1 ? - _(L("Tool")) : _(L("Feature type")); - - int type = m_choice_view_type->FindString(choise); - if (m_choice_view_type->GetSelection() != type) { - m_choice_view_type->SetSelection(type); - if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types)) - m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; - m_preferred_color_mode = "feature"; - } - reload_print(); - }); + wxGetApp().preset_bundle->project_config.option("colorprint_heights")->values = m_slider->GetTicksValues(); + m_schedule_background_process(); + + update_view_type(); + + reload_print(); + }); } // Find an index of a value in a sorted vector, which is in . @@ -787,9 +797,14 @@ void Preview::load_print_as_fff(bool keep_z_range) // Load the real G-code preview. m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); m_loaded = true; - } else + } else { + // disable color change information for multi-material presets + if (wxGetApp().extruders_edited_cnt() > 1) + color_print_values.clear(); + // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); + } show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); // recalculates zs and update sliders accordingly std::vector zs = m_canvas->get_current_print_zs(true); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 993e260e4..e86d0e430 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -127,6 +127,8 @@ public: void move_double_slider(wxKeyEvent& evt); void edit_double_slider(wxKeyEvent& evt); + void update_view_type(); + private: bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a0deb52e3..09ab91ef1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3947,6 +3947,9 @@ void Plater::reslice() } else if (!p->background_process.empty() && !p->background_process.idle()) p->show_action_buttons(true); + + // update type of preview + p->preview->update_view_type(); } void Plater::reslice_SLA_supports(const ModelObject &object) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index aed423674..55044138f 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2027,6 +2027,9 @@ void DoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord void DoubleSlider::draw_ticks(wxDC& dc) { + if (!m_is_enabled_tick_manipulation) + return; + dc.SetPen(m_is_enabled_tick_manipulation ? DARK_GREY_PEN : LIGHT_GREY_PEN ); int height, width; get_size(&width, &height); @@ -2044,6 +2047,9 @@ void DoubleSlider::draw_ticks(wxDC& dc) void DoubleSlider::draw_colored_band(wxDC& dc) { + if (!m_is_enabled_tick_manipulation) + return; + int height, width; get_size(&width, &height); @@ -2113,7 +2119,7 @@ void DoubleSlider::draw_one_layer_icon(wxDC& dc) void DoubleSlider::draw_revert_icon(wxDC& dc) { - if (m_ticks.empty()) + if (m_ticks.empty() || !m_is_enabled_tick_manipulation) return; int width, height; @@ -2218,7 +2224,7 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) m_selection == ssLower ? correct_lower_value() : correct_higher_value(); if (!m_selection) m_selection = ssHigher; } - else if (is_point_in_rect(pos, m_rect_revert_icon)) { + else if (is_point_in_rect(pos, m_rect_revert_icon) && m_is_enabled_tick_manipulation) { // discard all color changes SetLowerValue(m_min_value); SetHigherValue(m_max_value); -- cgit v1.2.3 From 2a71665de90f043d25a9b8f52281a1fc1072fdf2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 2 Jul 2019 15:10:59 +0200 Subject: Follow-up of d07b3fb08b5f8e81899a4772f8219fde49ef2126 -> Show current bed shape for custom bed in bed shape dialog --- src/slic3r/GUI/BedShapeDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index cec0f5067..20aa68ef2 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -234,8 +234,8 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points) // This is a custom bed shape, use the polygon provided. m_shape_options_book->SetSelection(SHAPE_CUSTOM); // Copy the polygon to the canvas, make a copy of the array. - m_canvas->m_bed_shape = points->values; - update_shape(); + m_loaded_bed_shape = points->values; + update_shape(); } void BedShapePanel::update_preview() -- cgit v1.2.3 From 0bcad2a5c52b774eba6472077cbe6cb786c20f27 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 2 Jul 2019 15:26:11 +0200 Subject: Fix for the last commit --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 22 ++++++++++------------ src/slic3r/GUI/GUI_ObjectLayers.hpp | 7 +++---- src/slic3r/GUI/GUI_ObjectList.cpp | 20 ++++++++++++++++++-- 3 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index f9d3a8956..b30d3ecd3 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -197,25 +197,17 @@ void ObjectLayers::update_layers_list() // Add new control according to the selected item if (type & itLayerRoot) - { - wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); - m_selectable_range = { 0.0, 0.0 }; create_layers_list(); - } else - { - t_layer_height_range range = objects_ctrl->GetModel()->GetLayerRangeByItem(item); - create_layer(range); - update_scene_from_editor_selection(range, etLayerHeight); - } + create_layer(objects_ctrl->GetModel()->GetLayerRangeByItem(item)); m_parent->Layout(); } -void ObjectLayers::update_scene_from_editor_selection(const t_layer_height_range& range, EditorType type) const +void ObjectLayers::update_scene_from_editor_selection() const { // needed to show the visual hints in 3D scene - wxGetApp().plater()->canvas3D()->handle_layers_data_focus_event(range, type); + wxGetApp().plater()->canvas3D()->handle_layers_data_focus_event(m_selectable_range, m_selection_type); } void ObjectLayers::UpdateAndShow(const bool show) @@ -232,6 +224,12 @@ void ObjectLayers::msw_rescale() m_bmp_add.msw_rescale(); } +void ObjectLayers::reset_selection() +{ + m_selectable_range = { 0.0, 0.0 }; + m_selection_type = etLayerHeight; +} + LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, const wxString& value, EditorType type, @@ -297,7 +295,7 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, this->Bind(wxEVT_SET_FOCUS, [this, parent](wxFocusEvent& e) { set_focus_data(); - parent->update_scene_from_editor_selection(parent->get_selectable_range(), parent->get_selection_type()); + parent->update_scene_from_editor_selection(); e.Skip(); }, this->GetId()); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 253cbf0a4..f274183e2 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -73,13 +73,12 @@ public: void create_layers_list(); void update_layers_list(); - void update_scene_from_editor_selection(const t_layer_height_range& range, EditorType type) const; + void update_scene_from_editor_selection() const; void UpdateAndShow(const bool show) override; void msw_rescale(); - - const t_layer_height_range& get_selectable_range() const { return m_selectable_range; } - EditorType get_selection_type() const { return m_selection_type; } + void reset_selection(); + void set_selectable_range(const t_layer_height_range& range) { m_selectable_range = range; } friend class LayerRangeEditor; }; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index af1a9908d..5c421705b 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -578,6 +578,22 @@ void ObjectList::selection_changed() wxPostEvent(this, event); } + if (const wxDataViewItem item = GetSelection()) + { + const ItemType type = m_objects_model->GetItemType(item); + // to correct visual hints for layers editing on the Scene + if (type & (itLayer|itLayerRoot)) { + wxGetApp().obj_layers()->reset_selection(); + + if (type & itLayerRoot) + wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); + else { + wxGetApp().obj_layers()->set_selectable_range(m_objects_model->GetLayerRangeByItem(item)); + wxGetApp().obj_layers()->update_scene_from_editor_selection(); + } + } + } + part_selection_changed(); } @@ -1864,7 +1880,7 @@ void ObjectList::layers_editing() // set some default value if (ranges.empty()) - ranges[{ 0.0f, 0.6f }] = get_default_layer_config(obj_idx); + ranges[{ 0.0f, 2.0f }] = get_default_layer_config(obj_idx); // create layer root item layers_item = add_layer_root_item(obj_item); @@ -2330,7 +2346,7 @@ void ObjectList::add_layer_range_after_current(const t_layer_height_range& curre if (current_range == last_range) { - const t_layer_height_range& new_range = { last_range.second, last_range.second + 0.5f }; + const t_layer_height_range& new_range = { last_range.second, last_range.second + 2.0f }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item); } -- cgit v1.2.3 From 90daffccf2b5fa0a5ab21cec8581e8bf1e92e72f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 2 Jul 2019 15:49:18 +0200 Subject: View dependent order of rendering for layers editing visual hints to keep the correct transparency --- src/slic3r/GUI/Plater.cpp | 5 +++++ src/slic3r/GUI/Plater.hpp | 2 ++ src/slic3r/GUI/Selection.cpp | 30 +++++++++++++++++------------- 3 files changed, 24 insertions(+), 13 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 98b7c1303..0a154034f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4273,6 +4273,11 @@ void Plater::msw_rescale() GetParent()->Layout(); } +const Camera& Plater::get_camera() const +{ + return p->camera; +} + bool Plater::can_delete() const { return p->can_delete(); } bool Plater::can_delete_all() const { return p->can_delete_all(); } bool Plater::can_increase_instances() const { return p->can_increase_instances(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index c3f8927c0..34fd7984e 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -220,6 +220,8 @@ public: void msw_rescale(); + const Camera& get_camera() const; + private: struct priv; std::unique_ptr p; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 9939c291e..bea94e2e6 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -6,7 +6,8 @@ #include "GUI_ObjectManipulation.hpp" #include "GUI_ObjectList.hpp" #include "Gizmos/GLGizmoBase.hpp" -#include "slic3r/GUI/3DScene.hpp" +#include "3DScene.hpp" +#include "Camera.hpp" #include @@ -1761,33 +1762,36 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co const float min_y = box.min(1) - Margin; const float max_y = box.max(1) + Margin; + // view dependend order of rendering to keep correct transparency + bool camera_on_top = wxGetApp().plater()->get_camera().get_theta() <= 90.0f; + float z1 = camera_on_top ? min_z : max_z; + float z2 = camera_on_top ? max_z : min_z; + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - // Draw the min_z plane ::glBegin(GL_QUADS); - if (type == 1) + if ((camera_on_top && (type == 1)) || (!camera_on_top && (type == 2))) ::glColor4f(1.0f, 0.38f, 0.0f, 1.0f); else ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); - ::glVertex3f(min_x, min_y, min_z); - ::glVertex3f(max_x, min_y, min_z); - ::glVertex3f(max_x, max_y, min_z); - ::glVertex3f(min_x, max_y, min_z); + ::glVertex3f(min_x, min_y, z1); + ::glVertex3f(max_x, min_y, z1); + ::glVertex3f(max_x, max_y, z1); + ::glVertex3f(min_x, max_y, z1); glsafe(::glEnd()); - // Draw the max_z plane ::glBegin(GL_QUADS); - if (type == 2) + if ((camera_on_top && (type == 2)) || (!camera_on_top && (type == 1))) ::glColor4f(1.0f, 0.38f, 0.0f, 1.0f); else ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); - ::glVertex3f(min_x, min_y, max_z); - ::glVertex3f(max_x, min_y, max_z); - ::glVertex3f(max_x, max_y, max_z); - ::glVertex3f(min_x, max_y, max_z); + ::glVertex3f(min_x, min_y, z2); + ::glVertex3f(max_x, min_y, z2); + ::glVertex3f(max_x, max_y, z2); + ::glVertex3f(min_x, max_y, z2); glsafe(::glEnd()); glsafe(::glEnable(GL_CULL_FACE)); -- cgit v1.2.3 From 5e846112eee7ff881b2fe5754d3136e152fe3220 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 2 Jul 2019 16:42:23 +0200 Subject: WIP UndoRedo: Added Undo/Redo stack, added Platter::take_snapshot(), experimental snapshots on loading STLs and increasing / decreasing model instances. --- src/slic3r/GUI/Plater.cpp | 31 ++++++++++++++++++++++++++++++- src/slic3r/GUI/Plater.hpp | 3 +++ src/slic3r/GUI/Selection.hpp | 3 ++- 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9d0c979b6..f08480559 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -69,6 +69,7 @@ #include "../Utils/ASCIIFolding.hpp" #include "../Utils/PrintHost.hpp" #include "../Utils/FixModelByWin10.hpp" +#include "../Utils/UndoRedo.hpp" #include // Needs to be last because reasons :-/ #include "WipeTowerDialog.hpp" @@ -1182,6 +1183,8 @@ const std::regex PlaterDropTarget::pattern_drop(".*[.](stl|obj|amf|3mf|prusa)", bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) { + plater->take_snapshot(_(L("Load Files"))); + std::vector paths; for (const auto &filename : filenames) { @@ -1247,6 +1250,7 @@ struct Plater::priv Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; + Slic3r::UndoRedo::Stack undo_redo_stack; // GUI elements wxSizer* panel_sizer{ nullptr }; @@ -1545,6 +1549,10 @@ struct Plater::priv void split_object(); void split_volume(); void scale_selection_to_fit_print_volume(); + + void take_snapshot(const std::string& snapshot_name) { this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); } + void take_snapshot(const wxString& snapshot_name) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data())); } + bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } void update_print_volume_state(); void schedule_background_process(); @@ -1775,6 +1783,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // updates camera type from .ini file camera.set_type(get_config("use_perspective_camera")); + + this->undo_redo_stack.initialize(model, view3D->get_canvas3d()->get_selection()); } void Plater::priv::update(bool force_full_scene_refresh) @@ -2139,7 +2149,7 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs &mode // the size of the object is too big -> this could lead to overflow when moving to clipper coordinates, // so scale down the mesh double inv = 1. / max_ratio; - object->scale_mesh(Vec3d(inv, inv, inv)); + object->scale_mesh_after_creation(Vec3d(inv, inv, inv)); object->origin_translation = Vec3d::Zero(); object->center_around_origin(); scaled_down = true; @@ -2355,6 +2365,8 @@ void Plater::priv::delete_object_from_model(size_t obj_idx) void Plater::priv::reset() { + this->take_snapshot(_(L("Reset Project"))); + set_project_filename(wxEmptyString); // Prevent toolpaths preview from rendering while we modify the Print object @@ -3515,6 +3527,8 @@ void Plater::new_project() void Plater::load_project() { + this->take_snapshot(_(L("Load Project"))); + wxString input_file; wxGetApp().load_project(this, input_file); @@ -3593,6 +3607,7 @@ void Plater::delete_object_from_model(size_t obj_idx) { p->delete_object_from_mo void Plater::remove_selected() { + this->take_snapshot(_(L("Delete Selected Objects"))); this->p->view3D->delete_selected(); } @@ -3600,6 +3615,8 @@ void Plater::increase_instances(size_t num) { if (! can_increase_instances()) { return; } + this->take_snapshot(_(L("Increase Instances"))); + int obj_idx = p->get_selected_object_idx(); ModelObject* model_object = p->model.objects[obj_idx]; @@ -3634,6 +3651,8 @@ void Plater::decrease_instances(size_t num) { if (! can_decrease_instances()) { return; } + this->take_snapshot(_(L("Decrease Instances"))); + int obj_idx = p->get_selected_object_idx(); ModelObject* model_object = p->model.objects[obj_idx]; @@ -3982,6 +4001,16 @@ void Plater::send_gcode() } } +void Plater::take_snapshot(const std::string &snapshot_name) +{ + p->take_snapshot(snapshot_name); +} + +void Plater::take_snapshot(const wxString &snapshot_name) +{ + p->take_snapshot(snapshot_name); +} + void Plater::on_extruders_change(int num_extruders) { auto& choices = sidebar().combos_filament(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 2851af654..9a6bcda7b 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -179,6 +179,9 @@ public: void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void send_gcode(); + void take_snapshot(const std::string &snapshot_name); + void take_snapshot(const wxString &snapshot_name); + void on_extruders_change(int extruders_count); void on_config_change(const DynamicPrintConfig &config); // On activating the parent window. diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index c23f23e6b..17ae72356 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -3,6 +3,7 @@ #include #include "libslic3r/Geometry.hpp" +#include "libslic3r/ObjectID.hpp" #include "3DScene.hpp" #if ENABLE_RENDER_SELECTION_CENTER @@ -66,7 +67,7 @@ private: Enum m_value; }; -class Selection +class Selection : public Slic3r::ObjectBase { public: typedef std::set IndicesList; -- cgit v1.2.3 From d101ed709c79c305433a14e780be63428f3da12f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 3 Jul 2019 08:58:05 +0200 Subject: Button 'Load shape from STL' centered into its panel in bed shape dialog --- src/slic3r/GUI/BedShapeDialog.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 20aa68ef2..4dc7d0f79 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -92,13 +92,15 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) Line line{ "", "" }; line.full_width = 1; line.widget = [this](wxWindow* parent) { - auto btn = new wxButton(parent, wxID_ANY, _(L("Load shape from STL...")), wxDefaultPosition, wxDefaultSize); - - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + auto shape_btn = new wxButton(parent, wxID_ANY, _(L("Load shape from STL..."))); + wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL); + shape_sizer->Add(shape_btn, 1, wxEXPAND); - btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) - { + wxSizer* sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(shape_sizer, 1, wxEXPAND); + + shape_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) + { load_stl(); })); -- cgit v1.2.3 From 7a7316fcbf79a51087266bf57373c8428760eac5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 3 Jul 2019 09:19:07 +0200 Subject: Fixed compile warnings in Bed3D --- src/slic3r/GUI/3DBed.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 68a74f61c..fc07581e6 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -44,8 +44,8 @@ public: const float* get_vertices_data() const; unsigned int get_vertices_data_size() const { return (unsigned int)m_vertices.size() * get_vertex_data_size(); } unsigned int get_vertex_data_size() const { return (unsigned int)(5 * sizeof(float)); } - unsigned int get_position_offset() const { return 0; } - unsigned int get_tex_coords_offset() const { return (unsigned int)(3 * sizeof(float)); } + size_t get_position_offset() const { return 0; } + size_t get_tex_coords_offset() const { return (size_t)(3 * sizeof(float)); } unsigned int get_vertices_count() const { return (unsigned int)m_vertices.size(); } #else const float* get_vertices() const { return m_vertices.data(); } -- cgit v1.2.3 From 2c0f0c85a5335405c09a9ff4fa84d2636de0d68d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 3 Jul 2019 10:06:22 +0200 Subject: Fixed bed shape dialog layout --- src/slic3r/GUI/BedShapeDialog.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 4dc7d0f79..d52204d4a 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -53,15 +53,12 @@ void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect) void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) { -// on_change(nullptr); - - auto box = new wxStaticBox(this, wxID_ANY, _(L("Shape"))); - auto sbsizer = new wxStaticBoxSizer(box, wxVERTICAL); + auto sbsizer = new wxStaticBoxSizer(wxVERTICAL, this, _(L("Shape"))); // shape options m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(25*wxGetApp().em_unit(), -1), wxCHB_TOP); - sbsizer->Add(m_shape_options_book); + sbsizer->Add(m_shape_options_book); auto optgroup = init_shape_options_page(_(L("Rectangular"))); ConfigOptionDef def; @@ -108,8 +105,8 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) }; optgroup->append_line(line); - Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e) - { + Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent& e) + { update_shape(); })); @@ -119,8 +116,8 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) // main sizer auto top_sizer = new wxBoxSizer(wxHORIZONTAL); - top_sizer->Add(sbsizer, 0, wxEXPAND | wxLeft | wxTOP | wxBOTTOM, 10); - if (m_canvas) + top_sizer->Add(sbsizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 10); + if (m_canvas) top_sizer->Add(m_canvas, 1, wxEXPAND | wxALL, 10) ; SetSizerAndFit(top_sizer); @@ -137,8 +134,7 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) // Create a panel for a rectangular / circular / custom bed shape. ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(const wxString& title) { - - auto panel = new wxPanel(m_shape_options_book); + auto panel = new wxPanel(m_shape_options_book); ConfigOptionsGroupShp optgroup; optgroup = std::make_shared(panel, _(L("Settings"))); -- cgit v1.2.3 From e2a670218bd5a47c09595b7bc60e2fd7ee4c7858 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 3 Jul 2019 13:43:54 +0200 Subject: WIP Undo / Redo: Serializing the configs of ModelObject / ModelVolume / ModelMaterial as separate objects to conserve memory. --- src/slic3r/GUI/Selection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 97168ee04..0784b70ff 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1160,7 +1160,7 @@ void Selection::copy_to_clipboard() ModelObject* dst_object = m_clipboard.add_object(); dst_object->name = src_object->name; dst_object->input_file = src_object->input_file; - dst_object->config = src_object->config; + static_cast(dst_object->config) = static_cast(src_object->config); dst_object->sla_support_points = src_object->sla_support_points; dst_object->sla_points_status = src_object->sla_points_status; dst_object->layer_height_ranges = src_object->layer_height_ranges; -- cgit v1.2.3 From 5a2ace1a6e466c3501817cfa73d3b74606222395 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Jul 2019 10:45:41 +0200 Subject: WIP Undo / Redo: First Undo in the history of PrusaSlicer! --- src/slic3r/GUI/GLCanvas3D.cpp | 21 +++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ src/slic3r/GUI/Plater.cpp | 38 +++++++++++++++++++++++++++++--------- src/slic3r/GUI/Plater.hpp | 2 ++ 4 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4116ac34b..511c423e6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1191,6 +1191,8 @@ wxDEFINE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar) : m_canvas(canvas) @@ -2350,6 +2352,25 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #endif /* __APPLE__ */ post_event(SimpleEvent(EVT_GLTOOLBAR_PASTE)); break; + + +#ifdef __APPLE__ + case 'y': + case 'Y': +#else /* __APPLE__ */ + case WXK_CONTROL_Y: +#endif /* __APPLE__ */ + post_event(SimpleEvent(EVT_GLCANVAS_REDO)); + break; +#ifdef __APPLE__ + case 'z': + case 'Z': +#else /* __APPLE__ */ + case WXK_CONTROL_Z: +#endif /* __APPLE__ */ + post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); + break; + #ifdef __APPLE__ case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. #else /* __APPLE__ */ diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d39a910b3..d71817b34 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -126,6 +126,8 @@ wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); class GLCanvas3D { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f08480559..3e6f3763a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1552,6 +1552,8 @@ struct Plater::priv void take_snapshot(const std::string& snapshot_name) { this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); } void take_snapshot(const wxString& snapshot_name) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data())); } + void undo(); + void redo(); bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } void update_print_volume_state(); @@ -1745,6 +1747,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this); view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); }); + view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); }); + view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); // 3DScene/Toolbar: view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); @@ -1785,6 +1789,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) camera.set_type(get_config("use_perspective_camera")); this->undo_redo_stack.initialize(model, view3D->get_canvas3d()->get_selection()); + this->take_snapshot(_(L("New Project"))); } void Plater::priv::update(bool force_full_scene_refresh) @@ -3490,6 +3495,26 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const } } +void Plater::priv::undo() +{ + if (this->undo_redo_stack.undo(model, const_cast(view3D->get_canvas3d()->get_selection()))) { + this->update(false); + //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) +// wxGetApp().obj_list()->update_selections(); +// selection_changed(); + } +} + +void Plater::priv::redo() +{ + if (this->undo_redo_stack.redo(model, const_cast(view3D->get_canvas3d()->get_selection()))) { + this->update(false); + //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) +// wxGetApp().obj_list()->update_selections(); +// selection_changed(); + } +} + void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& label) const { switch (btn_type) @@ -4001,15 +4026,10 @@ void Plater::send_gcode() } } -void Plater::take_snapshot(const std::string &snapshot_name) -{ - p->take_snapshot(snapshot_name); -} - -void Plater::take_snapshot(const wxString &snapshot_name) -{ - p->take_snapshot(snapshot_name); -} +void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); } +void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } +void Plater::undo() { p->undo(); } +void Plater::redo() { p->redo(); } void Plater::on_extruders_change(int num_extruders) { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 9a6bcda7b..91f218f6c 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -181,6 +181,8 @@ public: void take_snapshot(const std::string &snapshot_name); void take_snapshot(const wxString &snapshot_name); + void undo(); + void redo(); void on_extruders_change(int extruders_count); void on_config_change(const DynamicPrintConfig &config); -- cgit v1.2.3 From 74f9a5432f3f72423137b5cd9a56fc2c33e57845 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 4 Jul 2019 14:25:40 +0200 Subject: Reset previous layers range selection before selection Layers Item --- src/slic3r/GUI/GUI_ObjectList.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 5c421705b..4c4a30227 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1888,6 +1888,10 @@ void ObjectList::layers_editing() if (!layers_item.IsOk()) return; + // to correct visual hints for layers editing on the Scene, reset previous selection + wxGetApp().obj_layers()->reset_selection(); + wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); + // select LayerRoor item and expand select_item(layers_item); Expand(layers_item); -- cgit v1.2.3 From 1798e2a84c57a9ecde31ffbeebdf6da0758bcd94 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Jul 2019 14:35:04 +0200 Subject: WIP Undo / Redo : serialization / deserialization of object selection. --- src/slic3r/GUI/Plater.cpp | 25 +++++++++++++++---------- src/slic3r/GUI/Selection.cpp | 18 ++++++++++++++++++ src/slic3r/GUI/Selection.hpp | 6 ++++-- 3 files changed, 37 insertions(+), 12 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3e6f3763a..a492584e6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1645,6 +1645,7 @@ private: void update_fff_scene(); void update_sla_scene(); + void update_after_undo_redo(); // path to project file stored with no extension wxString m_project_filename; @@ -3497,22 +3498,26 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const void Plater::priv::undo() { - if (this->undo_redo_stack.undo(model, const_cast(view3D->get_canvas3d()->get_selection()))) { - this->update(false); - //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) -// wxGetApp().obj_list()->update_selections(); -// selection_changed(); - } + if (this->undo_redo_stack.undo(model)) + this->update_after_undo_redo(); } void Plater::priv::redo() { - if (this->undo_redo_stack.redo(model, const_cast(view3D->get_canvas3d()->get_selection()))) { - this->update(false); - //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) + if (this->undo_redo_stack.redo(model)) + this->update_after_undo_redo(); +} + +void Plater::priv::update_after_undo_redo() +{ + this->view3D->get_canvas3d()->get_selection().clear(); + this->update(false); // update volumes from the deserializd model + //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) + this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack.selection_deserialized().mode), this->undo_redo_stack.selection_deserialized().volumes_and_instances); // wxGetApp().obj_list()->update_selections(); // selection_changed(); - } + //FIXME what about the state of the manipulators? + //FIXME what about the focus? Cursor in the side panel? } void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& label) const diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 0784b70ff..2986d97dd 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -311,6 +311,24 @@ void Selection::add_all() this->set_bounding_boxes_dirty(); } +void Selection::set_deserialized(EMode mode, const std::vector> &volumes_and_instances) +{ + if (! m_valid) + return; + + m_mode = mode; + for (unsigned int i : m_list) + (*m_volumes)[i]->selected = false; + m_list.clear(); + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++ i) { + const GLVolume::CompositeID &id = (*m_volumes)[i]->composite_id; + if (std::binary_search(volumes_and_instances.begin(), volumes_and_instances.end(), std::make_pair(id.volume_id, id.instance_id))) + this->do_add_volume(i); + } + update_type(); + this->set_bounding_boxes_dirty(); +} + void Selection::clear() { if (!m_valid) diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 17ae72356..8168e5e88 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -3,7 +3,6 @@ #include #include "libslic3r/Geometry.hpp" -#include "libslic3r/ObjectID.hpp" #include "3DScene.hpp" #if ENABLE_RENDER_SELECTION_CENTER @@ -67,7 +66,7 @@ private: Enum m_value; }; -class Selection : public Slic3r::ObjectBase +class Selection { public: typedef std::set IndicesList; @@ -238,6 +237,9 @@ public: void add_all(); + // To be called after Undo or Redo once the volumes are updated. + void set_deserialized(EMode mode, const std::vector> &volumes_and_instances); + // Update the selection based on the new instance IDs. void instances_changed(const std::vector &instance_ids_selected); // Update the selection based on the map from old indices to new indices after m_volumes changed. -- cgit v1.2.3 From e586475bc32cb8ef8b2569ea60a5aa0d35a9bc09 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Jul 2019 17:14:15 +0200 Subject: WIP Undo / Redo: Optional debug print outs. --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a492584e6..4a743aab1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3498,7 +3498,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const void Plater::priv::undo() { - if (this->undo_redo_stack.undo(model)) + if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection())) this->update_after_undo_redo(); } -- cgit v1.2.3 From a29cc9e242285bc394fdd4e08a6911830cdd6631 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 4 Jul 2019 17:33:19 +0200 Subject: Update object list after undo/redo --- src/slic3r/GUI/GUI_ObjectList.cpp | 42 ++++++++++++++++++++++++++++++++++++++- src/slic3r/GUI/GUI_ObjectList.hpp | 2 ++ src/slic3r/GUI/Plater.cpp | 40 +++++++++++++++++++++++++++++++++---- src/slic3r/GUI/Selection.cpp | 8 +++----- src/slic3r/GUI/Selection.hpp | 2 +- 5 files changed, 83 insertions(+), 11 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index d7d1a1af7..acb6d3a86 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -65,6 +65,11 @@ static int extruders_count() return wxGetApp().extruders_cnt(); } +static void take_snapshot(const wxString& snapshot_name) +{ + wxGetApp().plater()->take_snapshot(snapshot_name); +} + ObjectList::ObjectList(wxWindow* parent) : wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE), m_parent(parent) @@ -580,7 +585,6 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol if (volumes.empty()) return; - ModelObject& model_object = *(*m_objects)[obj_idx]; const auto object_item = m_objects_model->GetItemById(obj_idx); wxDataViewItemArray items; @@ -816,6 +820,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) if (m_dragged_data.type() == itInstance) { + take_snapshot(_(L("Instances to Separated Objects"))); instances_to_separated_object(m_dragged_data.obj_idx(), m_dragged_data.inst_idxs()); m_dragged_data.clear(); return; @@ -833,6 +838,8 @@ void ObjectList::OnDrop(wxDataViewEvent &event) // if (to_volume_id > from_volume_id) to_volume_id--; // #endif // __WXGTK__ + take_snapshot(_(L("Remov Volume(s)"))); + auto& volumes = (*m_objects)[m_dragged_data.obj_idx()]->volumes; auto delta = to_volume_id < from_volume_id ? -1 : 1; int cnt = 0; @@ -1427,6 +1434,8 @@ void ObjectList::load_subobject(ModelVolumeType type) if (m_objects_model->GetItemType(item)&itInstance) item = m_objects_model->GetItemById(obj_idx); + take_snapshot(_(L("Load Part"))); + std::vector> volumes_info; load_part((*m_objects)[obj_idx], volumes_info, type); @@ -1502,6 +1511,8 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode if (instance_idx == -1) return; + take_snapshot(_(L("Add Generic Subobject"))); + // Selected object ModelObject &model_object = *(*m_objects)[obj_idx]; // Bounding box of the selected instance in world coordinate system including the translation, without modifiers. @@ -1616,6 +1627,8 @@ void ObjectList::del_instances_from_object(const int obj_idx) if (instances.size() <= 1) return; + take_snapshot(_(L("Delete All Instances from Object"))); + while ( instances.size()> 1) instances.pop_back(); @@ -1645,6 +1658,8 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con return false; } + take_snapshot(_(L("Delete Subobject"))); + object->delete_volume(idx); if (object->volumes.size() == 1) @@ -1661,6 +1676,8 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last intance from object."))); return false; } + + take_snapshot(_(L("Delete Instance"))); object->delete_instance(idx); } else @@ -1688,6 +1705,8 @@ void ObjectList::split() return; } + take_snapshot(_(L("Split to Parts"))); + wxBusyCursor wait; auto model_object = (*m_objects)[obj_idx]; @@ -1945,6 +1964,8 @@ void ObjectList::delete_from_model_and_list(const ItemType type, const int obj_i if ( !(type&(itObject|itVolume|itInstance)) ) return; + take_snapshot(_(L("Delete Selected Item"))); + if (type&itObject) { del_object(obj_idx); delete_object_from_list(obj_idx); @@ -2502,6 +2523,8 @@ void ObjectList::change_part_type() if (new_type == type || new_type == ModelVolumeType::INVALID) return; + take_snapshot(_(L("Paste from Clipboard"))); + const auto item = GetSelection(); volume->set_type(new_type); m_objects_model->SetVolumeType(item, new_type); @@ -2862,5 +2885,22 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const wxGetApp().plater()->update(); } +void ObjectList::recreate_object_list() +{ + m_prevent_list_events = true; + m_prevent_canvas_selection_update = true; + + m_objects_model->DeleteAll(); + + size_t obj_idx = 0; + while (obj_idx < m_objects->size()) { + add_object_to_list(obj_idx); + ++obj_idx; + } + + m_prevent_canvas_selection_update = false; + m_prevent_list_events = false; +} + } //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 166606e2e..3d312d9c9 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -300,6 +300,8 @@ public: void msw_rescale(); + void recreate_object_list(); + private: #ifdef __WXOSX__ // void OnChar(wxKeyEvent& event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a492584e6..567be0d41 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1738,7 +1738,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event &evt) { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); - view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { + this->take_snapshot(_(L("Instance Moved"))); + update(); }); view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); }); @@ -2337,17 +2339,21 @@ void Plater::priv::object_list_changed() void Plater::priv::select_all() { +// this->take_snapshot(_(L("Select All"))); + view3D->select_all(); this->sidebar->obj_list()->update_selections(); } void Plater::priv::deselect_all() { +// this->take_snapshot(_(L("Deselect All"))); view3D->deselect_all(); } void Plater::priv::remove(size_t obj_idx) { + this->take_snapshot(_(L("Remove Object"))); // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); @@ -2364,6 +2370,7 @@ void Plater::priv::remove(size_t obj_idx) void Plater::priv::delete_object_from_model(size_t obj_idx) { +// this->take_snapshot(_(L("Delete Object"))); // ys_FIXME What is the difference with "Remove Object"? model.delete_object(obj_idx); update(); object_list_changed(); @@ -2398,17 +2405,20 @@ void Plater::priv::reset() void Plater::priv::mirror(Axis axis) { + this->take_snapshot(_(L("Mirror"))); view3D->mirror_selection(axis); } void Plater::priv::arrange() { + this->take_snapshot(_(L("Arrange"))); m_ui_jobs.start(Jobs::Arrange); } // This method will find an optimal orientation for the currently selected item // Very similar in nature to the arrange method above... void Plater::priv::sla_optimize_rotation() { + this->take_snapshot(_(L("Optimize Rotation"))); m_ui_jobs.start(Jobs::Rotoptimize); } @@ -2564,6 +2574,8 @@ void Plater::priv::split_object() Slic3r::GUI::warning_catcher(q, _(L("The selected object couldn't be split because it contains only one part."))); else { + this->take_snapshot(_(L("Split to Objects"))); + unsigned int counter = 1; for (ModelObject* m : new_objects) m->name = current_model_object->name + "_" + std::to_string(counter++); @@ -2835,6 +2847,9 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = { if (obj_idx < 0) return; + + this->take_snapshot(_(L("Fix Throught NetFabb"))); + fix_model_by_win10_sdk_gui(*model.objects[obj_idx], vol_idx); this->update(); this->object_list_changed(); @@ -3074,6 +3089,8 @@ void Plater::priv::on_action_layersediting(SimpleEvent&) void Plater::priv::on_object_select(SimpleEvent& evt) { +// this->take_snapshot(_(L("Object Selection"))); + wxGetApp().obj_list()->update_selections(); selection_changed(); } @@ -3135,6 +3152,8 @@ void Plater::priv::on_right_click(Vec2dEvent& evt) void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) { + this->take_snapshot(_(L("Wipe Tower Moved"))); + DynamicPrintConfig cfg; cfg.opt("wipe_tower_x", true)->value = evt.data(0); cfg.opt("wipe_tower_y", true)->value = evt.data(1); @@ -3143,6 +3162,8 @@ void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt) { + this->take_snapshot(_(L("Wipe Tower Rotated"))); + DynamicPrintConfig cfg; cfg.opt("wipe_tower_x", true)->value = evt.data(0); cfg.opt("wipe_tower_y", true)->value = evt.data(1); @@ -3514,7 +3535,9 @@ void Plater::priv::update_after_undo_redo() this->update(false); // update volumes from the deserializd model //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack.selection_deserialized().mode), this->undo_redo_stack.selection_deserialized().volumes_and_instances); -// wxGetApp().obj_list()->update_selections(); + + wxGetApp().obj_list()->recreate_object_list(); + wxGetApp().obj_list()->update_selections(); // selection_changed(); //FIXME what about the state of the manipulators? //FIXME what about the focus? Cursor in the side panel? @@ -3580,6 +3603,8 @@ void Plater::add_model() if (input_files.empty()) return; + this->take_snapshot(_(L("Add object(s)"))); + std::vector input_paths; for (const auto &file : input_files) { input_paths.push_back(into_path(file)); @@ -3717,6 +3742,8 @@ void Plater::set_number_of_copies(/*size_t num*/) if (num < 0) return; + this->take_snapshot(wxString::Format(_(L("Set numbers of copies to %d")), num)); + int diff = (int)num - (int)model_object->instances.size(); if (diff > 0) increase_instances(diff); @@ -3745,6 +3772,8 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe return; } + this->take_snapshot(_(L("Cut"))); + wxBusyCursor wait; const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower); @@ -4245,8 +4274,11 @@ void Plater::copy_selection_to_clipboard() void Plater::paste_from_clipboard() { - if (can_paste_from_clipboard()) - p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); + if (!can_paste_from_clipboard()) + return; + + this->take_snapshot(_(L("Paste From Clipboard"))); + p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } void Plater::msw_rescale() diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2986d97dd..ffb423758 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -311,7 +311,7 @@ void Selection::add_all() this->set_bounding_boxes_dirty(); } -void Selection::set_deserialized(EMode mode, const std::vector> &volumes_and_instances) +void Selection::set_deserialized(EMode mode, const std::vector> &volumes_and_instances) { if (! m_valid) return; @@ -320,11 +320,9 @@ void Selection::set_deserialized(EMode mode, const std::vectorselected = false; m_list.clear(); - for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++ i) { - const GLVolume::CompositeID &id = (*m_volumes)[i]->composite_id; - if (std::binary_search(volumes_and_instances.begin(), volumes_and_instances.end(), std::make_pair(id.volume_id, id.instance_id))) + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++ i) + if (std::binary_search(volumes_and_instances.begin(), volumes_and_instances.end(), (*m_volumes)[i]->geometry_id)) this->do_add_volume(i); - } update_type(); this->set_bounding_boxes_dirty(); } diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 8168e5e88..35336c2b3 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -238,7 +238,7 @@ public: void add_all(); // To be called after Undo or Redo once the volumes are updated. - void set_deserialized(EMode mode, const std::vector> &volumes_and_instances); + void set_deserialized(EMode mode, const std::vector> &volumes_and_instances); // Update the selection based on the new instance IDs. void instances_changed(const std::vector &instance_ids_selected); -- cgit v1.2.3 From b1420283b6a548b3a64a7d4129e37651f655562f Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Jul 2019 20:49:46 +0200 Subject: Fixed merge issues. --- src/slic3r/GUI/GUI_ObjectList.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index d47c84c37..4ef1cb0d2 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3400,5 +3400,13 @@ void ObjectList::recreate_object_list() m_prevent_list_events = false; } +ModelObject* ObjectList::object(const int obj_idx) const +{ + if (obj_idx < 0) + return nullptr; + + return (*m_objects)[obj_idx]; +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file -- cgit v1.2.3 From 4e2fda3315dcfcc9272b71e7c286585a71dca0a5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 5 Jul 2019 19:06:19 +0200 Subject: Undo / Redo fixes --- src/slic3r/GUI/GLCanvas3D.cpp | 3 ++- src/slic3r/GUI/GUI_ObjectList.cpp | 28 +++++++++++++++++++--------- src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 1 + src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 1 + src/slic3r/GUI/Plater.cpp | 10 ++-------- src/slic3r/GUI/Selection.cpp | 24 ++++++++++++++++++++++++ 7 files changed, 50 insertions(+), 19 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 43d419eea..1d5cec04a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2947,9 +2947,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) { m_regenerate_volumes = false; + wxGetApp().plater()->take_snapshot(_(L("Move Object"))); do_move(); wxGetApp().obj_manipul()->set_dirty(); - // Let the platter know that the dragging finished, so a delayed refresh + // Let the plater know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 4ef1cb0d2..582fe1007 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2116,7 +2116,7 @@ void ObjectList::part_selection_changed() panel.Thaw(); } -void ObjectList::add_object_to_list(size_t obj_idx) +void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) { auto model_object = (*m_objects)[obj_idx]; const wxString& item_name = from_u8(model_object->name); @@ -2137,7 +2137,9 @@ void ObjectList::add_object_to_list(size_t obj_idx) false); auto opt_keys = volume->config.keys(); if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { - select_item(m_objects_model->AddSettingsChild(vol_item)); + const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(vol_item); + if (call_selection_changed) + select_item(settings_item); Expand(vol_item); } } @@ -2151,7 +2153,9 @@ void ObjectList::add_object_to_list(size_t obj_idx) // add settings to the object, if it has those auto opt_keys = model_object->config.keys(); if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { - select_item(m_objects_model->AddSettingsChild(item)); + const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(item); + if (call_selection_changed) + select_item(settings_item); Expand(item); } @@ -2159,7 +2163,8 @@ void ObjectList::add_object_to_list(size_t obj_idx) add_layer_root_item(item); #ifndef __WXOSX__ - selection_changed(); + if (call_selection_changed) + selection_changed(); #endif //__WXMSW__ } @@ -2963,11 +2968,10 @@ void ObjectList::change_part_type() void ObjectList::last_volume_is_deleted(const int obj_idx) { - if (obj_idx < 0 || m_objects->empty() || - obj_idx <= m_objects->size() || - (*m_objects)[obj_idx]->volumes.empty()) + if (obj_idx < 0 || obj_idx >= m_objects->size() || (*m_objects)[obj_idx]->volumes.empty()) return; - auto volume = (*m_objects)[obj_idx]->volumes[0]; + + auto volume = (*m_objects)[obj_idx]->volumes.front(); // clear volume's config values volume->config.clear(); @@ -3388,14 +3392,20 @@ void ObjectList::recreate_object_list() m_prevent_list_events = true; m_prevent_canvas_selection_update = true; + // Unselect all objects before deleting them, so that no change of selection is emitted during deletion. + this->UnselectAll(); m_objects_model->DeleteAll(); size_t obj_idx = 0; while (obj_idx < m_objects->size()) { - add_object_to_list(obj_idx); + add_object_to_list(obj_idx, false); ++obj_idx; } +#ifndef __WXOSX__ + selection_changed(); +#endif /* __WXOSX__ */ + m_prevent_canvas_selection_update = false; m_prevent_list_events = false; } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 354f6c019..2a92ecbe4 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -261,7 +261,7 @@ public: void part_selection_changed(); // Add object to the list - void add_object_to_list(size_t obj_idx); + void add_object_to_list(size_t obj_idx, bool call_selection_changed = true); // Delete object from the list void delete_object_from_list(); void delete_object_from_list(const size_t obj_idx); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 372cd79ef..79e45facd 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -655,6 +655,7 @@ void ObjectManipulation::change_position_value(int axis, double value) Selection& selection = canvas->get_selection(); selection.start_dragging(); selection.translate(position - m_cache.position, selection.requires_local_axes()); + wxGetApp().plater()->take_snapshot(_(L("Set Position"))); canvas->do_move(); m_cache.position = position; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c7435636d..c8900d8da 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -673,6 +673,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { case Move: { + wxGetApp().plater()->take_snapshot(_(L("Move Object"))); canvas.disable_regenerate_volumes(); canvas.do_move(); break; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0865ab713..bb394ffcf 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1773,9 +1773,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event &evt) { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); - view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { - this->take_snapshot(_(L("Instance Moved"))); - update(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); }); @@ -1826,7 +1824,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // updates camera type from .ini file camera.set_type(get_config("use_perspective_camera")); - this->undo_redo_stack.initialize(model, view3D->get_canvas3d()->get_selection()); + // Initialize the Undo / Redo stack with a first snapshot. this->take_snapshot(_(L("New Project"))); } @@ -3196,8 +3194,6 @@ void Plater::priv::on_right_click(Vec2dEvent& evt) void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) { - this->take_snapshot(_(L("Wipe Tower Moved"))); - DynamicPrintConfig cfg; cfg.opt("wipe_tower_x", true)->value = evt.data(0); cfg.opt("wipe_tower_y", true)->value = evt.data(1); @@ -3206,8 +3202,6 @@ void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt) { - this->take_snapshot(_(L("Wipe Tower Rotated"))); - DynamicPrintConfig cfg; cfg.opt("wipe_tower_x", true)->value = evt.data(0); cfg.opt("wipe_tower_y", true)->value = evt.data(1); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2d5be01ff..a71005cf2 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -806,6 +806,8 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config) double s = std::min(sx, std::min(sy, sz)); if (s != 1.0) { + wxGetApp().plater()->take_snapshot(_(L("Scale To Fit"))); + TransformationType type; type.set_world(); type.set_relative(); @@ -2032,6 +2034,10 @@ bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const void Selection::paste_volumes_from_clipboard() { +#ifdef _DEBUG + check_model_ids_validity(*m_model); +#endif /* _DEBUG */ + int dst_obj_idx = get_object_idx(); if ((dst_obj_idx < 0) || ((int)m_model->objects.size() <= dst_obj_idx)) return; @@ -2073,6 +2079,9 @@ void Selection::paste_volumes_from_clipboard() } volumes.push_back(dst_volume); +#ifdef _DEBUG + check_model_ids_validity(*m_model); +#endif /* _DEBUG */ } // keeps relative position of multivolume selections @@ -2086,10 +2095,18 @@ void Selection::paste_volumes_from_clipboard() wxGetApp().obj_list()->paste_volumes_into_list(dst_obj_idx, volumes); } + +#ifdef _DEBUG + check_model_ids_validity(*m_model); +#endif /* _DEBUG */ } void Selection::paste_objects_from_clipboard() { +#ifdef _DEBUG + check_model_ids_validity(*m_model); +#endif /* _DEBUG */ + std::vector object_idxs; const ModelObjectPtrs& src_objects = m_clipboard.get_objects(); for (const ModelObject* src_object : src_objects) @@ -2103,9 +2120,16 @@ void Selection::paste_objects_from_clipboard() } object_idxs.push_back(m_model->objects.size() - 1); +#ifdef _DEBUG + check_model_ids_validity(*m_model); +#endif /* _DEBUG */ } wxGetApp().obj_list()->paste_objects_into_list(object_idxs); + +#ifdef _DEBUG + check_model_ids_validity(*m_model); +#endif /* _DEBUG */ } } // namespace GUI -- cgit v1.2.3 From 270fec84d330a931a523081a460369d9871dbd2b Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 5 Jul 2019 19:46:48 +0200 Subject: Fix of the Undo / Redo for Cut. Added some more operations (for example Rotation) to the Undo / Redo. --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 2 ++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 ++ src/slic3r/GUI/Plater.cpp | 5 +++-- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 79e45facd..ec5272a44 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -302,6 +302,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL); selection.synchronize_unselected_volumes(); // Copy rotation values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. + wxGetApp().plater()->take_snapshot(_(L("Set Rotation"))); canvas->do_rotate(); UpdateAndShow(true); @@ -687,6 +688,7 @@ void ObjectManipulation::change_rotation_value(int axis, double value) selection.rotate( (M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation), transformation_type); + wxGetApp().plater()->take_snapshot(_(L("Set Orientation"))); canvas->do_rotate(); m_cache.rotation = rotation; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c8900d8da..438cd1a10 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -600,6 +600,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) if (m_current == Flatten) { // Rotate the object so the normal points downward: + wxGetApp().plater()->take_snapshot(_(L("Place on Face"))); selection.flattening_rotate(get_flattening_normal()); canvas.do_flatten(); wxGetApp().obj_manipul()->set_dirty(); @@ -685,6 +686,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) } case Rotate: { + wxGetApp().plater()->take_snapshot(_(L("Rotate Object"))); canvas.do_rotate(); break; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bb394ffcf..aa7a54286 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2389,7 +2389,6 @@ void Plater::priv::deselect_all() void Plater::priv::remove(size_t obj_idx) { - this->take_snapshot(_(L("Remove Object"))); // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); @@ -2406,7 +2405,7 @@ void Plater::priv::remove(size_t obj_idx) void Plater::priv::delete_object_from_model(size_t obj_idx) { -// this->take_snapshot(_(L("Delete Object"))); // ys_FIXME What is the difference with "Remove Object"? + this->take_snapshot(_(L("Delete Object"))); model.delete_object(obj_idx); update(); object_list_changed(); @@ -2850,6 +2849,8 @@ void Plater::priv::update_sla_scene() void Plater::priv::reload_from_disk() { + this->take_snapshot(_(L("Reload from Disk"))); + const auto &selection = get_selection(); const auto obj_orig_idx = selection.get_object_idx(); if (selection.is_wipe_tower() || obj_orig_idx == -1) { return; } -- cgit v1.2.3 From fb725502b7a6f7fd645d83ab640e22e0581d413d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 5 Jul 2019 20:27:44 +0200 Subject: Undo / Redo: Bound Ctrl-V/Ctrl-Z to the side panel. --- src/slic3r/GUI/GUI_ObjectList.cpp | 26 ++++++++++++++++++++++---- src/slic3r/GUI/GUI_ObjectList.hpp | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 582fe1007..90c3f2665 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -143,20 +143,24 @@ ObjectList::ObjectList(wxWindow* parent) : // Bind(wxEVT_KEY_DOWN, &ObjectList::OnChar, this); { // Accelerators - wxAcceleratorEntry entries[6]; + wxAcceleratorEntry entries[8]; entries[0].Set(wxACCEL_CTRL, (int) 'C', wxID_COPY); entries[1].Set(wxACCEL_CTRL, (int) 'X', wxID_CUT); entries[2].Set(wxACCEL_CTRL, (int) 'V', wxID_PASTE); entries[3].Set(wxACCEL_CTRL, (int) 'A', wxID_SELECTALL); - entries[4].Set(wxACCEL_NORMAL, WXK_DELETE, wxID_DELETE); - entries[5].Set(wxACCEL_NORMAL, WXK_BACK, wxID_DELETE); - wxAcceleratorTable accel(6, entries); + entries[4].Set(wxACCEL_CTRL, (int) 'Z', wxID_UNDO); + entries[5].Set(wxACCEL_CTRL, (int) 'Y', wxID_REDO); + entries[6].Set(wxACCEL_NORMAL, WXK_DELETE, wxID_DELETE); + entries[7].Set(wxACCEL_NORMAL, WXK_BACK, wxID_DELETE); + wxAcceleratorTable accel(8, entries); SetAcceleratorTable(accel); this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->copy(); }, wxID_COPY); this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->paste(); }, wxID_PASTE); this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->select_item_all_children(); }, wxID_SELECTALL); this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->remove(); }, wxID_DELETE); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->undo(); }, wxID_UNDO); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->redo(); }, wxID_REDO); } #else __WXOSX__ Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX @@ -809,6 +813,16 @@ void ObjectList::paste() wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); } +void ObjectList::undo() +{ + wxGetApp().plater()->undo(); +} + +void ObjectList::redo() +{ + wxGetApp().plater()->redo(); +} + #ifndef __WXOSX__ void ObjectList::key_event(wxKeyEvent& event) { @@ -827,6 +841,10 @@ void ObjectList::key_event(wxKeyEvent& event) copy(); else if (wxGetKeyState(wxKeyCode('V')) && wxGetKeyState(WXK_CONTROL)) paste(); + else if (wxGetKeyState(wxKeyCode('Y')) && wxGetKeyState(WXK_CONTROL)) + redo(); + else if (wxGetKeyState(wxKeyCode('Z')) && wxGetKeyState(WXK_CONTROL)) + undo(); else event.Skip(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 2a92ecbe4..a5a9c2138 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -204,6 +204,8 @@ public: void copy(); void paste(); + void undo(); + void redo(); void get_settings_choice(const wxString& category_name); void get_freq_settings_choice(const wxString& bundle_name); -- cgit v1.2.3 From 25d916f144a868c28dc9c433b281d53f84afdd6b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Jul 2019 08:40:20 +0200 Subject: Color change time estimates --- src/slic3r/GUI/Plater.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 09ab91ef1..217937123 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1116,10 +1116,20 @@ void Sidebar::show_sliced_info_sizer(const bool show) if (ps.estimated_normal_print_time != "N/A") { new_label += wxString::Format("\n - %s", _(L("normal mode"))); info_text += wxString::Format("\n%s", ps.estimated_normal_print_time); + for (unsigned int i = 0; i < (unsigned int)ps.estimated_normal_color_print_times.size(); ++i) + { + new_label += wxString::Format("\n - %s%d", _(L("Color ")), i + 1); + info_text += wxString::Format("\n%s", ps.estimated_normal_color_print_times[i]); + } } if (ps.estimated_silent_print_time != "N/A") { new_label += wxString::Format("\n - %s", _(L("stealth mode"))); info_text += wxString::Format("\n%s", ps.estimated_silent_print_time); + for (unsigned int i = 0; i < (unsigned int)ps.estimated_normal_color_print_times.size(); ++i) + { + new_label += wxString::Format("\n - %s%d", _(L("Color ")), i + 1); + info_text += wxString::Format("\n%s", ps.estimated_normal_color_print_times[i]); + } } p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); } -- cgit v1.2.3 From 7b6229289d144d1f24feb53cda31973a64e34ff8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 8 Jul 2019 10:57:35 +0200 Subject: Added undo/redo to the "Edit" menu --- src/slic3r/GUI/MainFrame.cpp | 8 ++++++++ src/slic3r/GUI/Plater.cpp | 10 ++++++++++ src/slic3r/GUI/Plater.hpp | 2 ++ 3 files changed, 20 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d800f6f38..67b336a0e 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -502,6 +502,14 @@ void MainFrame::init_menubar() _(L("Deletes all objects")), [this](wxCommandEvent&) { m_plater->reset_with_confirm(); }, menu_icon("delete_all_menu"), nullptr, [this](){return can_delete_all(); }, this); + editMenu->AppendSeparator(); + append_menu_item(editMenu, wxID_ANY, _(L("&Undo")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "Z", + _(L("Undo")), [this](wxCommandEvent&) { m_plater->undo(); }, + "undo", nullptr, [this](){return m_plater->can_undo(); }, this); + append_menu_item(editMenu, wxID_ANY, _(L("&Redo")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "Y", + _(L("Redo")), [this](wxCommandEvent&) { m_plater->redo(); }, + "undo", nullptr, [this](){return m_plater->can_redo(); }, this); + editMenu->AppendSeparator(); append_menu_item(editMenu, wxID_ANY, _(L("&Copy")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "C", _(L("Copy selection to clipboard")), [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index aa7a54286..6ac58eb84 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4405,6 +4405,16 @@ bool Plater::can_copy_to_clipboard() const return true; } +bool Plater::can_undo() const +{ + return p->undo_redo_stack.has_undo_snapshot(); +} + +bool Plater::can_redo() const +{ + return p->undo_redo_stack.has_redo_snapshot(); +} + SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() : m_was_running(wxGetApp().plater()->is_background_process_running()) { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index d38957b3a..0be465f53 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -222,6 +222,8 @@ public: bool can_layers_editing() const; bool can_paste_from_clipboard() const; bool can_copy_to_clipboard() const; + bool can_undo() const; + bool can_redo() const; void msw_rescale(); -- cgit v1.2.3 From 4ba7dfb6ddb6aa92456088184862a8ad1e2c7222 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Jul 2019 15:30:59 +0200 Subject: Refactoring of functions thick_lines_to_indexed_vertex_array() to reduce the amount of produced vertices while reducing visual artifacts in gcode toolpaths due to averaged normals --- src/slic3r/GUI/3DScene.cpp | 27 ++++++++++++++++++++++----- src/slic3r/GUI/3DScene.hpp | 2 -- src/slic3r/GUI/GLCanvas3D.cpp | 6 ------ 3 files changed, 22 insertions(+), 13 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index fe0cd9ffb..c49c7c9ca 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -849,6 +849,7 @@ static void thick_lines_to_indexed_vertex_array( int idx_initial[4] = { -1, -1, -1, -1 }; double width_initial = 0.; double bottom_z_initial = 0.0; + double len_prev = 0.0; // loop once more in case of closed loops size_t lines_end = closed ? (lines.size() + 1) : lines.size(); @@ -864,6 +865,7 @@ static void thick_lines_to_indexed_vertex_array( bool is_closing = closed && is_last; Vec2d v = unscale(line.vector()).normalized(); + double len = unscale(line.length()); Vec2d a = unscale(line.a); Vec2d b = unscale(line.b); @@ -927,7 +929,14 @@ static void thick_lines_to_indexed_vertex_array( // Continuing a previous segment. // Share left / right vertices if possible. double v_dot = v_prev.dot(v); - bool sharp = v_dot < 0.9999; // v_dot < 0.9999; // cos(1 degree) + // To reduce gpu memory usage, we try to reuse vertices + // To reduce the visual artifacts, due to averaged normals, we allow to reuse vertices only when any of two adjacent edges + // is longer than a fixed threshold. + // The following value is arbitrary, it comes from tests made on a bunch of models showing the visual artifacts + double len_threshold = 2.5; + + // Generate new vertices if the angle between adjacent edges is greater than 45 degrees or thresholds conditions are met + bool sharp = (v_dot < 0.707) || (len_prev > len_threshold) || (len > len_threshold); if (sharp) { if (!bottom_z_different) { @@ -1003,6 +1012,7 @@ static void thick_lines_to_indexed_vertex_array( bottom_z_prev = bottom_z; b1_prev = b1; v_prev = v; + len_prev = len; if (bottom_z_different && (closed || (!is_first && !is_last))) { @@ -1056,6 +1066,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, int idx_initial[4] = { -1, -1, -1, -1 }; int idx_prev[4] = { -1, -1, -1, -1 }; double z_prev = 0.0; + double len_prev = 0.0; Vec3d n_right_prev = Vec3d::Zero(); Vec3d n_top_prev = Vec3d::Zero(); Vec3d unit_v_prev = Vec3d::Zero(); @@ -1077,6 +1088,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, double width = widths[i]; Vec3d unit_v = unscale(line.vector()).normalized(); + double len = unscale(line.length()); Vec3d n_top = Vec3d::Zero(); Vec3d n_right = Vec3d::Zero(); @@ -1153,9 +1165,16 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, // Continuing a previous segment. // Share left / right vertices if possible. double v_dot = unit_v_prev.dot(unit_v); - bool is_sharp = v_dot < 0.9999; // v_dot < 0.9999; // cos(1 degree) bool is_right_turn = n_top_prev.dot(unit_v_prev.cross(unit_v)) > 0.0; + // To reduce gpu memory usage, we try to reuse vertices + // To reduce the visual artifacts, due to averaged normals, we allow to reuse vertices only when any of two adjacent edges + // is longer than a fixed threshold. + // The following value is arbitrary, it comes from tests made on a bunch of models showing the visual artifacts + double len_threshold = 2.5; + + // Generate new vertices if the angle between adjacent edges is greater than 45 degrees or thresholds conditions are met + bool is_sharp = (v_dot < 0.707) || (len_prev > len_threshold) || (len > len_threshold); if (is_sharp) { // Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn. @@ -1234,6 +1253,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines, n_right_prev = n_right; n_top_prev = n_top; unit_v_prev = unit_v; + len_prev = len; if (!closed) { @@ -1495,9 +1515,6 @@ void GLModel::set_scale(const Vec3d& scale) void GLModel::reset() { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// m_volume.release_geometry(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_filename = ""; } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index bb629a1d8..50821a6ca 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -74,9 +74,7 @@ public: quad_indices_VBO_id(0) {} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ~GLIndexedVertexArray() { release_geometry(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLIndexedVertexArray& operator=(const GLIndexedVertexArray &rhs) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 77c755538..d15d9aa4d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1356,9 +1356,6 @@ void GLCanvas3D::reset_volumes() if (!m_volumes.empty()) { m_selection.clear(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// m_volumes.release_geometry(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_volumes.clear(); m_dirty = true; } @@ -1920,9 +1917,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re assert(volume_idx_wipe_tower_old == -1); volume_idx_wipe_tower_old = (int)volume_id; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// volume->release_geometry(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (! m_reload_delayed) delete volume; } else { -- cgit v1.2.3 From fbf14b42e9831b5fc99be555668e126df37f9d58 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 8 Jul 2019 18:01:14 +0200 Subject: Added undo/redo icons. Fist step to implementation Undo/Redo list for toolbar --- src/slic3r/GUI/GLCanvas3D.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GLToolbar.cpp | 4 +++ src/slic3r/GUI/GLToolbar.hpp | 7 +++++ src/slic3r/GUI/ImGuiWrapper.cpp | 21 +++++++++++++++ src/slic3r/GUI/ImGuiWrapper.hpp | 1 + src/slic3r/GUI/MainFrame.cpp | 2 +- 6 files changed, 92 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1d5cec04a..970b349cb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3618,6 +3618,64 @@ bool GLCanvas3D::_init_toolbar() if (!m_toolbar.add_item(item)) return false; + if (!m_toolbar.add_separator()) + return false; + + item.name = "undo"; +#if ENABLE_SVG_ICONS + item.icon_filename = "undo_toolbar.svg"; +#endif // ENABLE_SVG_ICONS + item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; + item.sprite_id = 11; + item.action_callback = [this]() + { + if (m_canvas != nullptr) { + wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO)); + m_toolbar.set_imgui_visible(); + } + }; + item.visibility_callback = []()->bool { return true; }; + item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_undo(); }; + item.render_callback = [this]() + { + if (m_canvas != nullptr && m_toolbar.get_imgui_visible()) { + ImGuiWrapper* imgui = wxGetApp().imgui(); + + const float approx_height = m_toolbar.get_height(); + imgui->set_next_window_pos(600, approx_height, ImGuiCond_Always); + + imgui->set_next_window_bg_alpha(0.5f); + imgui->begin(_(L("Undo Stack")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + + std::vector undo_stack = {"A", "B", "C", "D","A", "B", "C", "D","A", "B", "C", "D",}; + int sel = 4; + imgui->multi_sel_list("", undo_stack, sel); + + const bool undo_clicked = imgui->button(_(L("Undo N Action"))); + + imgui->end(); + if (undo_clicked) + m_toolbar.set_imgui_visible(false); + } + }; + if (!m_toolbar.add_item(item)) + return false; + + item.name = "redo"; +#if ENABLE_SVG_ICONS + item.icon_filename = "redo_toolbar.svg"; +#endif // ENABLE_SVG_ICONS + item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; + item.sprite_id = 12; + item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); }; + item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_redo(); }; + item.render_callback = []() {}; + if (!m_toolbar.add_item(item)) + return false; + + if (!m_toolbar.add_separator()) + return false; + return true; } diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index f8082ad7e..a851e3a4c 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -35,6 +35,7 @@ wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent); const GLToolbarItem::ActionCallback GLToolbarItem::Default_Action_Callback = [](){}; const GLToolbarItem::VisibilityCallback GLToolbarItem::Default_Visibility_Callback = []()->bool { return true; }; const GLToolbarItem::EnabledStateCallback GLToolbarItem::Default_Enabled_State_Callback = []()->bool { return true; }; +const GLToolbarItem::RenderCallback GLToolbarItem::Default_Render_Callback = [](){}; GLToolbarItem::Data::Data() : name("") @@ -48,6 +49,7 @@ GLToolbarItem::Data::Data() , action_callback(Default_Action_Callback) , visibility_callback(Default_Visibility_Callback) , enabled_state_callback(Default_Enabled_State_Callback) + , render_callback(Default_Render_Callback) { } @@ -81,6 +83,8 @@ bool GLToolbarItem::update_enabled_state() void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const { GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); + + m_data.render_callback(); } GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 24314d60f..aa68fae38 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -37,6 +37,7 @@ public: typedef std::function ActionCallback; typedef std::function VisibilityCallback; typedef std::function EnabledStateCallback; + typedef std::function RenderCallback; enum EType : unsigned char { @@ -68,6 +69,7 @@ public: ActionCallback action_callback; VisibilityCallback visibility_callback; EnabledStateCallback enabled_state_callback; + RenderCallback render_callback; Data(); }; @@ -75,6 +77,7 @@ public: static const ActionCallback Default_Action_Callback; static const VisibilityCallback Default_Visibility_Callback; static const EnabledStateCallback Default_Enabled_State_Callback; + static const RenderCallback Default_Render_Callback; private: EType m_type; @@ -249,6 +252,7 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; + bool m_imgui_visible {false}; public: #if ENABLE_SVG_ICONS @@ -305,6 +309,9 @@ public: bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); + void set_imgui_visible(bool visible = true) { m_imgui_visible = visible; } + bool get_imgui_visible() { return m_imgui_visible; } + private: void calc_layout() const; float get_width_horizontal() const; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index b6abf641a..cbcf33f77 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -342,6 +342,27 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector& return res; } +// Getter for the const char*[] +static bool StringGetter(void* data, int i, const char** out_text) +{ + const std::vector* v = (std::vector*)data; + if (out_text) + *out_text = (*v)[i].c_str(); + return true; +} + +bool ImGuiWrapper::multi_sel_list(const wxString& label, const std::vector& options, int& selection) +{ + // this is to force the label to the left of the widget: + if (!label.IsEmpty()) + text(label); + + bool res = false; + ImGui::ListBox("", &selection, StringGetter, (void*)&options, (int)options.size()); + + return res; +} + void ImGuiWrapper::disabled_begin(bool disabled) { wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call"); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 0479e4743..42c562b72 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -67,6 +67,7 @@ public: void text(const std::string &label); void text(const wxString &label); bool combo(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected + bool multi_sel_list(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected void disabled_begin(bool disabled); void disabled_end(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 67b336a0e..cca6e02e6 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -508,7 +508,7 @@ void MainFrame::init_menubar() "undo", nullptr, [this](){return m_plater->can_undo(); }, this); append_menu_item(editMenu, wxID_ANY, _(L("&Redo")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "Y", _(L("Redo")), [this](wxCommandEvent&) { m_plater->redo(); }, - "undo", nullptr, [this](){return m_plater->can_redo(); }, this); + "redo", nullptr, [this](){return m_plater->can_redo(); }, this); editMenu->AppendSeparator(); append_menu_item(editMenu, wxID_ANY, _(L("&Copy")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "C", -- cgit v1.2.3 From 36049788acc8ae888d4e8df65f89b6708c2455bb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 9 Jul 2019 08:24:23 +0200 Subject: Fixed reset of bed 3d model --- src/slic3r/GUI/3DScene.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c49c7c9ca..9e3eaf41d 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1515,6 +1515,7 @@ void GLModel::set_scale(const Vec3d& scale) void GLModel::reset() { + m_volume.indexed_vertex_array.release_geometry(); m_filename = ""; } -- cgit v1.2.3 From d4914441f3dc5038c1599fb92561502d260d05ab Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 9 Jul 2019 10:18:57 +0200 Subject: Modified logic to add snapshots to undo/redo stack using GLCanvas::do_xxxxxx() methods --- src/slic3r/GUI/GLCanvas3D.cpp | 41 ++++++++++++++++++++++++------- src/slic3r/GUI/GLCanvas3D.hpp | 11 +++++---- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 14 ++++------- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 12 +++------ src/slic3r/GUI/Selection.cpp | 6 ++--- 5 files changed, 50 insertions(+), 34 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1d5cec04a..7a2e5345d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1799,7 +1799,7 @@ std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) void GLCanvas3D::mirror_selection(Axis axis) { m_selection.mirror(axis); - do_mirror(); + do_mirror("Mirror Object"); wxGetApp().obj_manipul()->set_dirty(); } @@ -2947,8 +2947,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) { m_regenerate_volumes = false; - wxGetApp().plater()->take_snapshot(_(L("Move Object"))); - do_move(); + do_move("Move Object"); wxGetApp().obj_manipul()->set_dirty(); // Let the plater know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. @@ -3107,11 +3106,14 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) const } -void GLCanvas3D::do_move() +void GLCanvas3D::do_move(const std::string& snapshot_type) { if (m_model == nullptr) return; + if (!snapshot_type.empty()) + wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + std::set> done; // keeps track of modified instances bool object_moved = false; Vec3d wipe_tower_origin = Vec3d::Zero(); @@ -3162,13 +3164,18 @@ void GLCanvas3D::do_move() if (wipe_tower_origin != Vec3d::Zero()) post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_MOVED, std::move(wipe_tower_origin))); + + m_dirty = true; } -void GLCanvas3D::do_rotate() +void GLCanvas3D::do_rotate(const std::string& snapshot_type) { if (m_model == nullptr) return; + if (!snapshot_type.empty()) + wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + std::set> done; // keeps track of modified instances Selection::EMode selection_mode = m_selection.get_mode(); @@ -3217,13 +3224,18 @@ void GLCanvas3D::do_rotate() if (!done.empty()) post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_ROTATED)); + + m_dirty = true; } -void GLCanvas3D::do_scale() +void GLCanvas3D::do_scale(const std::string& snapshot_type) { if (m_model == nullptr) return; + if (!snapshot_type.empty()) + wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + std::set> done; // keeps track of modified instances Selection::EMode selection_mode = m_selection.get_mode(); @@ -3269,18 +3281,27 @@ void GLCanvas3D::do_scale() if (!done.empty()) post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_ROTATED)); + + m_dirty = true; } -void GLCanvas3D::do_flatten() +void GLCanvas3D::do_flatten(const Vec3d& normal, const std::string& snapshot_type) { - do_rotate(); + if (!snapshot_type.empty()) + wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + + m_selection.flattening_rotate(normal); + do_rotate(""); // avoid taking another snapshot } -void GLCanvas3D::do_mirror() +void GLCanvas3D::do_mirror(const std::string& snapshot_type) { if (m_model == nullptr) return; + if (!snapshot_type.empty()) + wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + std::set> done; // keeps track of modified instances Selection::EMode selection_mode = m_selection.get_mode(); @@ -3319,6 +3340,8 @@ void GLCanvas3D::do_mirror() } post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); + + m_dirty = true; } void GLCanvas3D::set_camera_zoom(double zoom) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 47b1c5ec2..c1b6dce14 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -599,11 +599,12 @@ public: void set_tooltip(const std::string& tooltip) const; - void do_move(); - void do_rotate(); - void do_scale(); - void do_flatten(); - void do_mirror(); + // the following methods add a snapshot to the undo/redo stack, unless the given string is empty + void do_move(const std::string& snapshot_type); + void do_rotate(const std::string& snapshot_type); + void do_scale(const std::string& snapshot_type); + void do_flatten(const Vec3d& normal, const std::string& snapshot_type); + void do_mirror(const std::string& snapshot_type); void set_camera_zoom(double zoom); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index ec5272a44..787c92451 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -220,8 +220,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL); selection.synchronize_unselected_volumes(); // Copy mirroring values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. - canvas->do_mirror(); - canvas->set_as_dirty(); + canvas->do_mirror("Set Mirror"); UpdateAndShow(true); }); return sizer; @@ -302,8 +301,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL); selection.synchronize_unselected_volumes(); // Copy rotation values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. - wxGetApp().plater()->take_snapshot(_(L("Set Rotation"))); - canvas->do_rotate(); + canvas->do_rotate("Set Rotation"); UpdateAndShow(true); }); @@ -656,8 +654,7 @@ void ObjectManipulation::change_position_value(int axis, double value) Selection& selection = canvas->get_selection(); selection.start_dragging(); selection.translate(position - m_cache.position, selection.requires_local_axes()); - wxGetApp().plater()->take_snapshot(_(L("Set Position"))); - canvas->do_move(); + canvas->do_move("Set Position"); m_cache.position = position; m_cache.position_rounded(axis) = DBL_MAX; @@ -688,8 +685,7 @@ void ObjectManipulation::change_rotation_value(int axis, double value) selection.rotate( (M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation), transformation_type); - wxGetApp().plater()->take_snapshot(_(L("Set Orientation"))); - canvas->do_rotate(); + canvas->do_rotate("Set Orientation"); m_cache.rotation = rotation; m_cache.rotation_rounded(axis) = DBL_MAX; @@ -754,7 +750,7 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const selection.start_dragging(); selection.scale(scaling_factor * 0.01, transformation_type); - wxGetApp().plater()->canvas3D()->do_scale(); + wxGetApp().plater()->canvas3D()->do_scale("Set Scale"); } void ObjectManipulation::on_change(t_config_option_key opt_key, const boost::any& value) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 438cd1a10..23f3cc6c3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -600,9 +600,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) if (m_current == Flatten) { // Rotate the object so the normal points downward: - wxGetApp().plater()->take_snapshot(_(L("Place on Face"))); - selection.flattening_rotate(get_flattening_normal()); - canvas.do_flatten(); + canvas.do_flatten(get_flattening_normal(), "Place on Face"); wxGetApp().obj_manipul()->set_dirty(); } @@ -674,20 +672,18 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { case Move: { - wxGetApp().plater()->take_snapshot(_(L("Move Object"))); canvas.disable_regenerate_volumes(); - canvas.do_move(); + canvas.do_move("Gizmo-Move Object"); break; } case Scale: { - canvas.do_scale(); + canvas.do_scale("Gizmo-Scale Object"); break; } case Rotate: { - wxGetApp().plater()->take_snapshot(_(L("Rotate Object"))); - canvas.do_rotate(); + canvas.do_rotate("Gizmo-Rotate Object"); break; } default: diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index a71005cf2..997146546 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -806,7 +806,7 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config) double s = std::min(sx, std::min(sy, sz)); if (s != 1.0) { - wxGetApp().plater()->take_snapshot(_(L("Scale To Fit"))); + wxGetApp().plater()->take_snapshot(_(L("Scale To Fit"))); TransformationType type; type.set_world(); @@ -816,12 +816,12 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config) // apply scale start_dragging(); scale(s * Vec3d::Ones(), type); - wxGetApp().plater()->canvas3D()->do_scale(); + wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot // center selection on print bed start_dragging(); translate(print_volume.center() - get_bounding_box().center()); - wxGetApp().plater()->canvas3D()->do_move(); + wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot wxGetApp().obj_manipul()->set_dirty(); } -- cgit v1.2.3 From 52dc8547aca48764b4c40bbb020dcfaafaedaa72 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 9 Jul 2019 15:08:34 +0200 Subject: Reverder order of rendering of color print time estimates --- src/slic3r/GUI/Plater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7ba9e585a..dee78aef7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1132,7 +1132,7 @@ void Sidebar::show_sliced_info_sizer(const bool show) if (ps.estimated_normal_print_time != "N/A") { new_label += wxString::Format("\n - %s", _(L("normal mode"))); info_text += wxString::Format("\n%s", ps.estimated_normal_print_time); - for (unsigned int i = 0; i < (unsigned int)ps.estimated_normal_color_print_times.size(); ++i) + for (int i = (int)ps.estimated_normal_color_print_times.size() - 1; i >= 0; --i) { new_label += wxString::Format("\n - %s%d", _(L("Color ")), i + 1); info_text += wxString::Format("\n%s", ps.estimated_normal_color_print_times[i]); @@ -1141,7 +1141,7 @@ void Sidebar::show_sliced_info_sizer(const bool show) if (ps.estimated_silent_print_time != "N/A") { new_label += wxString::Format("\n - %s", _(L("stealth mode"))); info_text += wxString::Format("\n%s", ps.estimated_silent_print_time); - for (unsigned int i = 0; i < (unsigned int)ps.estimated_normal_color_print_times.size(); ++i) + for (int i = (int)ps.estimated_normal_color_print_times.size() - 1; i >= 0; --i) { new_label += wxString::Format("\n - %s%d", _(L("Color ")), i + 1); info_text += wxString::Format("\n%s", ps.estimated_normal_color_print_times[i]); -- cgit v1.2.3 From 1347e655c21ec665621e0929373e5e211b5610a4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 9 Jul 2019 15:27:28 +0200 Subject: Next improvements of an undo/redo from a toolbar --- src/slic3r/GUI/GLCanvas3D.cpp | 84 ++++++++++++++++++++++++++--------------- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GLToolbar.cpp | 4 +- src/slic3r/GUI/GLToolbar.hpp | 24 ++++++++++-- src/slic3r/GUI/ImGuiWrapper.cpp | 35 +++++++++-------- src/slic3r/GUI/ImGuiWrapper.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 15 ++++++++ src/slic3r/GUI/Plater.hpp | 1 + 8 files changed, 113 insertions(+), 53 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 970b349cb..e362cf74d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3442,6 +3442,41 @@ bool GLCanvas3D::_is_shown_on_screen() const return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; } +// Getter for the const char*[] +static bool string_getter(const bool is_undo, int idx, const char** out_text) +{ + return wxGetApp().plater()->undo_redo_string_getter(is_undo, idx, out_text); +} + +void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) +{ + if (m_canvas != nullptr && m_toolbar.get_imgui_visible(is_undo)) + { + const wxString& stack_name = _(is_undo ? L("Undo") : L("Redo")); + ImGuiWrapper* imgui = wxGetApp().imgui(); + + const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); + imgui->set_next_window_pos(x, m_toolbar.get_height(), ImGuiCond_Always); + + imgui->set_next_window_bg_alpha(0.5f); + imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + + int hovered = m_toolbar.get_imgui_hovered_pos(); + int selected = -1; + const float em = static_cast(wxGetApp().em_unit()); + + if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) + m_toolbar.set_imgui_hovered_pos(hovered); + if (selected >= 0) + m_toolbar.hide_imgui(is_undo); + + imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1)); + + imgui->end(); + } +} + bool GLCanvas3D::_init_toolbar() { if (!m_toolbar.is_enabled()) @@ -3627,37 +3662,19 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; - item.action_callback = [this]() - { + item.is_toggable = false; + item.action_callback = [this]() { if (m_canvas != nullptr) { wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO)); - m_toolbar.set_imgui_visible(); + m_toolbar.activate_imgui(true); } }; item.visibility_callback = []()->bool { return true; }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_undo(); }; - item.render_callback = [this]() - { - if (m_canvas != nullptr && m_toolbar.get_imgui_visible()) { - ImGuiWrapper* imgui = wxGetApp().imgui(); - - const float approx_height = m_toolbar.get_height(); - imgui->set_next_window_pos(600, approx_height, ImGuiCond_Always); - - imgui->set_next_window_bg_alpha(0.5f); - imgui->begin(_(L("Undo Stack")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - - std::vector undo_stack = {"A", "B", "C", "D","A", "B", "C", "D","A", "B", "C", "D",}; - int sel = 4; - imgui->multi_sel_list("", undo_stack, sel); - - const bool undo_clicked = imgui->button(_(L("Undo N Action"))); - - imgui->end(); - if (undo_clicked) - m_toolbar.set_imgui_visible(false); - } + item.enabled_state_callback = [this]()->bool { + if (!wxGetApp().plater()->can_undo()) { m_toolbar.hide_imgui(true); return false; } + return true; }; + item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(true, pos_x); }; if (!m_toolbar.add_item(item)) return false; @@ -3667,15 +3684,20 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_redo(); }; - item.render_callback = []() {}; + item.action_callback = [this]() { + if (m_canvas != nullptr) { + wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); + m_toolbar.activate_imgui(false); + } + }; + item.enabled_state_callback = [this]()->bool { + if (!wxGetApp().plater()->can_redo()) { m_toolbar.hide_imgui(false); return false; } + return true; + }; + item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(false, pos_x); }; if (!m_toolbar.add_item(item)) return false; - if (!m_toolbar.add_separator()) - return false; - return true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 47b1c5ec2..4867f94ce 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -676,6 +676,7 @@ private: #endif // ENABLE_SHOW_CAMERA_TARGET void _render_sla_slices() const; void _render_selection_sidebar_hints() const; + void _render_undo_redo_stack(const bool is_undo, float pos_x); void _update_volumes_hover_state() const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index a851e3a4c..f6140464b 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -35,7 +35,7 @@ wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent); const GLToolbarItem::ActionCallback GLToolbarItem::Default_Action_Callback = [](){}; const GLToolbarItem::VisibilityCallback GLToolbarItem::Default_Visibility_Callback = []()->bool { return true; }; const GLToolbarItem::EnabledStateCallback GLToolbarItem::Default_Enabled_State_Callback = []()->bool { return true; }; -const GLToolbarItem::RenderCallback GLToolbarItem::Default_Render_Callback = [](){}; +const GLToolbarItem::RenderCallback GLToolbarItem::Default_Render_Callback = [](float, float, float, float){}; GLToolbarItem::Data::Data() : name("") @@ -84,7 +84,7 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b { GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); - m_data.render_callback(); + m_data.render_callback(left, right, bottom, top); } GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index aa68fae38..e32e4a41e 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -37,7 +37,7 @@ public: typedef std::function ActionCallback; typedef std::function VisibilityCallback; typedef std::function EnabledStateCallback; - typedef std::function RenderCallback; + typedef std::function RenderCallback; enum EType : unsigned char { @@ -252,7 +252,10 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; - bool m_imgui_visible {false}; + bool m_undo_imgui_visible {false}; + bool m_redo_imgui_visible {false}; + int m_imgui_hovered_pos { -1 }; + int m_imgui_selected_pos { -1 }; public: #if ENABLE_SVG_ICONS @@ -309,8 +312,21 @@ public: bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); - void set_imgui_visible(bool visible = true) { m_imgui_visible = visible; } - bool get_imgui_visible() { return m_imgui_visible; } + // undo == true => "undo" imgui is activated + // undo == false => "redo" imgui is activated + bool get_imgui_visible(const bool undo) const { return undo ? m_undo_imgui_visible : m_redo_imgui_visible; } + void hide_imgui(const bool undo) { undo ? m_undo_imgui_visible = false : m_redo_imgui_visible = false; } + void activate_imgui(const bool undo) { + m_undo_imgui_visible = undo; + m_redo_imgui_visible = !undo; + m_imgui_hovered_pos = m_imgui_selected_pos = -1; + } + + void set_imgui_hovered_pos(int pos = -1) { m_imgui_hovered_pos = pos; } + int get_imgui_hovered_pos() const { return m_imgui_hovered_pos; } + + void set_imgui_selected_pos(int pos = -1) { m_imgui_selected_pos = pos; } + int get_imgui_selected_pos() const { return m_imgui_selected_pos; } private: void calc_layout() const; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index cbcf33f77..7f4a6c10c 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -342,25 +342,30 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector& return res; } -// Getter for the const char*[] -static bool StringGetter(void* data, int i, const char** out_text) +bool ImGuiWrapper::undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool , int , const char**), int& hovered, int& selected) { - const std::vector* v = (std::vector*)data; - if (out_text) - *out_text = (*v)[i].c_str(); - return true; -} + bool is_hovered = false; + ImGui::ListBoxHeader("", size); -bool ImGuiWrapper::multi_sel_list(const wxString& label, const std::vector& options, int& selection) -{ - // this is to force the label to the left of the widget: - if (!label.IsEmpty()) - text(label); + int i=0; + const char* item_text; + while (items_getter(is_undo, i, &item_text)) + { + ImGui::Selectable(item_text, i < hovered); - bool res = false; - ImGui::ListBox("", &selection, StringGetter, (void*)&options, (int)options.size()); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip(item_text); + hovered = i; + is_hovered = true; + } - return res; + if (ImGui::IsItemClicked()) + selected = i; + i++; + } + + ImGui::ListBoxFooter(); + return is_hovered; } void ImGuiWrapper::disabled_begin(bool disabled) diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 42c562b72..a18b15184 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -67,7 +67,7 @@ public: void text(const std::string &label); void text(const wxString &label); bool combo(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected - bool multi_sel_list(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected + bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected); void disabled_begin(bool disabled); void disabled_end(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6ac58eb84..3dfc1d1b8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4110,6 +4110,21 @@ void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot( void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::undo() { p->undo(); } void Plater::redo() { p->redo(); } +bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** out_text) +{ + const size_t& active_snapshot_time = p->undo_redo_stack.active_snapshot_time(); + const std::vector& ss_stack = p->undo_redo_stack.snapshots(); + const auto it = std::lower_bound(ss_stack.begin(), ss_stack.end(), UndoRedo::Snapshot(active_snapshot_time)); + + const int idx_in_ss_stack = it - ss_stack.begin() + (is_undo ? -(++idx) : idx); + + if (0 < idx_in_ss_stack && idx_in_ss_stack < ss_stack.size() - 1) { + *out_text = ss_stack[idx_in_ss_stack].name.c_str(); + return true; + } + + return false; +} void Plater::on_extruders_change(int num_extruders) { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 0be465f53..7f379c638 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -187,6 +187,7 @@ public: void take_snapshot(const wxString &snapshot_name); void undo(); void redo(); + bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text); void on_extruders_change(int extruders_count); void on_config_change(const DynamicPrintConfig &config); -- cgit v1.2.3 From f985f5190c8260b28b1a3d06d20138ee16113dad Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 9 Jul 2019 20:45:00 +0200 Subject: Completed undo/redo from a toolbar --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 48 +++++++++++++++++++++++++++++++++++++++---- src/slic3r/GUI/Plater.hpp | 2 ++ 3 files changed, 47 insertions(+), 5 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index dc59f4e5b..d87b97f53 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3492,7 +3492,7 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) m_toolbar.set_imgui_hovered_pos(hovered); if (selected >= 0) - m_toolbar.hide_imgui(is_undo); + is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1)); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3dfc1d1b8..a450ac0e5 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1583,8 +1583,11 @@ struct Plater::priv void take_snapshot(const std::string& snapshot_name) { this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); } void take_snapshot(const wxString& snapshot_name) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data())); } + int get_active_snapshot_index(); void undo(); void redo(); + void undo_to(size_t time_to_load); + void redo_to(size_t time_to_load); bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } void update_print_volume_state(); @@ -3560,6 +3563,14 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const } } +int Plater::priv::get_active_snapshot_index() +{ + const size_t& active_snapshot_time = this->undo_redo_stack.active_snapshot_time(); + const std::vector& ss_stack = this->undo_redo_stack.snapshots(); + const auto it = std::lower_bound(ss_stack.begin(), ss_stack.end(), UndoRedo::Snapshot(active_snapshot_time)); + return it - ss_stack.begin(); +} + void Plater::priv::undo() { if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection())) @@ -3572,6 +3583,18 @@ void Plater::priv::redo() this->update_after_undo_redo(); } +void Plater::priv::undo_to(size_t time_to_load) +{ + if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection(), time_to_load)) + this->update_after_undo_redo(); +} + +void Plater::priv::redo_to(size_t time_to_load) +{ + if (this->undo_redo_stack.redo(model, time_to_load)) + this->update_after_undo_redo(); +} + void Plater::priv::update_after_undo_redo() { this->view3D->get_canvas3d()->get_selection().clear(); @@ -4110,13 +4133,30 @@ void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot( void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::undo() { p->undo(); } void Plater::redo() { p->redo(); } +void Plater::undo_to(int selection) +{ + if (selection == 0) { + p->undo(); + return; + } + + const int idx = p->get_active_snapshot_index() - selection - 1; + p->undo_to(p->undo_redo_stack.snapshots()[idx].timestamp); +} +void Plater::redo_to(int selection) +{ + if (selection == 0) { + p->redo(); + return; + } + + const int idx = selection + p->get_active_snapshot_index(); + p->redo_to(p->undo_redo_stack.snapshots()[idx].timestamp); +} bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** out_text) { - const size_t& active_snapshot_time = p->undo_redo_stack.active_snapshot_time(); const std::vector& ss_stack = p->undo_redo_stack.snapshots(); - const auto it = std::lower_bound(ss_stack.begin(), ss_stack.end(), UndoRedo::Snapshot(active_snapshot_time)); - - const int idx_in_ss_stack = it - ss_stack.begin() + (is_undo ? -(++idx) : idx); + const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -(++idx) : idx); if (0 < idx_in_ss_stack && idx_in_ss_stack < ss_stack.size() - 1) { *out_text = ss_stack[idx_in_ss_stack].name.c_str(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7f379c638..ca3d59224 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -187,6 +187,8 @@ public: void take_snapshot(const wxString &snapshot_name); void undo(); void redo(); + void undo_to(int selection); + void redo_to(int selection); bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text); void on_extruders_change(int extruders_count); -- cgit v1.2.3 From 3720e6a3a3ec59fca0f8781139e5d329156f81e6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 10 Jul 2019 10:15:07 +0200 Subject: Fixed redo_to() function and code cleaning from redundant options --- src/slic3r/GUI/GLCanvas3D.cpp | 66 ++++++++++++++++--------------------------- src/slic3r/GUI/GLToolbar.cpp | 3 +- src/slic3r/GUI/GLToolbar.hpp | 16 ----------- src/slic3r/GUI/Plater.cpp | 2 +- 4 files changed, 27 insertions(+), 60 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d87b97f53..4fa5b8b27 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3473,31 +3473,31 @@ static bool string_getter(const bool is_undo, int idx, const char** out_text) void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) { - if (m_canvas != nullptr && m_toolbar.get_imgui_visible(is_undo)) - { - const wxString& stack_name = _(is_undo ? L("Undo") : L("Redo")); - ImGuiWrapper* imgui = wxGetApp().imgui(); + const wxString& stack_name = _(is_undo ? L("Undo") : L("Redo")); + ImGuiWrapper* imgui = wxGetApp().imgui(); + + const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); + imgui->set_next_window_pos(x, m_toolbar.get_height(), ImGuiCond_Always); - const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); - imgui->set_next_window_pos(x, m_toolbar.get_height(), ImGuiCond_Always); + imgui->set_next_window_bg_alpha(0.5f); + imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - imgui->set_next_window_bg_alpha(0.5f); - imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + int hovered = m_toolbar.get_imgui_hovered_pos(); + int selected = -1; + const float em = static_cast(wxGetApp().em_unit()); - int hovered = m_toolbar.get_imgui_hovered_pos(); - int selected = -1; - const float em = static_cast(wxGetApp().em_unit()); + if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) + m_toolbar.set_imgui_hovered_pos(hovered); + else + m_toolbar.set_imgui_hovered_pos(-1); - if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) - m_toolbar.set_imgui_hovered_pos(hovered); - if (selected >= 0) - is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); + if (selected >= 0) + is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); - imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1)); + imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1)); - imgui->end(); - } + imgui->end(); } bool GLCanvas3D::_init_toolbar() @@ -3685,19 +3685,10 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; - item.is_toggable = false; - item.action_callback = [this]() { - if (m_canvas != nullptr) { - wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO)); - m_toolbar.activate_imgui(true); - } - }; + item.action_callback = [this]() { if (m_canvas != nullptr) m_toolbar.set_imgui_hovered_pos(-1); }; item.visibility_callback = []()->bool { return true; }; - item.enabled_state_callback = [this]()->bool { - if (!wxGetApp().plater()->can_undo()) { m_toolbar.hide_imgui(true); return false; } - return true; - }; - item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(true, pos_x); }; + item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); } ; + item.render_callback = [this](float pos_x, float, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, pos_x); }; if (!m_toolbar.add_item(item)) return false; @@ -3707,17 +3698,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; - item.action_callback = [this]() { - if (m_canvas != nullptr) { - wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); - m_toolbar.activate_imgui(false); - } - }; - item.enabled_state_callback = [this]()->bool { - if (!wxGetApp().plater()->can_redo()) { m_toolbar.hide_imgui(false); return false; } - return true; - }; - item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(false, pos_x); }; + item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; + item.render_callback = [this](float pos_x, float, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, pos_x); }; if (!m_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index f6140464b..e78605333 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -84,7 +84,8 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b { GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); - m_data.render_callback(left, right, bottom, top); + if (is_pressed()) + m_data.render_callback(left, right, bottom, top); } GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index e32e4a41e..78dd56081 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -252,10 +252,7 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; - bool m_undo_imgui_visible {false}; - bool m_redo_imgui_visible {false}; int m_imgui_hovered_pos { -1 }; - int m_imgui_selected_pos { -1 }; public: #if ENABLE_SVG_ICONS @@ -312,22 +309,9 @@ public: bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); - // undo == true => "undo" imgui is activated - // undo == false => "redo" imgui is activated - bool get_imgui_visible(const bool undo) const { return undo ? m_undo_imgui_visible : m_redo_imgui_visible; } - void hide_imgui(const bool undo) { undo ? m_undo_imgui_visible = false : m_redo_imgui_visible = false; } - void activate_imgui(const bool undo) { - m_undo_imgui_visible = undo; - m_redo_imgui_visible = !undo; - m_imgui_hovered_pos = m_imgui_selected_pos = -1; - } - void set_imgui_hovered_pos(int pos = -1) { m_imgui_hovered_pos = pos; } int get_imgui_hovered_pos() const { return m_imgui_hovered_pos; } - void set_imgui_selected_pos(int pos = -1) { m_imgui_selected_pos = pos; } - int get_imgui_selected_pos() const { return m_imgui_selected_pos; } - private: void calc_layout() const; float get_width_horizontal() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a450ac0e5..d8825ab3a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4150,7 +4150,7 @@ void Plater::redo_to(int selection) return; } - const int idx = selection + p->get_active_snapshot_index(); + const int idx = p->get_active_snapshot_index() + selection + 1; p->redo_to(p->undo_redo_stack.snapshots()[idx].timestamp); } bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** out_text) -- cgit v1.2.3 From 46e295407b3c568e39cebb79dc8b3c3dbca386c3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 10 Jul 2019 10:52:12 +0200 Subject: Modified toolbar to call RenderCallback only when the item is toggable and pressed --- src/slic3r/GUI/GLCanvas3D.cpp | 40 +++++++---------------- src/slic3r/GUI/GLToolbar.cpp | 75 +++++++++++++++++++++++++++---------------- src/slic3r/GUI/GLToolbar.hpp | 23 ++----------- 3 files changed, 63 insertions(+), 75 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d87b97f53..4c9f70019 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3473,9 +3473,9 @@ static bool string_getter(const bool is_undo, int idx, const char** out_text) void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) { - if (m_canvas != nullptr && m_toolbar.get_imgui_visible(is_undo)) + if (m_canvas != nullptr) { - const wxString& stack_name = _(is_undo ? L("Undo") : L("Redo")); + const wxString stack_name = _(is_undo ? L("Undo") : L("Redo")); ImGuiWrapper* imgui = wxGetApp().imgui(); const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); @@ -3483,16 +3483,17 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) imgui->set_next_window_bg_alpha(0.5f); imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - int hovered = m_toolbar.get_imgui_hovered_pos(); + int hovered = -1; int selected = -1; const float em = static_cast(wxGetApp().em_unit()); if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) - m_toolbar.set_imgui_hovered_pos(hovered); - if (selected >= 0) - is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); + { + if (selected >= 0) + is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); + } imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1)); @@ -3685,18 +3686,9 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; - item.is_toggable = false; - item.action_callback = [this]() { - if (m_canvas != nullptr) { - wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO)); - m_toolbar.activate_imgui(true); - } - }; + item.action_callback = [this]() { if (m_canvas != nullptr) { wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO)); } }; item.visibility_callback = []()->bool { return true; }; - item.enabled_state_callback = [this]()->bool { - if (!wxGetApp().plater()->can_undo()) { m_toolbar.hide_imgui(true); return false; } - return true; - }; + item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); }; item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(true, pos_x); }; if (!m_toolbar.add_item(item)) return false; @@ -3707,16 +3699,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; - item.action_callback = [this]() { - if (m_canvas != nullptr) { - wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); - m_toolbar.activate_imgui(false); - } - }; - item.enabled_state_callback = [this]()->bool { - if (!wxGetApp().plater()->can_redo()) { m_toolbar.hide_imgui(false); return false; } - return true; - }; + item.action_callback = [this]() { if (m_canvas != nullptr) { wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); } }; + item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(false, pos_x); }; if (!m_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index f6140464b..78e10c4f1 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -84,7 +84,8 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b { GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); - m_data.render_callback(left, right, bottom, top); + if (is_toggable() && is_pressed()) + m_data.render_callback(left, right, bottom, top); } GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const @@ -164,6 +165,7 @@ GLToolbar::GLToolbar(GLToolbar::EType type) , m_icons_texture_dirty(true) #endif // ENABLE_SVG_ICONS , m_tooltip("") + , m_pressed_toggable_id(-1) { } @@ -345,7 +347,7 @@ void GLToolbar::select_item(const std::string& name) bool GLToolbar::is_item_pressed(const std::string& name) const { - for (GLToolbarItem* item : m_items) + for (const GLToolbarItem* item : m_items) { if (item->get_name() == name) return item->is_pressed(); @@ -356,7 +358,7 @@ bool GLToolbar::is_item_pressed(const std::string& name) const bool GLToolbar::is_item_disabled(const std::string& name) const { - for (GLToolbarItem* item : m_items) + for (const GLToolbarItem* item : m_items) { if (item->get_name() == name) return item->is_disabled(); @@ -367,7 +369,7 @@ bool GLToolbar::is_item_disabled(const std::string& name) const bool GLToolbar::is_item_visible(const std::string& name) const { - for (GLToolbarItem* item : m_items) + for (const GLToolbarItem* item : m_items) { if (item->get_name() == name) return item->is_visible(); @@ -376,11 +378,25 @@ bool GLToolbar::is_item_visible(const std::string& name) const return false; } +bool GLToolbar::is_any_item_pressed() const +{ + for (const GLToolbarItem* item : m_items) + { + if (item->is_pressed()) + return true; + } + + return false; +} + bool GLToolbar::update_items_state() { bool ret = false; ret |= update_items_visibility(); ret |= update_items_enabled_state(); + if (!is_any_item_pressed()) + m_pressed_toggable_id = -1; + return ret; } @@ -558,36 +574,41 @@ float GLToolbar::get_main_size() const void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) { - if (item_id < (unsigned int)m_items.size()) + if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id)) { - GLToolbarItem* item = m_items[item_id]; - if ((item != nullptr) && !item->is_separator() && item->is_hovered()) + if (item_id < (unsigned int)m_items.size()) { - if (item->is_toggable()) + GLToolbarItem* item = m_items[item_id]; + if ((item != nullptr) && !item->is_separator() && item->is_hovered()) { - GLToolbarItem::EState state = item->get_state(); - if (state == GLToolbarItem::Hover) - item->set_state(GLToolbarItem::HoverPressed); - else if (state == GLToolbarItem::HoverPressed) - item->set_state(GLToolbarItem::Hover); + if (item->is_toggable()) + { + GLToolbarItem::EState state = item->get_state(); + if (state == GLToolbarItem::Hover) + item->set_state(GLToolbarItem::HoverPressed); + else if (state == GLToolbarItem::HoverPressed) + item->set_state(GLToolbarItem::Hover); - parent.render(); - item->do_action(); - } - else - { - if (m_type == Radio) - select_item(item->get_name()); - else - item->set_state(GLToolbarItem::HoverPressed); + m_pressed_toggable_id = item->is_pressed() ? item_id : -1; - parent.render(); - item->do_action(); - if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled)) + parent.render(); + item->do_action(); + } + else { - // the item may get disabled during the action, if not, set it back to hover state - item->set_state(GLToolbarItem::Hover); + if (m_type == Radio) + select_item(item->get_name()); + else + item->set_state(GLToolbarItem::HoverPressed); + parent.render(); + item->do_action(); + if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled)) + { + // the item may get disabled during the action, if not, set it back to hover state + item->set_state(GLToolbarItem::Hover); + parent.render(); + } } } } diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index e32e4a41e..de19296a5 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -252,10 +252,7 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; - bool m_undo_imgui_visible {false}; - bool m_redo_imgui_visible {false}; - int m_imgui_hovered_pos { -1 }; - int m_imgui_selected_pos { -1 }; + unsigned int m_pressed_toggable_id; public: #if ENABLE_SVG_ICONS @@ -302,6 +299,8 @@ public: bool is_item_disabled(const std::string& name) const; bool is_item_visible(const std::string& name) const; + bool is_any_item_pressed() const; + const std::string& get_tooltip() const { return m_tooltip; } @@ -312,22 +311,6 @@ public: bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); - // undo == true => "undo" imgui is activated - // undo == false => "redo" imgui is activated - bool get_imgui_visible(const bool undo) const { return undo ? m_undo_imgui_visible : m_redo_imgui_visible; } - void hide_imgui(const bool undo) { undo ? m_undo_imgui_visible = false : m_redo_imgui_visible = false; } - void activate_imgui(const bool undo) { - m_undo_imgui_visible = undo; - m_redo_imgui_visible = !undo; - m_imgui_hovered_pos = m_imgui_selected_pos = -1; - } - - void set_imgui_hovered_pos(int pos = -1) { m_imgui_hovered_pos = pos; } - int get_imgui_hovered_pos() const { return m_imgui_hovered_pos; } - - void set_imgui_selected_pos(int pos = -1) { m_imgui_selected_pos = pos; } - int get_imgui_selected_pos() const { return m_imgui_selected_pos; } - private: void calc_layout() const; float get_width_horizontal() const; -- cgit v1.2.3 From 99df9f56c4a68660d819180caa15f538b7341c5d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 10 Jul 2019 11:28:11 +0200 Subject: Added take_snapshot() for adding of settings --- src/slic3r/GUI/GUI_ObjectList.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 90c3f2665..c11865cac 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1115,6 +1115,8 @@ void ObjectList::get_settings_choice(const wxString& category_name) } #endif + take_snapshot(wxString::Format(_(L("Add Settings for %s")), is_part ? _(L("Sub-object")) : _(L("Object")))); + std::vector selected_options; selected_options.reserve(selection_cnt); for (auto sel : selections) @@ -1165,6 +1167,8 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name) assert(m_config); auto opt_keys = m_config->keys(); + take_snapshot(wxString::Format(_(L("Add Settings Bundle for %s")), m_objects_model->GetItemType(GetSelection()) & itObject ? _(L("Object")) : _(L("Sub-object")))); + const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; for (auto& opt_key : options) { -- cgit v1.2.3 From 40a1f31e847e8613c7b588e6a026b1dcdec317ad Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 10 Jul 2019 11:59:25 +0200 Subject: Disable remaining toolbar items when one of them is toggable and pressed --- src/slic3r/GUI/GLToolbar.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 78e10c4f1..8c9751086 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -1396,9 +1396,15 @@ bool GLToolbar::update_items_enabled_state() { bool ret = false; - for (GLToolbarItem* item : m_items) + for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) { + GLToolbarItem* item = m_items[i]; ret |= item->update_enabled_state(); + if (item->is_enabled() && (m_pressed_toggable_id != -1) && (m_pressed_toggable_id != i)) + { + ret = true; + item->set_state(GLToolbarItem::Disabled); + } } if (ret) -- cgit v1.2.3 From 14dad5039a316b9a9224cc638f3bd0b783a1293b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 10 Jul 2019 13:45:25 +0200 Subject: Imgui dialogs for undo/redo centered on their toolbar item icon --- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++---- src/slic3r/GUI/ImGuiWrapper.cpp | 4 ++-- src/slic3r/GUI/ImGuiWrapper.hpp | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4fa5b8b27..d14739c94 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3477,8 +3477,7 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) ImGuiWrapper* imgui = wxGetApp().imgui(); const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); - imgui->set_next_window_pos(x, m_toolbar.get_height(), ImGuiCond_Always); - + imgui->set_next_window_pos(x, m_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); imgui->set_next_window_bg_alpha(0.5f); imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); @@ -3688,7 +3687,7 @@ bool GLCanvas3D::_init_toolbar() item.action_callback = [this]() { if (m_canvas != nullptr) m_toolbar.set_imgui_hovered_pos(-1); }; item.visibility_callback = []()->bool { return true; }; item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); } ; - item.render_callback = [this](float pos_x, float, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, pos_x); }; + item.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; if (!m_toolbar.add_item(item)) return false; @@ -3699,7 +3698,7 @@ bool GLCanvas3D::_init_toolbar() item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; - item.render_callback = [this](float pos_x, float, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, pos_x); }; + item.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, 0.5f * (left + right)); }; if (!m_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 7f4a6c10c..f58266a5d 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -233,9 +233,9 @@ ImVec2 ImGuiWrapper::calc_text_size(const wxString &text) return size; } -void ImGuiWrapper::set_next_window_pos(float x, float y, int flag) +void ImGuiWrapper::set_next_window_pos(float x, float y, int flag, float pivot_x, float pivot_y) { - ImGui::SetNextWindowPos(ImVec2(x, y), (ImGuiCond)flag); + ImGui::SetNextWindowPos(ImVec2(x, y), (ImGuiCond)flag, ImVec2(pivot_x, pivot_y)); ImGui::SetNextWindowSize(ImVec2(0.0, 0.0)); } diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index a18b15184..c6550351e 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -51,7 +51,7 @@ public: ImVec2 scaled(float x, float y) const { return ImVec2(x * m_font_size, y * m_font_size); } ImVec2 calc_text_size(const wxString &text); - void set_next_window_pos(float x, float y, int flag); + void set_next_window_pos(float x, float y, int flag, float pivot_x = 0.0f, float pivot_y = 0.0f); void set_next_window_bg_alpha(float alpha); bool begin(const std::string &name, int flags = 0); -- cgit v1.2.3 From 1b5ab100bd685d5cf4e77d0b653b864562f9932b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 10 Jul 2019 14:08:14 +0200 Subject: GLToolbar::m_imgui_hovered_pos replaced with GLCanvas3D::m_imgui_undo_redo_hovered_pos --- src/slic3r/GUI/GLCanvas3D.cpp | 8 ++++---- src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ src/slic3r/GUI/GLToolbar.hpp | 4 ---- 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d14739c94..3dccf4551 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3482,14 +3482,14 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - int hovered = m_toolbar.get_imgui_hovered_pos(); + int hovered = m_imgui_undo_redo_hovered_pos; int selected = -1; const float em = static_cast(wxGetApp().em_unit()); if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) - m_toolbar.set_imgui_hovered_pos(hovered); + m_imgui_undo_redo_hovered_pos = hovered; else - m_toolbar.set_imgui_hovered_pos(-1); + m_imgui_undo_redo_hovered_pos = -1; if (selected >= 0) is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); @@ -3684,7 +3684,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; - item.action_callback = [this]() { if (m_canvas != nullptr) m_toolbar.set_imgui_hovered_pos(-1); }; + item.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.visibility_callback = []()->bool { return true; }; item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); } ; item.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index f9efdf37a..1949c864b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -488,6 +488,8 @@ private: RenderStats m_render_stats; #endif // ENABLE_RENDER_STATISTICS + int m_imgui_undo_redo_hovered_pos{ -1 }; + public: GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar); ~GLCanvas3D(); diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 2ba1bb31b..de19296a5 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -252,7 +252,6 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; - int m_imgui_hovered_pos { -1 }; unsigned int m_pressed_toggable_id; public: @@ -312,9 +311,6 @@ public: bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); - void set_imgui_hovered_pos(int pos = -1) { m_imgui_hovered_pos = pos; } - int get_imgui_hovered_pos() const { return m_imgui_hovered_pos; } - private: void calc_layout() const; float get_width_horizontal() const; -- cgit v1.2.3 From 1dc0439a31562d901db266a039ca166ba3f7d08e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 10 Jul 2019 15:55:53 +0200 Subject: Fixed margins for FreqChangedParams --- src/slic3r/GUI/OptionsGroup.hpp | 6 ++++++ src/slic3r/GUI/Plater.cpp | 15 ++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 422a5c2a2..d720787b6 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -162,6 +162,12 @@ public: void clear_fields_except_of(const std::vector left_fields); + void hide_labels() { + label_width = 0; + m_grid_sizer->SetCols(m_grid_sizer->GetEffectiveColsCount()-1); + static_cast(m_grid_sizer)->AddGrowableCol(!extra_column ? 0 : 1); + } + OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false, column_t extra_clmn = nullptr) : m_parent(_parent), title(title), diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index dee78aef7..3a155c9b0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -245,6 +245,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * last_selected(wxNOT_FOUND), m_em_unit(wxGetApp().em_unit()) { + SetFont(wxGetApp().normal_font()); Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) { auto selected_item = this->GetSelection(); @@ -373,7 +374,7 @@ class FreqChangedParams : public OG_Settings std::shared_ptr m_og_sla; public: - FreqChangedParams(wxWindow* parent, const int label_width); + FreqChangedParams(wxWindow* parent); ~FreqChangedParams() {} wxButton* get_wiping_dialog_button() { return m_wiping_dialog_button; } @@ -382,14 +383,14 @@ public: void Show(const bool is_fff); }; -FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : +FreqChangedParams::FreqChangedParams(wxWindow* parent) : OG_Settings(parent, false) { DynamicPrintConfig* config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; // Frequently changed parameters for FFF_technology m_og->set_config(config); - m_og->label_width = label_width == 0 ? 1 : label_width; + m_og->hide_labels(); m_og->m_on_change = [config, this](t_config_option_key opt_key, boost::any value) { Tab* tab_print = wxGetApp().get_tab(Preset::TYPE_PRINT); @@ -485,6 +486,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : auto wiping_dialog_btn = [config, this](wxWindow* parent) { m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + m_wiping_dialog_button->SetFont(wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_wiping_dialog_button); m_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e) @@ -512,9 +514,9 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : // Frequently changed parameters for SLA_technology m_og_sla = std::make_shared(parent, ""); + m_og_sla->hide_labels(); DynamicPrintConfig* config_sla = &wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; m_og_sla->set_config(config_sla); - m_og_sla->label_width = label_width == 0 ? 1 : label_width; m_og_sla->m_on_change = [config_sla, this](t_config_option_key opt_key, boost::any value) { Tab* tab = wxGetApp().get_tab(Preset::TYPE_SLA_PRINT); @@ -733,13 +735,12 @@ Sidebar::Sidebar(Plater *parent) init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false); const int margin_5 = int(0.5*wxGetApp().em_unit());// 5; - const int margin_10 = 10;//int(1.5*wxGetApp().em_unit());// 15; p->sizer_params = new wxBoxSizer(wxVERTICAL); // Frequently changed parameters - p->frequently_changed_parameters = new FreqChangedParams(p->scrolled, 0/*label_width*/); - p->sizer_params->Add(p->frequently_changed_parameters->get_sizer(), 0, wxEXPAND | wxTOP | wxBOTTOM, margin_10); + p->frequently_changed_parameters = new FreqChangedParams(p->scrolled); + p->sizer_params->Add(p->frequently_changed_parameters->get_sizer(), 0, wxEXPAND | wxTOP | wxBOTTOM, wxOSX ? 1 : margin_5); // Object List p->object_list = new ObjectList(p->scrolled); -- cgit v1.2.3 From 5cbaa7b08129899ff207d660aed42e22531ef9b4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 10 Jul 2019 17:50:24 +0200 Subject: FreqChangedParams : workaround for right border alignment --- src/slic3r/GUI/OptionsGroup.cpp | 4 ++-- src/slic3r/GUI/Plater.cpp | 42 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 7 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 0ed23889e..9feca2f3d 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -266,7 +266,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n is_sizer_field(field) ? v_sizer->Add(field->getSizer(), 0, wxEXPAND) : v_sizer->Add(field->getWindow(), 0, wxEXPAND); - return; + break;//return; } is_sizer_field(field) ? @@ -300,7 +300,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n { // extra widget for non-staticbox option group (like for the frequently used parameters on the sidebar) should be wxALIGN_RIGHT const auto v_sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(v_sizer, 1, wxEXPAND); + sizer->Add(v_sizer, option_set.size() == 1 ? 0 : 1, wxEXPAND); v_sizer->Add(extra_widget(this->ctrl_parent()), 0, wxALIGN_RIGHT); return; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3a155c9b0..2988278d7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -373,6 +373,7 @@ class FreqChangedParams : public OG_Settings wxSizer* m_sizer {nullptr}; std::shared_ptr m_og_sla; + std::vector m_empty_buttons; public: FreqChangedParams(wxWindow* parent); ~FreqChangedParams() {} @@ -381,8 +382,19 @@ public: wxSizer* get_sizer() override; ConfigOptionsGroup* get_og(const bool is_fff); void Show(const bool is_fff); + + void msw_rescale(); }; +void FreqChangedParams::msw_rescale() +{ + m_og->msw_rescale(); + m_og_sla->msw_rescale(); + + for (auto btn: m_empty_buttons) + btn->msw_rescale(); +} + FreqChangedParams::FreqChangedParams(wxWindow* parent) : OG_Settings(parent, false) { @@ -462,6 +474,20 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : Option option = Option(support_def, "support"); option.opt.full_width = true; line.append_option(option); + + /* Not a best solution, but + * Temporary workaround for right border alignment + */ + auto empty_widget = [this] (wxWindow* parent) { + auto sizer = new wxBoxSizer(wxHORIZONTAL); + auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_transparent.png", wxEmptyString, + wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); + sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, int(0.3 * wxGetApp().em_unit())); + m_empty_buttons.push_back(btn); + return sizer; + }; + line.append_widget(empty_widget); + m_og->append_line(line); @@ -488,7 +514,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); m_wiping_dialog_button->SetFont(wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_wiping_dialog_button); + sizer->Add(m_wiping_dialog_button, 0, wxALIGN_CENTER_VERTICAL); m_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e) { auto &config = wxGetApp().preset_bundle->project_config; @@ -505,6 +531,13 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent)); } })); + + auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_transparent.png", wxEmptyString, + wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); + sizer->Add(btn , 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, + int(0.3 * wxGetApp().em_unit())); + m_empty_buttons.push_back(btn); + return sizer; }; line.append_widget(wiping_dialog_btn); @@ -554,7 +587,8 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : support_def_sla.enum_labels.erase(support_def_sla.enum_labels.begin() + 2); option = Option(support_def_sla, "support"); option.opt.full_width = true; - line.append_option(option); + line.append_option(option); + line.append_widget(empty_widget); m_og_sla->append_line(line); line = Line{ "", "" }; @@ -947,9 +981,7 @@ void Sidebar::msw_rescale() // ... then refill them and set min size to correct layout of the sidebar update_all_preset_comboboxes(); - p->frequently_changed_parameters->get_og(true)->msw_rescale(); - p->frequently_changed_parameters->get_og(false)->msw_rescale(); - + p->frequently_changed_parameters->msw_rescale(); p->object_list->msw_rescale(); p->object_manipulation->msw_rescale(); p->object_settings->msw_rescale(); -- cgit v1.2.3 From dbf0eacfa7c0ac05183dbee54e003ce0c517fbd1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 11 Jul 2019 07:46:40 +0200 Subject: Deactivate undo/redo toolbar items when leaving the 3D scene or clicking into it --- src/slic3r/GUI/GLCanvas3D.cpp | 24 ++++++++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ src/slic3r/GUI/GLToolbar.cpp | 30 ++++++++++++++++++++++++------ src/slic3r/GUI/GLToolbar.hpp | 7 +++++-- 4 files changed, 53 insertions(+), 10 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3dccf4551..31087d633 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2397,7 +2397,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #endif /* __APPLE__ */ post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; - case WXK_ESCAPE: { deselect_all(); break; } case '0': { select_view("iso"); break; } case '1': { select_view("top"); break; } @@ -2744,12 +2743,17 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } else if (evt.Leaving()) { + _deactivate_undo_redo_toolbar_items(); + // to remove hover on objects when the mouse goes out of this canvas m_mouse.position = Vec2d(-1.0, -1.0); m_dirty = true; } - else if (evt.LeftDown() || evt.RightDown()) + else if (evt.LeftDown() || evt.RightDown() || evt.MiddleDown()) { + if (_deactivate_undo_redo_toolbar_items()) + return; + // If user pressed left or right button we first check whether this happened // on a volume or not. m_layers_editing.state = LayersEditing::Unknown; @@ -5866,6 +5870,22 @@ void GLCanvas3D::_update_selection_from_hover() m_dirty = true; } +bool GLCanvas3D::_deactivate_undo_redo_toolbar_items() +{ + if (m_toolbar.is_item_pressed("undo")) + { + m_toolbar.force_action(m_toolbar.get_item_id("undo"), *this); + return true; + } + else if (m_toolbar.is_item_pressed("redo")) + { + m_toolbar.force_action(m_toolbar.get_item_id("redo"), *this); + return true; + } + + return false; +} + const Print* GLCanvas3D::fff_print() const { return (m_process == nullptr) ? nullptr : m_process->fff_print(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 1949c864b..3ae420cdb 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -742,6 +742,8 @@ private: // updates the selection from the content of m_hover_volume_idxs void _update_selection_from_hover(); + bool _deactivate_undo_redo_toolbar_items(); + static std::vector _parse_colors(const std::vector& colors); public: diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 8c9751086..45e427522 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -389,6 +389,22 @@ bool GLToolbar::is_any_item_pressed() const return false; } +unsigned int GLToolbar::get_item_id(const std::string& name) const +{ + for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) + { + if (m_items[i]->get_name() == name) + return i; + } + + return -1; +} + +void GLToolbar::force_action(unsigned int item_id, GLCanvas3D& parent) +{ + do_action(item_id, parent, false); +} + bool GLToolbar::update_items_state() { bool ret = false; @@ -461,10 +477,8 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.parent = &parent; processed = true; if ((item_id != -2) && !m_items[item_id]->is_separator()) - { // mouse is inside an icon - do_action((unsigned int)item_id, parent); - } + do_action((unsigned int)item_id, parent, true); } else if (evt.MiddleDown()) { @@ -572,14 +586,14 @@ float GLToolbar::get_main_size() const return size; } -void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) +void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent, bool check_hover) { if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id)) { if (item_id < (unsigned int)m_items.size()) { GLToolbarItem* item = m_items[item_id]; - if ((item != nullptr) && !item->is_separator() && item->is_hovered()) + if ((item != nullptr) && !item->is_separator() && (!check_hover || item->is_hovered())) { if (item->is_toggable()) { @@ -588,6 +602,10 @@ void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) item->set_state(GLToolbarItem::HoverPressed); else if (state == GLToolbarItem::HoverPressed) item->set_state(GLToolbarItem::Hover); + else if (state == GLToolbarItem::Pressed) + item->set_state(GLToolbarItem::Normal); + else if (state == GLToolbarItem::Normal) + item->set_state(GLToolbarItem::Pressed); m_pressed_toggable_id = item->is_pressed() ? item_id : -1; @@ -599,7 +617,7 @@ void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) if (m_type == Radio) select_item(item->get_name()); else - item->set_state(GLToolbarItem::HoverPressed); + item->set_state(item->is_hovered() ? GLToolbarItem::HoverPressed : GLToolbarItem::Pressed); parent.render(); item->do_action(); diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index de19296a5..33e1ca234 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -301,8 +301,11 @@ public: bool is_any_item_pressed() const; - const std::string& get_tooltip() const { return m_tooltip; } + unsigned int get_item_id(const std::string& name) const; + + void force_action(unsigned int item_id, GLCanvas3D& parent); + const std::string& get_tooltip() const { return m_tooltip; } // returns true if any item changed its state bool update_items_state(); @@ -318,7 +321,7 @@ private: float get_height_horizontal() const; float get_height_vertical() const; float get_main_size() const; - void do_action(unsigned int item_id, GLCanvas3D& parent); + void do_action(unsigned int item_id, GLCanvas3D& parent, bool check_hover); std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent); std::string update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent); std::string update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent); -- cgit v1.2.3 From f964f5e99a5f432569ce3e04a26a420a1490c7ae Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 11 Jul 2019 07:54:33 +0200 Subject: Deactivate undo/redo toolbar items by pressing Esc key --- src/slic3r/GUI/GLCanvas3D.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 31087d633..fe91e9a96 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2326,6 +2326,9 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) return; } + if ((keyCode == WXK_ESCAPE) && _deactivate_undo_redo_toolbar_items()) + return; + if (m_gizmos.on_char(evt, *this)) return; -- cgit v1.2.3 From 4c6c608342e92d6769205ea8b68bde7ebbef04d6 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 11 Jul 2019 15:29:46 +0200 Subject: GLToolbar and GLToolbarItem refactored to allow two different actions when left/right clicking on items. Stack dialog for undo and redo items is now shown on right click only --- src/slic3r/GUI/GLCanvas3D.cpp | 64 +++++++++++++++++++++------------------ src/slic3r/GUI/GLToolbar.cpp | 70 +++++++++++++++++++++++++++++++++---------- src/slic3r/GUI/GLToolbar.hpp | 47 ++++++++++++++++++++++------- src/slic3r/GUI/Plater.cpp | 6 ++-- 4 files changed, 127 insertions(+), 60 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fe91e9a96..ceca4e0ff 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3550,7 +3550,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Add...")) + " [" + GUI::shortkey_ctrl_prefix() + "I]"; item.sprite_id = 0; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); }; if (!m_toolbar.add_item(item)) return false; @@ -3560,8 +3560,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Delete")) + " [Del]"; item.sprite_id = 1; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_delete(); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete(); }; if (!m_toolbar.add_item(item)) return false; @@ -3571,8 +3571,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Delete all")) + " [" + GUI::shortkey_ctrl_prefix() + "Del]"; item.sprite_id = 2; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_delete_all(); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete_all(); }; if (!m_toolbar.add_item(item)) return false; @@ -3582,8 +3582,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Arrange")) + " [A]"; item.sprite_id = 3; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_arrange(); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); }; if (!m_toolbar.add_item(item)) return false; @@ -3596,8 +3596,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Copy")) + " [" + GUI::shortkey_ctrl_prefix() + "C]"; item.sprite_id = 4; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_copy_to_clipboard(); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_copy_to_clipboard(); }; if (!m_toolbar.add_item(item)) return false; @@ -3607,8 +3607,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Paste")) + " [" + GUI::shortkey_ctrl_prefix() + "V]"; item.sprite_id = 5; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_paste_from_clipboard(); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_paste_from_clipboard(); }; if (!m_toolbar.add_item(item)) return false; @@ -3621,9 +3621,10 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Add instance")) + " [+]"; item.sprite_id = 6; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); }; + if (!m_toolbar.add_item(item)) return false; @@ -3633,9 +3634,9 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Remove instance")) + " [-]"; item.sprite_id = 7; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); }; if (!m_toolbar.add_item(item)) return false; @@ -3648,9 +3649,9 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Split to objects")); item.sprite_id = 8; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; item.visibility_callback = GLToolbarItem::Default_Visibility_Callback; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); }; if (!m_toolbar.add_item(item)) return false; @@ -3660,9 +3661,9 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Split to parts")); item.sprite_id = 9; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); }; if (!m_toolbar.add_item(item)) return false; @@ -3675,10 +3676,10 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Layers editing")); item.sprite_id = 10; - item.is_toggable = true; - item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; + item.left_toggable = true; + item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; }; - item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_layers_editing(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_layers_editing(); }; if (!m_toolbar.add_item(item)) return false; @@ -3691,10 +3692,13 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; - item.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; + item.left_toggable = false; + item.right_toggable = true; + item.left_action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); }; + item.right_action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.visibility_callback = []()->bool { return true; }; - item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); } ; - item.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; + item.enabling_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); }; + item.right_render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; if (!m_toolbar.add_item(item)) return false; @@ -3704,8 +3708,10 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; - item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; - item.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, 0.5f * (left + right)); }; + item.left_action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; + item.right_action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; + item.enabling_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; + item.right_render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, 0.5f * (left + right)); }; if (!m_toolbar.add_item(item)) return false; @@ -5877,12 +5883,12 @@ bool GLCanvas3D::_deactivate_undo_redo_toolbar_items() { if (m_toolbar.is_item_pressed("undo")) { - m_toolbar.force_action(m_toolbar.get_item_id("undo"), *this); + m_toolbar.force_right_action(m_toolbar.get_item_id("undo"), *this); return true; } else if (m_toolbar.is_item_pressed("redo")) { - m_toolbar.force_action(m_toolbar.get_item_id("redo"), *this); + m_toolbar.force_right_action(m_toolbar.get_item_id("redo"), *this); return true; } diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 45e427522..862805f8d 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -34,7 +34,7 @@ wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent); const GLToolbarItem::ActionCallback GLToolbarItem::Default_Action_Callback = [](){}; const GLToolbarItem::VisibilityCallback GLToolbarItem::Default_Visibility_Callback = []()->bool { return true; }; -const GLToolbarItem::EnabledStateCallback GLToolbarItem::Default_Enabled_State_Callback = []()->bool { return true; }; +const GLToolbarItem::EnablingCallback GLToolbarItem::Default_Enabling_Callback = []()->bool { return true; }; const GLToolbarItem::RenderCallback GLToolbarItem::Default_Render_Callback = [](float, float, float, float){}; GLToolbarItem::Data::Data() @@ -44,12 +44,15 @@ GLToolbarItem::Data::Data() #endif // ENABLE_SVG_ICONS , tooltip("") , sprite_id(-1) - , is_toggable(false) + , left_toggable(false) + , right_toggable(false) , visible(true) - , action_callback(Default_Action_Callback) + , left_action_callback(Default_Action_Callback) + , right_action_callback(Default_Action_Callback) , visibility_callback(Default_Visibility_Callback) - , enabled_state_callback(Default_Enabled_State_Callback) - , render_callback(Default_Render_Callback) + , enabling_callback(Default_Enabling_Callback) + , left_render_callback(nullptr) + , right_render_callback(nullptr) { } @@ -57,6 +60,7 @@ GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Dat : m_type(type) , m_state(Normal) , m_data(data) + , m_last_action(Undefined) { } @@ -72,7 +76,7 @@ bool GLToolbarItem::update_visibility() bool GLToolbarItem::update_enabled_state() { - bool enabled = m_data.enabled_state_callback(); + bool enabled = m_data.enabling_callback(); bool ret = (is_enabled() != enabled); if (ret) m_state = enabled ? GLToolbarItem::Normal : GLToolbarItem::Disabled; @@ -84,8 +88,13 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b { GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); - if (is_toggable() && is_pressed()) - m_data.render_callback(left, right, bottom, top); + if (is_pressed()) + { + if ((m_last_action == Left) && m_data.left_toggable && (m_data.left_render_callback != nullptr)) + m_data.left_render_callback(left, right, bottom, top); + else if ((m_last_action == Right) && m_data.right_toggable && (m_data.right_render_callback != nullptr)) + m_data.right_render_callback(left, right, bottom, top); + } } GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const @@ -400,9 +409,14 @@ unsigned int GLToolbar::get_item_id(const std::string& name) const return -1; } -void GLToolbar::force_action(unsigned int item_id, GLCanvas3D& parent) +void GLToolbar::force_left_action(unsigned int item_id, GLCanvas3D& parent) +{ + do_action(GLToolbarItem::Left, item_id, parent, false); +} + +void GLToolbar::force_right_action(unsigned int item_id, GLCanvas3D& parent) { - do_action(item_id, parent, false); + do_action(GLToolbarItem::Right, item_id, parent, false); } bool GLToolbar::update_items_state() @@ -476,9 +490,12 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.left = true; m_mouse_capture.parent = &parent; processed = true; - if ((item_id != -2) && !m_items[item_id]->is_separator()) + if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action() == GLToolbarItem::Left))) + { // mouse is inside an icon - do_action((unsigned int)item_id, parent, true); + do_action(GLToolbarItem::Left, (unsigned int)item_id, parent, true); + parent.set_as_dirty(); + } } else if (evt.MiddleDown()) { @@ -489,6 +506,13 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) { m_mouse_capture.right = true; m_mouse_capture.parent = &parent; + processed = true; + if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action() == GLToolbarItem::Right))) + { + // mouse is inside an icon + do_action(GLToolbarItem::Right, (unsigned int)item_id, parent, true); + parent.set_as_dirty(); + } } else if (evt.LeftUp()) processed = true; @@ -586,7 +610,7 @@ float GLToolbar::get_main_size() const return size; } -void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent, bool check_hover) +void GLToolbar::do_action(GLToolbarItem::EActionType type, unsigned int item_id, GLCanvas3D& parent, bool check_hover) { if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id)) { @@ -595,7 +619,8 @@ void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent, bool check_h GLToolbarItem* item = m_items[item_id]; if ((item != nullptr) && !item->is_separator() && (!check_hover || item->is_hovered())) { - if (item->is_toggable()) + if (((type == GLToolbarItem::Right) && item->is_right_toggable()) || + ((type == GLToolbarItem::Left) && item->is_left_toggable())) { GLToolbarItem::EState state = item->get_state(); if (state == GLToolbarItem::Hover) @@ -608,9 +633,15 @@ void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent, bool check_h item->set_state(GLToolbarItem::Pressed); m_pressed_toggable_id = item->is_pressed() ? item_id : -1; + item->reset_last_action(); parent.render(); - item->do_action(); + switch (type) + { + default: + case GLToolbarItem::Left: { item->do_left_action(); break; } + case GLToolbarItem::Right: { item->do_right_action(); break; } + } } else { @@ -619,8 +650,15 @@ void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent, bool check_h else item->set_state(item->is_hovered() ? GLToolbarItem::HoverPressed : GLToolbarItem::Pressed); + item->reset_last_action(); parent.render(); - item->do_action(); + switch (type) + { + default: + case GLToolbarItem::Left: { item->do_left_action(); break; } + case GLToolbarItem::Right: { item->do_right_action(); break; } + } + if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled)) { // the item may get disabled during the action, if not, set it back to hover state diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 33e1ca234..86cd1a7fc 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -36,8 +36,8 @@ class GLToolbarItem public: typedef std::function ActionCallback; typedef std::function VisibilityCallback; - typedef std::function EnabledStateCallback; - typedef std::function RenderCallback; + typedef std::function EnablingCallback; + typedef std::function RenderCallback; enum EType : unsigned char { @@ -46,6 +46,14 @@ public: Num_Types }; + enum EActionType : unsigned char + { + Undefined, + Left, + Right, + Num_Action_Types + }; + enum EState : unsigned char { Normal, @@ -64,25 +72,33 @@ public: #endif // ENABLE_SVG_ICONS std::string tooltip; unsigned int sprite_id; - bool is_toggable; + bool left_toggable; + bool right_toggable; bool visible; - ActionCallback action_callback; + // action on left click + ActionCallback left_action_callback; + // action on right click + ActionCallback right_action_callback; VisibilityCallback visibility_callback; - EnabledStateCallback enabled_state_callback; - RenderCallback render_callback; + EnablingCallback enabling_callback; + // render callback on left click + RenderCallback left_render_callback; + // render callback on right click + RenderCallback right_render_callback; Data(); }; static const ActionCallback Default_Action_Callback; static const VisibilityCallback Default_Visibility_Callback; - static const EnabledStateCallback Default_Enabled_State_Callback; + static const EnablingCallback Default_Enabling_Callback; static const RenderCallback Default_Render_Callback; private: EType m_type; EState m_state; Data m_data; + EActionType m_last_action; public: GLToolbarItem(EType type, const Data& data); @@ -96,17 +112,25 @@ public: #endif // ENABLE_SVG_ICONS const std::string& get_tooltip() const { return m_data.tooltip; } - void do_action() { m_data.action_callback(); } + void do_left_action() { m_last_action = Left; m_data.left_action_callback(); } + void do_right_action() { m_last_action = Right; m_data.right_action_callback(); } bool is_enabled() const { return m_state != Disabled; } bool is_disabled() const { return m_state == Disabled; } bool is_hovered() const { return (m_state == Hover) || (m_state == HoverPressed); } bool is_pressed() const { return (m_state == Pressed) || (m_state == HoverPressed); } - bool is_toggable() const { return m_data.is_toggable; } + bool is_left_toggable() const { return m_data.left_toggable; } + bool is_right_toggable() const { return m_data.right_toggable; } bool is_visible() const { return m_data.visible; } bool is_separator() const { return m_type == Separator; } + bool has_left_render_callback() const { return m_data.left_render_callback != nullptr; } + bool has_right_render_callback() const { return m_data.right_render_callback != nullptr; } + + EActionType get_last_action() const { return m_last_action; } + void reset_last_action() { m_last_action = Undefined; } + // returns true if the state changes bool update_visibility(); // returns true if the state changes @@ -303,7 +327,8 @@ public: unsigned int get_item_id(const std::string& name) const; - void force_action(unsigned int item_id, GLCanvas3D& parent); + void force_left_action(unsigned int item_id, GLCanvas3D& parent); + void force_right_action(unsigned int item_id, GLCanvas3D& parent); const std::string& get_tooltip() const { return m_tooltip; } @@ -321,7 +346,7 @@ private: float get_height_horizontal() const; float get_height_vertical() const; float get_main_size() const; - void do_action(unsigned int item_id, GLCanvas3D& parent, bool check_hover); + void do_action(GLToolbarItem::EActionType type, unsigned int item_id, GLCanvas3D& parent, bool check_hover); std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent); std::string update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent); std::string update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d8825ab3a..ea66d5f78 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3421,8 +3421,7 @@ void Plater::priv::init_view_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("3D editor view")) + " [" + GUI::shortkey_ctrl_prefix() + "5]"; item.sprite_id = 0; - item.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; - item.is_toggable = false; + item.left_action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; if (!view_toolbar.add_item(item)) return; @@ -3432,8 +3431,7 @@ void Plater::priv::init_view_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Preview")) + " [" + GUI::shortkey_ctrl_prefix() + "6]"; item.sprite_id = 1; - item.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; - item.is_toggable = false; + item.left_action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; if (!view_toolbar.add_item(item)) return; -- cgit v1.2.3 From a6a5b94155b22b4434e8f4ad1dc0426da95ffa1e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 11 Jul 2019 16:00:01 +0200 Subject: Added suppress_snapshots() and allow_snapshots() for avoid of excess "snapshoting" --- src/slic3r/GUI/GUI_ObjectList.cpp | 10 +++++++++- src/slic3r/GUI/Plater.cpp | 22 ++++++++++++++++++++-- src/slic3r/GUI/Plater.hpp | 2 ++ 3 files changed, 31 insertions(+), 3 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c11865cac..360318413 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -66,11 +66,14 @@ static int extruders_count() return wxGetApp().extruders_cnt(); } -static void take_snapshot(const wxString& snapshot_name) +static void take_snapshot(const wxString& snapshot_name) { wxGetApp().plater()->take_snapshot(snapshot_name); } +static void suppress_snapshots(){ wxGetApp().plater()->suppress_snapshots(); } +static void allow_snapshots() { wxGetApp().plater()->allow_snapshots(); } + ObjectList::ObjectList(wxWindow* parent) : wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE), m_parent(parent) @@ -2333,6 +2336,9 @@ void ObjectList::remove() wxDataViewItem parent = wxDataViewItem(0); + take_snapshot(_(L("Delete Selected"))); + suppress_snapshots(); + for (auto& item : sels) { if (m_objects_model->GetParent(item) == wxDataViewItem(0)) @@ -2353,6 +2359,8 @@ void ObjectList::remove() if (parent) select_item(parent); + + allow_snapshots(); } void ObjectList::del_layer_range(const t_layer_height_range& range) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d8825ab3a..15dd6b6ca 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1280,7 +1280,11 @@ struct Plater::priv PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; Slic3r::UndoRedo::Stack undo_redo_stack; - + bool m_prevent_snapshots = false; /* Used for avoid of excess "snapshoting". + * Like for "delete selected" or "set numbers of copies" + * we should call tack_snapshot just ones + * instead of calls for each action separately + * */ // GUI elements wxSizer* panel_sizer{ nullptr }; wxPanel* current_panel{ nullptr }; @@ -1581,13 +1585,20 @@ struct Plater::priv void split_volume(); void scale_selection_to_fit_print_volume(); - void take_snapshot(const std::string& snapshot_name) { this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); } + void take_snapshot(const std::string& snapshot_name) + { + if (this->m_prevent_snapshots) + return; + this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); + } void take_snapshot(const wxString& snapshot_name) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data())); } int get_active_snapshot_index(); void undo(); void redo(); void undo_to(size_t time_to_load); void redo_to(size_t time_to_load); + void suppress_snapshots() { this->m_prevent_snapshots = true; } + void allow_snapshots() { this->m_prevent_snapshots = false; } bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } void update_print_volume_state(); @@ -3729,7 +3740,9 @@ void Plater::delete_object_from_model(size_t obj_idx) { p->delete_object_from_mo void Plater::remove_selected() { this->take_snapshot(_(L("Delete Selected Objects"))); + this->suppress_snapshots(); this->p->view3D->delete_selected(); + this->allow_snapshots(); } void Plater::increase_instances(size_t num) @@ -3809,12 +3822,15 @@ void Plater::set_number_of_copies(/*size_t num*/) return; this->take_snapshot(wxString::Format(_(L("Set numbers of copies to %d")), num)); + this->suppress_snapshots(); int diff = (int)num - (int)model_object->instances.size(); if (diff > 0) increase_instances(diff); else if (diff < 0) decrease_instances(-diff); + + this->allow_snapshots(); } bool Plater::is_selection_empty() const @@ -4131,6 +4147,8 @@ void Plater::send_gcode() void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); } void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } +void Plater::suppress_snapshots() { p->suppress_snapshots(); } +void Plater::allow_snapshots() { p->allow_snapshots(); } void Plater::undo() { p->undo(); } void Plater::redo() { p->redo(); } void Plater::undo_to(int selection) diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index ca3d59224..23a5f12cf 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -185,6 +185,8 @@ public: void take_snapshot(const std::string &snapshot_name); void take_snapshot(const wxString &snapshot_name); + void suppress_snapshots(); + void allow_snapshots(); void undo(); void redo(); void undo_to(int selection); -- cgit v1.2.3 From 2f57f756e54151721e9be4b5f0bbe2788830ad20 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 12 Jul 2019 09:26:19 +0200 Subject: Follow-up of 4c6c608342e92d6769205ea8b68bde7ebbef04d6 -> refactoring --- src/slic3r/GUI/GLCanvas3D.cpp | 40 +++++++++++++++++++------------------- src/slic3r/GUI/GLToolbar.cpp | 31 ++++++++++++++--------------- src/slic3r/GUI/GLToolbar.hpp | 45 ++++++++++++++++++++++++------------------- src/slic3r/GUI/Plater.cpp | 4 ++-- 4 files changed, 63 insertions(+), 57 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ceca4e0ff..86aab33be 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3550,7 +3550,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Add...")) + " [" + GUI::shortkey_ctrl_prefix() + "I]"; item.sprite_id = 0; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); }; if (!m_toolbar.add_item(item)) return false; @@ -3560,7 +3560,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Delete")) + " [Del]"; item.sprite_id = 1; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete(); }; if (!m_toolbar.add_item(item)) return false; @@ -3571,7 +3571,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Delete all")) + " [" + GUI::shortkey_ctrl_prefix() + "Del]"; item.sprite_id = 2; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_delete_all(); }; if (!m_toolbar.add_item(item)) return false; @@ -3582,7 +3582,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Arrange")) + " [A]"; item.sprite_id = 3; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); }; if (!m_toolbar.add_item(item)) return false; @@ -3596,7 +3596,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Copy")) + " [" + GUI::shortkey_ctrl_prefix() + "C]"; item.sprite_id = 4; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_copy_to_clipboard(); }; if (!m_toolbar.add_item(item)) return false; @@ -3607,7 +3607,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Paste")) + " [" + GUI::shortkey_ctrl_prefix() + "V]"; item.sprite_id = 5; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_paste_from_clipboard(); }; if (!m_toolbar.add_item(item)) return false; @@ -3621,7 +3621,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Add instance")) + " [+]"; item.sprite_id = 6; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); }; @@ -3634,7 +3634,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Remove instance")) + " [-]"; item.sprite_id = 7; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); }; if (!m_toolbar.add_item(item)) @@ -3649,7 +3649,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Split to objects")); item.sprite_id = 8; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; item.visibility_callback = GLToolbarItem::Default_Visibility_Callback; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); }; if (!m_toolbar.add_item(item)) @@ -3661,7 +3661,7 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Split to parts")); item.sprite_id = 9; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); }; if (!m_toolbar.add_item(item)) @@ -3676,8 +3676,8 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Layers editing")); item.sprite_id = 10; - item.left_toggable = true; - item.left_action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; + item.left.toggable = true; + item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; }; item.enabling_callback = []()->bool { return wxGetApp().plater()->can_layers_editing(); }; if (!m_toolbar.add_item(item)) @@ -3692,13 +3692,13 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; - item.left_toggable = false; - item.right_toggable = true; - item.left_action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); }; - item.right_action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; + item.left.toggable = false; + item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); }; + item.right.toggable = true; + item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; + item.right.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; item.visibility_callback = []()->bool { return true; }; item.enabling_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); }; - item.right_render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(true, 0.5f * (left + right)); }; if (!m_toolbar.add_item(item)) return false; @@ -3708,10 +3708,10 @@ bool GLCanvas3D::_init_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; - item.left_action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; - item.right_action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; + item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; + item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; + item.right.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, 0.5f * (left + right)); }; item.enabling_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); }; - item.right_render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) _render_undo_redo_stack(false, 0.5f * (left + right)); }; if (!m_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 862805f8d..5093eb5d4 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -37,6 +37,13 @@ const GLToolbarItem::VisibilityCallback GLToolbarItem::Default_Visibility_Callba const GLToolbarItem::EnablingCallback GLToolbarItem::Default_Enabling_Callback = []()->bool { return true; }; const GLToolbarItem::RenderCallback GLToolbarItem::Default_Render_Callback = [](float, float, float, float){}; +GLToolbarItem::Data::Option::Option() + : toggable(false) + , action_callback(Default_Action_Callback) + , render_callback(nullptr) +{ +} + GLToolbarItem::Data::Data() : name("") #if ENABLE_SVG_ICONS @@ -44,15 +51,9 @@ GLToolbarItem::Data::Data() #endif // ENABLE_SVG_ICONS , tooltip("") , sprite_id(-1) - , left_toggable(false) - , right_toggable(false) , visible(true) - , left_action_callback(Default_Action_Callback) - , right_action_callback(Default_Action_Callback) , visibility_callback(Default_Visibility_Callback) , enabling_callback(Default_Enabling_Callback) - , left_render_callback(nullptr) - , right_render_callback(nullptr) { } @@ -60,7 +61,7 @@ GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Dat : m_type(type) , m_state(Normal) , m_data(data) - , m_last_action(Undefined) + , m_last_action_type(Undefined) { } @@ -90,10 +91,10 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b if (is_pressed()) { - if ((m_last_action == Left) && m_data.left_toggable && (m_data.left_render_callback != nullptr)) - m_data.left_render_callback(left, right, bottom, top); - else if ((m_last_action == Right) && m_data.right_toggable && (m_data.right_render_callback != nullptr)) - m_data.right_render_callback(left, right, bottom, top); + if ((m_last_action_type == Left) && m_data.left.can_render()) + m_data.left.render_callback(left, right, bottom, top); + else if ((m_last_action_type == Right) && m_data.right.can_render()) + m_data.right.render_callback(left, right, bottom, top); } } @@ -490,7 +491,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.left = true; m_mouse_capture.parent = &parent; processed = true; - if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action() == GLToolbarItem::Left))) + if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Left))) { // mouse is inside an icon do_action(GLToolbarItem::Left, (unsigned int)item_id, parent, true); @@ -507,7 +508,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.right = true; m_mouse_capture.parent = &parent; processed = true; - if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action() == GLToolbarItem::Right))) + if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Right))) { // mouse is inside an icon do_action(GLToolbarItem::Right, (unsigned int)item_id, parent, true); @@ -633,7 +634,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, unsigned int item_id, item->set_state(GLToolbarItem::Pressed); m_pressed_toggable_id = item->is_pressed() ? item_id : -1; - item->reset_last_action(); + item->reset_last_action_type(); parent.render(); switch (type) @@ -650,7 +651,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, unsigned int item_id, else item->set_state(item->is_hovered() ? GLToolbarItem::HoverPressed : GLToolbarItem::Pressed); - item->reset_last_action(); + item->reset_last_action_type(); parent.render(); switch (type) { diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 86cd1a7fc..34a92ea34 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -66,25 +66,30 @@ public: struct Data { + struct Option + { + bool toggable; + ActionCallback action_callback; + RenderCallback render_callback; + + Option(); + + bool can_render() const { return toggable && (render_callback != nullptr); } + }; + std::string name; #if ENABLE_SVG_ICONS std::string icon_filename; #endif // ENABLE_SVG_ICONS std::string tooltip; unsigned int sprite_id; - bool left_toggable; - bool right_toggable; + // mouse left click + Option left; + // mouse right click + Option right; bool visible; - // action on left click - ActionCallback left_action_callback; - // action on right click - ActionCallback right_action_callback; VisibilityCallback visibility_callback; EnablingCallback enabling_callback; - // render callback on left click - RenderCallback left_render_callback; - // render callback on right click - RenderCallback right_render_callback; Data(); }; @@ -98,7 +103,7 @@ private: EType m_type; EState m_state; Data m_data; - EActionType m_last_action; + EActionType m_last_action_type; public: GLToolbarItem(EType type, const Data& data); @@ -112,24 +117,24 @@ public: #endif // ENABLE_SVG_ICONS const std::string& get_tooltip() const { return m_data.tooltip; } - void do_left_action() { m_last_action = Left; m_data.left_action_callback(); } - void do_right_action() { m_last_action = Right; m_data.right_action_callback(); } + void do_left_action() { m_last_action_type = Left; m_data.left.action_callback(); } + void do_right_action() { m_last_action_type = Right; m_data.right.action_callback(); } bool is_enabled() const { return m_state != Disabled; } bool is_disabled() const { return m_state == Disabled; } bool is_hovered() const { return (m_state == Hover) || (m_state == HoverPressed); } bool is_pressed() const { return (m_state == Pressed) || (m_state == HoverPressed); } - - bool is_left_toggable() const { return m_data.left_toggable; } - bool is_right_toggable() const { return m_data.right_toggable; } bool is_visible() const { return m_data.visible; } bool is_separator() const { return m_type == Separator; } - bool has_left_render_callback() const { return m_data.left_render_callback != nullptr; } - bool has_right_render_callback() const { return m_data.right_render_callback != nullptr; } + bool is_left_toggable() const { return m_data.left.toggable; } + bool is_right_toggable() const { return m_data.right.toggable; } + + bool has_left_render_callback() const { return m_data.left.render_callback != nullptr; } + bool has_right_render_callback() const { return m_data.right.render_callback != nullptr; } - EActionType get_last_action() const { return m_last_action; } - void reset_last_action() { m_last_action = Undefined; } + EActionType get_last_action_type() const { return m_last_action_type; } + void reset_last_action_type() { m_last_action_type = Undefined; } // returns true if the state changes bool update_visibility(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 06252e1e7..e826d748e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3432,7 +3432,7 @@ void Plater::priv::init_view_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("3D editor view")) + " [" + GUI::shortkey_ctrl_prefix() + "5]"; item.sprite_id = 0; - item.left_action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; + item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; if (!view_toolbar.add_item(item)) return; @@ -3442,7 +3442,7 @@ void Plater::priv::init_view_toolbar() #endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Preview")) + " [" + GUI::shortkey_ctrl_prefix() + "6]"; item.sprite_id = 1; - item.left_action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; + item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; if (!view_toolbar.add_item(item)) return; -- cgit v1.2.3 From cc70c8dff9c6b9395845caba0542954276081613 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 12 Jul 2019 10:13:35 +0200 Subject: Tech ENABLE_SVG_ICONS set as default --- src/slic3r/GUI/GLCanvas3D.cpp | 124 --------------------- src/slic3r/GUI/GLCanvas3D.hpp | 4 - src/slic3r/GUI/GLToolbar.cpp | 161 +-------------------------- src/slic3r/GUI/GLToolbar.hpp | 52 --------- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 6 - src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 8 -- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 5 - src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 5 - src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 5 - src/slic3r/GUI/Gizmos/GLGizmoMove.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 13 --- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 5 - src/slic3r/GUI/Gizmos/GLGizmoScale.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 5 - src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 154 +------------------------ src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 14 --- src/slic3r/GUI/Plater.cpp | 18 --- 21 files changed, 3 insertions(+), 600 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d15d9aa4d..ec7746092 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1199,11 +1199,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar , m_bed(bed) , m_camera(camera) , m_view_toolbar(view_toolbar) -#if ENABLE_SVG_ICONS , m_toolbar(GLToolbar::Normal, "Top") -#else - , m_toolbar(GLToolbar::Normal) -#endif // ENABLE_SVG_ICONS , m_use_clipping_planes(false) , m_sidebar_field("") , m_keep_dirty(false) @@ -3422,12 +3418,6 @@ bool GLCanvas3D::_init_toolbar() if (!m_toolbar.is_enabled()) return true; -#if !ENABLE_SVG_ICONS - ItemsIconsTexture::Metadata icons_data; - icons_data.filename = "toolbar.png"; - icons_data.icon_size = 37; -#endif // !ENABLE_SVG_ICONS - BackgroundTexture::Metadata background_data; background_data.filename = "toolbar_background.png"; background_data.left = 16; @@ -3435,11 +3425,7 @@ bool GLCanvas3D::_init_toolbar() background_data.right = 16; background_data.bottom = 16; -#if ENABLE_SVG_ICONS if (!m_toolbar.init(background_data)) -#else - if (!m_toolbar.init(icons_data, background_data)) -#endif // ENABLE_SVG_ICONS { // unable to init the toolbar texture, disable it m_toolbar.set_enabled(false); @@ -3456,9 +3442,7 @@ bool GLCanvas3D::_init_toolbar() GLToolbarItem::Data item; item.name = "add"; -#if ENABLE_SVG_ICONS item.icon_filename = "add.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Add...")) + " [" + GUI::shortkey_ctrl_prefix() + "I]"; item.sprite_id = 0; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); }; @@ -3466,9 +3450,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "delete"; -#if ENABLE_SVG_ICONS item.icon_filename = "remove.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Delete")) + " [Del]"; item.sprite_id = 1; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE)); }; @@ -3477,9 +3459,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "deleteall"; -#if ENABLE_SVG_ICONS item.icon_filename = "delete_all.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Delete all")) + " [" + GUI::shortkey_ctrl_prefix() + "Del]"; item.sprite_id = 2; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); }; @@ -3488,9 +3468,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "arrange"; -#if ENABLE_SVG_ICONS item.icon_filename = "arrange.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Arrange")) + " [A]"; item.sprite_id = 3; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); }; @@ -3502,9 +3480,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "copy"; -#if ENABLE_SVG_ICONS item.icon_filename = "copy.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Copy")) + " [" + GUI::shortkey_ctrl_prefix() + "C]"; item.sprite_id = 4; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; @@ -3513,9 +3489,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "paste"; -#if ENABLE_SVG_ICONS item.icon_filename = "paste.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Paste")) + " [" + GUI::shortkey_ctrl_prefix() + "V]"; item.sprite_id = 5; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; @@ -3527,9 +3501,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "more"; -#if ENABLE_SVG_ICONS item.icon_filename = "instance_add.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Add instance")) + " [+]"; item.sprite_id = 6; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; @@ -3539,9 +3511,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "fewer"; -#if ENABLE_SVG_ICONS item.icon_filename = "instance_remove.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Remove instance")) + " [-]"; item.sprite_id = 7; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; @@ -3554,9 +3524,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "splitobjects"; -#if ENABLE_SVG_ICONS item.icon_filename = "split_objects.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Split to objects")); item.sprite_id = 8; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; @@ -3566,9 +3534,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "splitvolumes"; -#if ENABLE_SVG_ICONS item.icon_filename = "split_parts.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Split to parts")); item.sprite_id = 9; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; @@ -3581,9 +3547,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "layersediting"; -#if ENABLE_SVG_ICONS item.icon_filename = "layers_white.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Layers editing")); item.sprite_id = 10; item.is_toggable = true; @@ -3921,9 +3885,6 @@ void GLCanvas3D::_render_overlays() const _render_gizmos_overlay(); _render_warning_texture(); _render_legend_texture(); -#if !ENABLE_SVG_ICONS - _resize_toolbars(); -#endif // !ENABLE_SVG_ICONS _render_toolbar(); _render_view_toolbar(); @@ -4000,7 +3961,6 @@ void GLCanvas3D::_render_current_gizmo() const void GLCanvas3D::_render_gizmos_overlay() const { -#if ENABLE_SVG_ICONS #if ENABLE_RETINA_GL // m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor()); const float scale = m_retina_helper->get_scale_factor()*wxGetApp().toolbar_icon_scale(); @@ -4011,14 +3971,12 @@ void GLCanvas3D::_render_gizmos_overlay() const const float size = int(GLGizmosManager::Default_Icons_Size*wxGetApp().toolbar_icon_scale()); m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment #endif /* __WXMSW__ */ -#endif // ENABLE_SVG_ICONS m_gizmos.render_overlay(*this, m_selection); } void GLCanvas3D::_render_toolbar() const { -#if ENABLE_SVG_ICONS #if ENABLE_RETINA_GL // m_toolbar.set_scale(m_retina_helper->get_scale_factor()); const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(true); @@ -4073,20 +4031,12 @@ void GLCanvas3D::_render_toolbar() const } } m_toolbar.set_position(top, left); -#else -#if ENABLE_RETINA_GL - m_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); -#else - m_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); -#endif /* __WXMSW__ */ -#endif // ENABLE_SVG_ICONS m_toolbar.render(*this); } void GLCanvas3D::_render_view_toolbar() const { -#if ENABLE_SVG_ICONS #if ENABLE_RETINA_GL // m_view_toolbar.set_scale(m_retina_helper->get_scale_factor()); const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(); @@ -4106,13 +4056,6 @@ void GLCanvas3D::_render_view_toolbar() const float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom; float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; m_view_toolbar.set_position(top, left); -#else -#if ENABLE_RETINA_GL - m_view_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); -#else - m_view_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); -#endif /* __WXMSW__ */ -#endif // ENABLE_SVG_ICONS m_view_toolbar.render(*this); } @@ -5555,73 +5498,6 @@ bool GLCanvas3D::_is_any_volume_outside() const return false; } -#if !ENABLE_SVG_ICONS -void GLCanvas3D::_resize_toolbars() const -{ - Size cnv_size = get_canvas_size(); - float zoom = (float)m_camera.get_zoom(); - float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - -#if ENABLE_RETINA_GL - m_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); -#else - m_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); -#endif /* __WXMSW__ */ - - GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation(); - - switch (m_toolbar.get_layout_type()) - { - default: - case GLToolbar::Layout::Horizontal: - { - // centers the toolbar on the top edge of the 3d scene - float top, left; - if (orientation == GLToolbar::Layout::Top) - { - top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - left = -0.5f * m_toolbar.get_width() * inv_zoom; - } - else - { - top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom; - left = -0.5f * m_toolbar.get_width() * inv_zoom; - } - m_toolbar.set_position(top, left); - break; - } - case GLToolbar::Layout::Vertical: - { - // centers the toolbar on the right edge of the 3d scene - float top, left; - if (orientation == GLToolbar::Layout::Left) - { - top = 0.5f * m_toolbar.get_height() * inv_zoom; - left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; - } - else - { - top = 0.5f * m_toolbar.get_height() * inv_zoom; - left = (0.5f * (float)cnv_size.get_width() - m_toolbar.get_width()) * inv_zoom; - } - m_toolbar.set_position(top, left); - break; - } - } - -#if ENABLE_RETINA_GL - m_view_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); -#else - m_view_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); -#endif /* __WXMSW__ */ - - // places the toolbar on the bottom-left corner of the 3d scene - float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom; - float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; - m_view_toolbar.set_position(top, left); -} -#endif // !ENABLE_SVG_ICONS - void GLCanvas3D::_update_selection_from_hover() { bool ctrl_pressed = wxGetKeyState(WXK_CONTROL); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 882455a01..2408e0273 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -728,10 +728,6 @@ private: bool _is_any_volume_outside() const; -#if !ENABLE_SVG_ICONS - void _resize_toolbars() const; -#endif // !ENABLE_SVG_ICONS - // updates the selection from the content of m_hover_volume_idxs void _update_selection_from_hover(); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index a927eba9b..97bb957ea 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -38,9 +38,7 @@ const GLToolbarItem::EnabledStateCallback GLToolbarItem::Default_Enabled_State_C GLToolbarItem::Data::Data() : name("") -#if ENABLE_SVG_ICONS , icon_filename("") -#endif // ENABLE_SVG_ICONS , tooltip("") , sprite_id(-1) , is_toggable(false) @@ -105,14 +103,6 @@ GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int return uvs; } -#if !ENABLE_SVG_ICONS -ItemsIconsTexture::Metadata::Metadata() - : filename("") - , icon_size(0) -{ -} -#endif // !ENABLE_SVG_ICONS - BackgroundTexture::Metadata::Metadata() : filename("") , left(0) @@ -122,9 +112,7 @@ BackgroundTexture::Metadata::Metadata() { } -#if ENABLE_SVG_ICONS const float GLToolbar::Default_Icons_Size = 40.0f; -#endif // ENABLE_SVG_ICONS GLToolbar::Layout::Layout() : type(Horizontal) @@ -134,31 +122,19 @@ GLToolbar::Layout::Layout() , border(0.0f) , separator_size(0.0f) , gap_size(0.0f) -#if ENABLE_SVG_ICONS , icons_size(Default_Icons_Size) , scale(1.0f) -#else - , icons_scale(1.0f) -#endif // ENABLE_SVG_ICONS , width(0.0f) , height(0.0f) , dirty(true) { } -#if ENABLE_SVG_ICONS GLToolbar::GLToolbar(GLToolbar::EType type, const std::string& name) -#else -GLToolbar::GLToolbar(GLToolbar::EType type) -#endif // ENABLE_SVG_ICONS : m_type(type) -#if ENABLE_SVG_ICONS , m_name(name) -#endif // ENABLE_SVG_ICONS , m_enabled(false) -#if ENABLE_SVG_ICONS , m_icons_texture_dirty(true) -#endif // ENABLE_SVG_ICONS , m_tooltip("") { } @@ -171,27 +147,13 @@ GLToolbar::~GLToolbar() } } -#if ENABLE_SVG_ICONS bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture) -#else -bool GLToolbar::init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture) -#endif // ENABLE_SVG_ICONS { -#if ENABLE_SVG_ICONS if (m_background_texture.texture.get_id() != 0) return true; std::string path = resources_dir() + "/icons/"; bool res = false; -#else - if (m_icons_texture.texture.get_id() != 0) - return true; - - std::string path = resources_dir() + "/icons/"; - bool res = !icons_texture.filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture.filename, false, true); - if (res) - m_icons_texture.metadata = icons_texture; -#endif // ENABLE_SVG_ICONS if (!background_texture.filename.empty()) res = m_background_texture.texture.load_from_file(path + background_texture.filename, false, true); @@ -247,7 +209,6 @@ void GLToolbar::set_gap_size(float size) m_layout.dirty = true; } -#if ENABLE_SVG_ICONS void GLToolbar::set_icons_size(float size) { if (m_layout.icons_size != size) @@ -267,13 +228,6 @@ void GLToolbar::set_scale(float scale) m_icons_texture_dirty = true; } } -#else -void GLToolbar::set_icons_scale(float scale) -{ - m_layout.icons_scale = scale; - m_layout.dirty = true; -} -#endif // ENABLE_SVG_ICONS bool GLToolbar::is_enabled() const { @@ -385,10 +339,8 @@ void GLToolbar::render(const GLCanvas3D& parent) const if (!m_enabled || m_items.empty()) return; -#if ENABLE_SVG_ICONS if (m_icons_texture_dirty) generate_icons_texture(); -#endif // ENABLE_SVG_ICONS switch (m_layout.type) { @@ -492,20 +444,12 @@ float GLToolbar::get_width_horizontal() const float GLToolbar::get_width_vertical() const { -#if ENABLE_SVG_ICONS return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; -#else - return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale; -#endif // ENABLE_SVG_ICONS } float GLToolbar::get_height_horizontal() const { -#if ENABLE_SVG_ICONS return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; -#else - return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale; -#endif // ENABLE_SVG_ICONS } float GLToolbar::get_height_vertical() const @@ -515,7 +459,6 @@ float GLToolbar::get_height_vertical() const float GLToolbar::get_main_size() const { -#if ENABLE_SVG_ICONS float size = 2.0f * m_layout.border; for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) { @@ -531,25 +474,7 @@ float GLToolbar::get_main_size() const if (m_items.size() > 1) size += ((float)m_items.size() - 1.0f) * m_layout.gap_size; - size *= m_layout.scale; -#else - float size = 2.0f * m_layout.border * m_layout.icons_scale; - for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) - { - if (!m_items[i]->is_visible()) - continue; - - if (m_items[i]->is_separator()) - size += m_layout.separator_size * m_layout.icons_scale; - else - size += (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale; - } - - if (m_items.size() > 1) - size += ((float)m_items.size() - 1.0f) * m_layout.gap_size * m_layout.icons_scale; -#endif // ENABLE_SVG_ICONS - - return size; + return size * m_layout.scale; } void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) @@ -609,20 +534,12 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC float zoom = (float)parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; -#if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; -#else - float factor = m_layout.icons_scale * inv_zoom; -#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_layout.icons_size * factor; -#else - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; -#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -714,20 +631,12 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan float zoom = (float)parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; -#if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; -#else - float factor = m_layout.icons_scale * inv_zoom; -#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_layout.icons_size * factor; -#else - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; -#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -831,20 +740,12 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 float zoom = (float)parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; -#if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; -#else - float factor = m_layout.icons_scale * inv_zoom; -#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_layout.icons_size * factor; -#else - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; -#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -914,20 +815,12 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& float zoom = (float)parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; -#if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; -#else - float factor = m_layout.icons_scale * inv_zoom; -#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_layout.icons_size * factor; -#else - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; -#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -993,34 +886,15 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& void GLToolbar::render_horizontal(const GLCanvas3D& parent) const { -#if ENABLE_SVG_ICONS unsigned int tex_id = m_icons_texture.get_id(); int tex_width = m_icons_texture.get_width(); int tex_height = m_icons_texture.get_height(); -#else - unsigned int tex_id = m_icons_texture.texture.get_id(); - int tex_width = m_icons_texture.texture.get_width(); - int tex_height = m_icons_texture.texture.get_height(); -#endif // ENABLE_SVG_ICONS - -#if !ENABLE_SVG_ICONS - if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) - return; -#endif // !ENABLE_SVG_ICONS float zoom = (float)parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; -#if ENABLE_SVG_ICONS float factor = inv_zoom * m_layout.scale; -#else - float factor = inv_zoom * m_layout.icons_scale; -#endif // ENABLE_SVG_ICONS -#if ENABLE_SVG_ICONS float scaled_icons_size = m_layout.icons_size * factor; -#else - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; -#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -1121,10 +995,8 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const left += scaled_border; top -= scaled_border; -#if ENABLE_SVG_ICONS if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; -#endif // ENABLE_SVG_ICONS // renders icons for (const GLToolbarItem* item : m_items) @@ -1136,11 +1008,7 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const left += separator_stride; else { -#if ENABLE_SVG_ICONS item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); -#else - item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, m_icons_texture.metadata.icon_size); -#endif // ENABLE_SVG_ICONS left += icon_stride; } } @@ -1148,34 +1016,15 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const void GLToolbar::render_vertical(const GLCanvas3D& parent) const { -#if ENABLE_SVG_ICONS unsigned int tex_id = m_icons_texture.get_id(); int tex_width = m_icons_texture.get_width(); int tex_height = m_icons_texture.get_height(); -#else - unsigned int tex_id = m_icons_texture.texture.get_id(); - int tex_width = m_icons_texture.texture.get_width(); - int tex_height = m_icons_texture.texture.get_height(); -#endif // ENABLE_SVG_ICONS - -#if !ENABLE_SVG_ICONS - if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) - return; -#endif // !ENABLE_SVG_ICONS float zoom = (float)parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; -#if ENABLE_SVG_ICONS float factor = inv_zoom * m_layout.scale; -#else - float factor = inv_zoom * m_layout.icons_scale; -#endif // ENABLE_SVG_ICONS -#if ENABLE_SVG_ICONS float scaled_icons_size = m_layout.icons_size * factor; -#else - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale * factor; -#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -1276,10 +1125,8 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const left += scaled_border; top -= scaled_border; -#if ENABLE_SVG_ICONS if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; -#endif // ENABLE_SVG_ICONS // renders icons for (const GLToolbarItem* item : m_items) @@ -1291,17 +1138,12 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const top -= separator_stride; else { -#if ENABLE_SVG_ICONS item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); -#else - item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, m_icons_texture.metadata.icon_size); -#endif // ENABLE_SVG_ICONS top -= icon_stride; } } } -#if ENABLE_SVG_ICONS bool GLToolbar::generate_icons_texture() const { std::string path = resources_dir() + "/icons/"; @@ -1337,7 +1179,6 @@ bool GLToolbar::generate_icons_texture() const return res; } -#endif // ENABLE_SVG_ICONS bool GLToolbar::update_items_visibility() { diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 24314d60f..7b4cf8b10 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -58,9 +58,7 @@ public: struct Data { std::string name; -#if ENABLE_SVG_ICONS std::string icon_filename; -#endif // ENABLE_SVG_ICONS std::string tooltip; unsigned int sprite_id; bool is_toggable; @@ -88,9 +86,7 @@ public: void set_state(EState state) { m_state = state; } const std::string& get_name() const { return m_data.name; } -#if ENABLE_SVG_ICONS const std::string& get_icon_filename() const { return m_data.icon_filename; } -#endif // ENABLE_SVG_ICONS const std::string& get_tooltip() const { return m_data.tooltip; } void do_action() { m_data.action_callback(); } @@ -118,27 +114,6 @@ private: friend class GLToolbar; }; -#if !ENABLE_SVG_ICONS -// items icon textures are assumed to be square and all with the same size in pixels, no internal check is done -// icons are layed-out into the texture starting from the top-left corner in the same order as enum GLToolbarItem::EState -// from left to right -struct ItemsIconsTexture -{ - struct Metadata - { - // path of the file containing the icons' texture - std::string filename; - // size of the square icons, in pixels - unsigned int icon_size; - - Metadata(); - }; - - GLTexture texture; - Metadata metadata; -}; -#endif // !ENABLE_SVG_ICONS - struct BackgroundTexture { struct Metadata @@ -164,9 +139,7 @@ struct BackgroundTexture class GLToolbar { public: -#if ENABLE_SVG_ICONS static const float Default_Icons_Size; -#endif // ENABLE_SVG_ICONS enum EType : unsigned char { @@ -201,12 +174,8 @@ public: float border; float separator_size; float gap_size; -#if ENABLE_SVG_ICONS float icons_size; float scale; -#else - float icons_scale; -#endif // ENABLE_SVG_ICONS float width; float height; @@ -219,16 +188,10 @@ private: typedef std::vector ItemsList; EType m_type; -#if ENABLE_SVG_ICONS std::string m_name; -#endif // ENABLE_SVG_ICONS bool m_enabled; -#if ENABLE_SVG_ICONS mutable GLTexture m_icons_texture; mutable bool m_icons_texture_dirty; -#else - ItemsIconsTexture m_icons_texture; -#endif // ENABLE_SVG_ICONS BackgroundTexture m_background_texture; mutable Layout m_layout; @@ -251,18 +214,10 @@ private: std::string m_tooltip; public: -#if ENABLE_SVG_ICONS GLToolbar(EType type, const std::string& name); -#else - explicit GLToolbar(EType type); -#endif // ENABLE_SVG_ICONS ~GLToolbar(); -#if ENABLE_SVG_ICONS bool init(const BackgroundTexture::Metadata& background_texture); -#else - bool init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture); -#endif // ENABLE_SVG_ICONS Layout::EType get_layout_type() const; void set_layout_type(Layout::EType type); @@ -273,12 +228,8 @@ public: void set_border(float border); void set_separator_size(float size); void set_gap_size(float size); -#if ENABLE_SVG_ICONS void set_icons_size(float size); void set_scale(float scale); -#else - void set_icons_scale(float scale); -#endif // ENABLE_SVG_ICONS bool is_enabled() const; void set_enabled(bool enable); @@ -297,7 +248,6 @@ public: const std::string& get_tooltip() const { return m_tooltip; } - // returns true if any item changed its state bool update_items_state(); @@ -324,9 +274,7 @@ private: void render_horizontal(const GLCanvas3D& parent) const; void render_vertical(const GLCanvas3D& parent) const; -#if ENABLE_SVG_ICONS bool generate_icons_texture() const; -#endif // ENABLE_SVG_ICONS // returns true if any item changed its state bool update_items_visibility(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 030bd0146..7da3dec8a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -132,18 +132,12 @@ void GLGizmoBase::Grabber::render_face(float half_size) const glsafe(::glEnd()); } -#if ENABLE_SVG_ICONS GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) -#else -GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, unsigned int sprite_id) -#endif // ENABLE_SVG_ICONS : m_parent(parent) , m_group_id(-1) , m_state(Off) , m_shortcut_key(0) -#if ENABLE_SVG_ICONS , m_icon_filename(icon_filename) -#endif // ENABLE_SVG_ICONS , m_sprite_id(sprite_id) , m_hover_id(-1) , m_dragging(false) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index a29aaed3f..73c73a2c9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -89,9 +89,7 @@ protected: int m_group_id; EState m_state; int m_shortcut_key; -#if ENABLE_SVG_ICONS std::string m_icon_filename; -#endif // ENABLE_SVG_ICONS unsigned int m_sprite_id; int m_hover_id; bool m_dragging; @@ -102,11 +100,7 @@ protected: ImGuiWrapper* m_imgui; public: -#if ENABLE_SVG_ICONS GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoBase(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS virtual ~GLGizmoBase() {} bool init() { return on_init(); } @@ -122,9 +116,7 @@ public: int get_shortcut_key() const { return m_shortcut_key; } void set_shortcut_key(int key) { m_shortcut_key = key; } -#if ENABLE_SVG_ICONS const std::string& get_icon_filename() const { return m_icon_filename; } -#endif // ENABLE_SVG_ICONS bool is_activable(const Selection& selection) const { return on_is_activable(selection); } bool is_selectable() const { return on_is_selectable(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 17db953d4..b1c295098 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -19,13 +19,8 @@ const double GLGizmoCut::Offset = 10.0; const double GLGizmoCut::Margin = 20.0; const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 }; -#if ENABLE_SVG_ICONS GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#else -GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, unsigned int sprite_id) - : GLGizmoBase(parent, sprite_id) -#endif // ENABLE_SVG_ICONS , m_cut_z(0.0) , m_max_z(0.0) , m_keep_upper(true) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index fd4e8d8dc..79a7c58e2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -23,11 +23,7 @@ class GLGizmoCut : public GLGizmoBase bool m_rotate_lower; public: -#if ENABLE_SVG_ICONS GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoCut(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS protected: virtual bool on_init(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index ec991a241..6bb81a703 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -9,13 +9,8 @@ namespace Slic3r { namespace GUI { -#if ENABLE_SVG_ICONS GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#else -GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent, unsigned int sprite_id) - : GLGizmoBase(parent, sprite_id) -#endif // ENABLE_SVG_ICONS , m_normal(Vec3d::Zero()) , m_starting_center(Vec3d::Zero()) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index 1bd17e5ef..926dc3457 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -37,11 +37,7 @@ private: bool is_plane_update_necessary() const; public: -#if ENABLE_SVG_ICONS GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoFlatten(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS void set_flattening_data(const ModelObject* model_object); Vec3d get_flattening_normal() const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index a2ea738f5..b97f578b3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -10,13 +10,8 @@ namespace GUI { const double GLGizmoMove3D::Offset = 10.0; -#if ENABLE_SVG_ICONS GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#else -GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, unsigned int sprite_id) - : GLGizmoBase(parent, sprite_id) -#endif // ENABLE_SVG_ICONS , m_displacement(Vec3d::Zero()) , m_snap_step(1.0) , m_starting_drag_position(Vec3d::Zero()) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index ddab2b777..771496780 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -22,11 +22,7 @@ class GLGizmoMove3D : public GLGizmoBase GLUquadricObj* m_quadric; public: -#if ENABLE_SVG_ICONS GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoMove3D(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS virtual ~GLGizmoMove3D(); double get_snap_step(double step) const { return m_snap_step; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 68b9a8c33..f84c3886d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -19,11 +19,7 @@ const unsigned int GLGizmoRotate::SnapRegionsCount = 8; const float GLGizmoRotate::GrabberOffset = 0.15f; // in percent of radius GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) -#if ENABLE_SVG_ICONS : GLGizmoBase(parent, "", -1) -#else - : GLGizmoBase(parent, -1) -#endif // ENABLE_SVG_ICONS , m_axis(axis) , m_angle(0.0) , m_quadric(nullptr) @@ -40,11 +36,7 @@ GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) } GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other) -#if ENABLE_SVG_ICONS : GLGizmoBase(other.m_parent, other.m_icon_filename, other.m_sprite_id) -#else - : GLGizmoBase(other.m_parent, other.m_sprite_id) -#endif // ENABLE_SVG_ICONS , m_axis(other.m_axis) , m_angle(other.m_angle) , m_quadric(nullptr) @@ -417,13 +409,8 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, cons return transform(mouse_ray, m).intersect_plane(0.0); } -#if ENABLE_SVG_ICONS GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#else -GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, unsigned int sprite_id) - : GLGizmoBase(parent, sprite_id) -#endif // ENABLE_SVG_ICONS { m_gizmos.emplace_back(parent, GLGizmoRotate::X); m_gizmos.emplace_back(parent, GLGizmoRotate::Y); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index c65dee4d8..d2e564966 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -76,11 +76,7 @@ class GLGizmoRotate3D : public GLGizmoBase std::vector m_gizmos; public: -#if ENABLE_SVG_ICONS GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoRotate3D(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS Vec3d get_rotation() const { return Vec3d(m_gizmos[X].get_angle(), m_gizmos[Y].get_angle(), m_gizmos[Z].get_angle()); } void set_rotation(const Vec3d& rotation) { m_gizmos[X].set_angle(rotation(0)); m_gizmos[Y].set_angle(rotation(1)); m_gizmos[Z].set_angle(rotation(2)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index ca5383b0d..d30ceb092 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -13,13 +13,8 @@ namespace GUI { const float GLGizmoScale3D::Offset = 5.0f; -#if ENABLE_SVG_ICONS GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#else -GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, unsigned int sprite_id) - : GLGizmoBase(parent, sprite_id) -#endif // ENABLE_SVG_ICONS , m_scale(Vec3d::Ones()) , m_offset(Vec3d::Zero()) , m_snap_step(0.05) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index 3b0717f04..16307165f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -32,11 +32,7 @@ class GLGizmoScale3D : public GLGizmoBase StartingData m_starting; public: -#if ENABLE_SVG_ICONS GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoScale3D(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS double get_snap_step(double step) const { return m_snap_step; } void set_snap_step(double step) { m_snap_step = step; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 7e2b558d9..7b6cb0cc2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -19,13 +19,8 @@ namespace Slic3r { namespace GUI { -#if ENABLE_SVG_ICONS GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#else -GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, unsigned int sprite_id) - : GLGizmoBase(parent, sprite_id) -#endif // ENABLE_SVG_ICONS , m_quadric(nullptr) , m_its(nullptr) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 30238cc9d..f4b2fbb0e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -58,11 +58,7 @@ private: }; public: -#if ENABLE_SVG_ICONS GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); -#else - GLGizmoSlaSupports(GLCanvas3D& parent, unsigned int sprite_id); -#endif // ENABLE_SVG_ICONS virtual ~GLGizmoSlaSupports(); void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c9005807d..315027dad 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -12,17 +12,12 @@ namespace Slic3r { namespace GUI { -#if ENABLE_SVG_ICONS - const float GLGizmosManager::Default_Icons_Size = 64; -#endif // ENABLE_SVG_ICONS +const float GLGizmosManager::Default_Icons_Size = 64; GLGizmosManager::GLGizmosManager() : m_enabled(false) -#if ENABLE_SVG_ICONS , m_icons_texture_dirty(true) -#endif // ENABLE_SVG_ICONS , m_current(Undefined) -#if ENABLE_SVG_ICONS , m_overlay_icons_size(Default_Icons_Size) , m_overlay_scale(1.0f) , m_overlay_border(5.0f) @@ -30,11 +25,6 @@ GLGizmosManager::GLGizmosManager() , m_tooltip("") { } -#else -{ - set_overlay_scale(1.0); -} -#endif // ENABLE_SVG_ICONS GLGizmosManager::~GLGizmosManager() { @@ -43,20 +33,6 @@ GLGizmosManager::~GLGizmosManager() bool GLGizmosManager::init(GLCanvas3D& parent) { -#if !ENABLE_SVG_ICONS - m_icons_texture.metadata.filename = "gizmos.png"; - m_icons_texture.metadata.icon_size = 64; - - if (!m_icons_texture.metadata.filename.empty()) - { - if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false, true)) - { - reset(); - return false; - } - } -#endif // !ENABLE_SVG_ICONS - m_background_texture.metadata.filename = "toolbar_background.png"; m_background_texture.metadata.left = 16; m_background_texture.metadata.top = 16; @@ -72,11 +48,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) } } -#if ENABLE_SVG_ICONS GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "move.svg", 0); -#else - GLGizmoBase* gizmo = new GLGizmoMove3D(parent, 0); -#endif // ENABLE_SVG_ICONS if (gizmo == nullptr) return false; @@ -85,11 +57,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Move, gizmo)); -#if ENABLE_SVG_ICONS gizmo = new GLGizmoScale3D(parent, "scale.svg", 1); -#else - gizmo = new GLGizmoScale3D(parent, 1); -#endif // ENABLE_SVG_ICONS if (gizmo == nullptr) return false; @@ -98,11 +66,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); -#if ENABLE_SVG_ICONS gizmo = new GLGizmoRotate3D(parent, "rotate.svg", 2); -#else - gizmo = new GLGizmoRotate3D(parent, 2); -#endif // ENABLE_SVG_ICONS if (gizmo == nullptr) { reset(); @@ -117,11 +81,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); -#if ENABLE_SVG_ICONS gizmo = new GLGizmoFlatten(parent, "place.svg", 3); -#else - gizmo = new GLGizmoFlatten(parent, 3); -#endif // ENABLE_SVG_ICONS if (gizmo == nullptr) return false; @@ -132,11 +92,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); -#if ENABLE_SVG_ICONS gizmo = new GLGizmoCut(parent, "cut.svg", 4); -#else - gizmo = new GLGizmoCut(parent, 4); -#endif // ENABLE_SVG_ICONS if (gizmo == nullptr) return false; @@ -147,11 +103,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); -#if ENABLE_SVG_ICONS gizmo = new GLGizmoSlaSupports(parent, "sla_supports.svg", 5); -#else - gizmo = new GLGizmoSlaSupports(parent, 5); -#endif // ENABLE_SVG_ICONS if (gizmo == nullptr) return false; @@ -165,7 +117,6 @@ bool GLGizmosManager::init(GLCanvas3D& parent) return true; } -#if ENABLE_SVG_ICONS void GLGizmosManager::set_overlay_icon_size(float size) { if (m_overlay_icons_size != size) @@ -174,21 +125,14 @@ void GLGizmosManager::set_overlay_icon_size(float size) m_icons_texture_dirty = true; } } -#endif // ENABLE_SVG_ICONS void GLGizmosManager::set_overlay_scale(float scale) { -#if ENABLE_SVG_ICONS if (m_overlay_scale != scale) { m_overlay_scale = scale; m_icons_texture_dirty = true; } -#else - m_overlay_icons_scale = scale; - m_overlay_border = 5.0f * scale; - m_overlay_gap_y = 5.0f * scale; -#endif // ENABLE_SVG_ICONS } void GLGizmosManager::refresh_on_off_state(const Selection& selection) @@ -526,10 +470,8 @@ void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& if (!m_enabled) return; -#if ENABLE_SVG_ICONS if (m_icons_texture_dirty) generate_icons_texture(); -#endif // ENABLE_SVG_ICONS do_render_overlay(canvas, selection); } @@ -935,11 +877,7 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio float height = get_total_overlay_height(); float width = get_total_overlay_width(); -#if ENABLE_SVG_ICONS float scaled_border = m_overlay_border * m_overlay_scale * inv_zoom; -#else - float scaled_border = m_overlay_border * inv_zoom; -#endif // ENABLE_SVG_ICONS float top_x = (-0.5f * cnv_w) * inv_zoom; float top_y = (0.5f * height) * inv_zoom; @@ -1015,7 +953,6 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio } } -#if ENABLE_SVG_ICONS top_x += scaled_border; top_y -= scaled_border; float scaled_gap_y = m_overlay_gap_y * m_overlay_scale * inv_zoom; @@ -1027,21 +964,9 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio unsigned int tex_height = m_icons_texture.get_height(); float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f; float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f; -#else - top_x += m_overlay_border * inv_zoom; - top_y -= m_overlay_border * inv_zoom; - float scaled_gap_y = m_overlay_gap_y * inv_zoom; - - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale * inv_zoom; - unsigned int icons_texture_id = m_icons_texture.texture.get_id(); - unsigned int texture_size = m_icons_texture.texture.get_width(); - float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f; -#endif // ENABLE_SVG_ICONS - -#if ENABLE_SVG_ICONS + if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; -#endif // ENABLE_SVG_ICONS for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { @@ -1051,78 +976,44 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio unsigned int sprite_id = it->second->get_sprite_id(); GLGizmoBase::EState state = it->second->get_state(); -#if ENABLE_SVG_ICONS float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width; float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height; float v_top = sprite_id * v_icon_size; float u_left = state * u_icon_size; float v_bottom = v_top + v_icon_size; float u_right = u_left + u_icon_size; -#else - float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size; - float v_top = sprite_id * uv_icon_size; - float u_left = state * uv_icon_size; - float v_bottom = v_top + uv_icon_size; - float u_right = u_left + uv_icon_size; -#endif // ENABLE_SVG_ICONS GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); if (it->second->get_state() == GLGizmoBase::On) { float toolbar_top = (float)cnv_h - canvas.get_view_toolbar_height(); -#if ENABLE_SVG_ICONS it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); -#else - it->second->render_input_window(2.0f * m_overlay_border + scaled_icons_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); -#endif // ENABLE_SVG_ICONS } -#if ENABLE_SVG_ICONS top_y -= scaled_stride_y; -#else - top_y -= (scaled_icons_size + scaled_gap_y); -#endif // ENABLE_SVG_ICONS } } float GLGizmosManager::get_total_overlay_height() const { -#if ENABLE_SVG_ICONS float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; float scaled_border = m_overlay_border * m_overlay_scale; float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; float scaled_stride_y = scaled_icons_size + scaled_gap_y; float height = 2.0f * scaled_border; -#else - float height = 2.0f * m_overlay_border; - - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; -#if ENABLE_SVG_ICONS height += scaled_stride_y; -#else - height += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS } -#if ENABLE_SVG_ICONS return height - scaled_gap_y; -#else - return height - m_overlay_gap_y; -#endif // ENABLE_SVG_ICONS } float GLGizmosManager::get_total_overlay_width() const { -#if ENABLE_SVG_ICONS return (2.0f * m_overlay_border + m_overlay_icons_size) * m_overlay_scale; -#else - return (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale + 2.0f * m_overlay_border; -#endif // ENABLE_SVG_ICONS } GLGizmoBase* GLGizmosManager::get_current() const @@ -1131,7 +1022,6 @@ GLGizmoBase* GLGizmosManager::get_current() const return (it != m_gizmos.end()) ? it->second : nullptr; } -#if ENABLE_SVG_ICONS bool GLGizmosManager::generate_icons_texture() const { std::string path = resources_dir() + "/icons/"; @@ -1157,7 +1047,6 @@ bool GLGizmosManager::generate_icons_texture() const return res; } -#endif // ENABLE_SVG_ICONS void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) { @@ -1167,27 +1056,18 @@ void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& float cnv_h = (float)canvas.get_canvas_size().get_height(); float height = get_total_overlay_height(); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; float scaled_border = m_overlay_border * m_overlay_scale; float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; float scaled_stride_y = scaled_icons_size + scaled_gap_y; float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; -#if ENABLE_SVG_ICONS bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#else - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#endif // ENABLE_SVG_ICONS if (it->second->is_activable(selection) && inside) { if ((it->second->get_state() == GLGizmoBase::On)) @@ -1204,11 +1084,7 @@ void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& else it->second->set_state(GLGizmoBase::Off); -#if ENABLE_SVG_ICONS top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS } GizmosMap::iterator it = m_gizmos.find(m_current); @@ -1227,38 +1103,25 @@ std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const float cnv_h = (float)canvas.get_canvas_size().get_height(); float height = get_total_overlay_height(); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; float scaled_border = m_overlay_border * m_overlay_scale; float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; float scaled_stride_y = scaled_icons_size + scaled_gap_y; float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; -#if ENABLE_SVG_ICONS bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#else - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#endif // ENABLE_SVG_ICONS if (inside) name = it->second->get_name(); if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On)) it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); -#if ENABLE_SVG_ICONS top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS } return name; @@ -1272,34 +1135,21 @@ bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec float cnv_h = (float)canvas.get_canvas_size().get_height(); float height = get_total_overlay_height(); -#if ENABLE_SVG_ICONS float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; float scaled_border = m_overlay_border * m_overlay_scale; float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; float scaled_stride_y = scaled_icons_size + scaled_gap_y; float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; -#if ENABLE_SVG_ICONS if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) -#else - if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) -#endif // ENABLE_SVG_ICONS return true; -#if ENABLE_SVG_ICONS top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS } return false; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 1e42a29e6..87be7da41 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -46,9 +46,7 @@ public: class GLGizmosManager { public: -#if ENABLE_SVG_ICONS static const float Default_Icons_Size; -#endif // ENABLE_SVG_ICONS enum EType : unsigned char { @@ -66,21 +64,13 @@ private: bool m_enabled; typedef std::map GizmosMap; GizmosMap m_gizmos; -#if ENABLE_SVG_ICONS mutable GLTexture m_icons_texture; mutable bool m_icons_texture_dirty; -#else - ItemsIconsTexture m_icons_texture; -#endif // ENABLE_SVG_ICONS BackgroundTexture m_background_texture; EType m_current; -#if ENABLE_SVG_ICONS float m_overlay_icons_size; float m_overlay_scale; -#else - float m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS float m_overlay_border; float m_overlay_gap_y; @@ -109,9 +99,7 @@ public: bool is_enabled() const { return m_enabled; } void set_enabled(bool enable) { m_enabled = enable; } -#if ENABLE_SVG_ICONS void set_overlay_icon_size(float size); -#endif // ENABLE_SVG_ICONS void set_overlay_scale(float scale); void refresh_on_off_state(const Selection& selection); @@ -173,9 +161,7 @@ private: GLGizmoBase* get_current() const; -#if ENABLE_SVG_ICONS bool generate_icons_texture() const; -#endif // ENABLE_SVG_ICONS void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2988278d7..402acd59c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1736,11 +1736,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) })) , sidebar(new Sidebar(q)) , delayed_scene_refresh(false) -#if ENABLE_SVG_ICONS , view_toolbar(GLToolbar::Radio, "View") -#else - , view_toolbar(GLToolbar::Radio) -#endif // ENABLE_SVG_ICONS , m_project_filename(wxEmptyString) { this->q->SetFont(Slic3r::GUI::wxGetApp().normal_font()); @@ -3395,12 +3391,6 @@ bool Plater::priv::complit_init_part_menu() void Plater::priv::init_view_toolbar() { -#if !ENABLE_SVG_ICONS - ItemsIconsTexture::Metadata icons_data; - icons_data.filename = "view_toolbar.png"; - icons_data.icon_size = 64; -#endif // !ENABLE_SVG_ICONS - BackgroundTexture::Metadata background_data; background_data.filename = "toolbar_background.png"; background_data.left = 16; @@ -3408,11 +3398,7 @@ void Plater::priv::init_view_toolbar() background_data.right = 16; background_data.bottom = 16; -#if ENABLE_SVG_ICONS if (!view_toolbar.init(background_data)) -#else - if (!view_toolbar.init(icons_data, background_data)) -#endif // ENABLE_SVG_ICONS return; view_toolbar.set_layout_orientation(GLToolbar::Layout::Bottom); @@ -3422,9 +3408,7 @@ void Plater::priv::init_view_toolbar() GLToolbarItem::Data item; item.name = "3D"; -#if ENABLE_SVG_ICONS item.icon_filename = "editor.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("3D editor view")) + " [" + GUI::shortkey_ctrl_prefix() + "5]"; item.sprite_id = 0; item.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; @@ -3433,9 +3417,7 @@ void Plater::priv::init_view_toolbar() return; item.name = "Preview"; -#if ENABLE_SVG_ICONS item.icon_filename = "preview.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Preview")) + " [" + GUI::shortkey_ctrl_prefix() + "6]"; item.sprite_id = 1; item.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; -- cgit v1.2.3 From aed6acc073111d8d6134705e36894aedffba536c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 11 Jul 2019 18:42:02 +0200 Subject: Add take_snapshot for layers range editing actions --- src/slic3r/GUI/GUI_ObjectList.cpp | 37 +++++++++++++++++++++++++++++++------ src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 14 +++++++------- 3 files changed, 39 insertions(+), 14 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 360318413..dc4bb8795 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1756,6 +1756,8 @@ void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item) is_layer_settings && opt_cnt == 2 && m_config->has("extruder") && m_config->has("layer_height")) return; + take_snapshot(_(L("Delete Settings"))); + int extruder = -1; if (m_config->has("extruder")) extruder = m_config->option("extruder")->value; @@ -1793,6 +1795,8 @@ void ObjectList::del_layer_from_object(const int obj_idx, const t_layer_height_r const auto del_range = object(obj_idx)->layer_config_ranges.find(layer_range); if (del_range == object(obj_idx)->layer_config_ranges.end()) return; + + take_snapshot(_(L("Delete Layers Range"))); object(obj_idx)->layer_config_ranges.erase(del_range); @@ -1923,8 +1927,10 @@ void ObjectList::layers_editing() t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; // set some default value - if (ranges.empty()) + if (ranges.empty()) { + take_snapshot(_(L("Add Layers"))); ranges[{ 0.0f, 2.0f }] = get_default_layer_config(obj_idx); + } // create layer root item layers_item = add_layer_root_item(obj_item); @@ -1956,6 +1962,7 @@ wxDataViewItem ObjectList::add_layer_root_item(const wxDataViewItem obj_item) for (const auto range : object(obj_idx)->layer_config_ranges) add_layer_item(range.first, layers_item); + Expand(layers_item); return layers_item; } @@ -2406,6 +2413,8 @@ void ObjectList::add_layer_range_after_current(const t_layer_height_range& curre if (current_range == last_range) { + take_snapshot(_(L("Add New Layers Range"))); + const t_layer_height_range& new_range = { last_range.second, last_range.second + 2.0f }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item); @@ -2433,22 +2442,28 @@ void ObjectList::add_layer_range_after_current(const t_layer_height_range& curre t_layer_height_range new_range = { midl_layer, next_range.second }; + take_snapshot(_(L("Add New Layers Range"))); + suppress_snapshots(); + + // create new 2 layers instead of deleted one + // delete old layer wxDataViewItem layer_item = m_objects_model->GetItemByLayerRange(obj_idx, next_range); del_subobject_item(layer_item); - // create new 2 layers instead of deleted one - ranges[new_range] = old_config; add_layer_item(new_range, layers_item, layer_idx); new_range = { current_range.second, midl_layer }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item, layer_idx); + allow_snapshots(); } else { + take_snapshot(_(L("Add New Layers Range"))); + const t_layer_height_range new_range = { current_range.second, next_range.first }; ranges[new_range] = get_default_layer_config(obj_idx); add_layer_item(new_range, layers_item, layer_idx); @@ -2477,8 +2492,10 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, config.opt_int("extruder"), layer_idx); - if (config.keys().size() > 2) - select_item(m_objects_model->AddSettingsChild(layer_item)); + if (config.keys().size() > 2) { + m_objects_model->AddSettingsChild(layer_item); + Expand(layer_item); + } } bool ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) @@ -2508,6 +2525,8 @@ bool ObjectList::edit_layer_range(const t_layer_height_range& range, const t_lay const int obj_idx = get_selected_obj_idx(); if (obj_idx < 0) return false; + take_snapshot(_(L("Edit Layers Range"))); + const ItemType sel_type = m_objects_model->GetItemType(GetSelection()); t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; @@ -3417,11 +3436,13 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const wxGetApp().plater()->update(); } -void ObjectList::recreate_object_list() +void ObjectList::update_after_undo_redo() { m_prevent_list_events = true; m_prevent_canvas_selection_update = true; + suppress_snapshots(); + // Unselect all objects before deleting them, so that no change of selection is emitted during deletion. this->UnselectAll(); m_objects_model->DeleteAll(); @@ -3432,10 +3453,14 @@ void ObjectList::recreate_object_list() ++obj_idx; } + allow_snapshots(); + #ifndef __WXOSX__ selection_changed(); #endif /* __WXOSX__ */ + update_selections(); + m_prevent_canvas_selection_update = false; m_prevent_list_events = false; } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index a5a9c2138..34efa9025 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -335,7 +335,7 @@ public: void msw_rescale(); - void recreate_object_list(); + void update_after_undo_redo(); private: #ifdef __WXOSX__ diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e826d748e..9551524d4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1280,7 +1280,7 @@ struct Plater::priv PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; Slic3r::UndoRedo::Stack undo_redo_stack; - bool m_prevent_snapshots = false; /* Used for avoid of excess "snapshoting". + int m_prevent_snapshots = 0; /* Used for avoid of excess "snapshoting". * Like for "delete selected" or "set numbers of copies" * we should call tack_snapshot just ones * instead of calls for each action separately @@ -1587,8 +1587,9 @@ struct Plater::priv void take_snapshot(const std::string& snapshot_name) { - if (this->m_prevent_snapshots) + if (this->m_prevent_snapshots > 0) return; + assert(this->m_prevent_snapshots >= 0); this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); } void take_snapshot(const wxString& snapshot_name) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data())); } @@ -1597,8 +1598,8 @@ struct Plater::priv void redo(); void undo_to(size_t time_to_load); void redo_to(size_t time_to_load); - void suppress_snapshots() { this->m_prevent_snapshots = true; } - void allow_snapshots() { this->m_prevent_snapshots = false; } + void suppress_snapshots() { this->m_prevent_snapshots++; } + void allow_snapshots() { this->m_prevent_snapshots--; } bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } void update_print_volume_state(); @@ -3611,9 +3612,8 @@ void Plater::priv::update_after_undo_redo() //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack.selection_deserialized().mode), this->undo_redo_stack.selection_deserialized().volumes_and_instances); - wxGetApp().obj_list()->recreate_object_list(); - wxGetApp().obj_list()->update_selections(); -// selection_changed(); + wxGetApp().obj_list()->update_after_undo_redo(); + //FIXME what about the state of the manipulators? //FIXME what about the focus? Cursor in the side panel? } -- cgit v1.2.3 From 6826e31e2a1c6fb519c47a58f6052d6d2335a0ea Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 11 Jul 2019 23:46:23 +0200 Subject: Some code refactoring for settings items --- src/slic3r/GUI/GUI_ObjectList.cpp | 144 ++++++++++++++++++++++++---------- src/slic3r/GUI/GUI_ObjectList.hpp | 10 ++- src/slic3r/GUI/GUI_ObjectSettings.cpp | 133 ++++++++++++++----------------- src/slic3r/GUI/GUI_ObjectSettings.hpp | 2 +- 4 files changed, 166 insertions(+), 123 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dc4bb8795..53c0c653e 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -25,7 +25,7 @@ namespace GUI wxDEFINE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent); // pt_FFF -FreqSettingsBundle FREQ_SETTINGS_BUNDLE_FFF = +SettingsBundle FREQ_SETTINGS_BUNDLE_FFF = { { L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } }, { L("Infill") , { "fill_density", "fill_pattern" } }, @@ -36,7 +36,7 @@ FreqSettingsBundle FREQ_SETTINGS_BUNDLE_FFF = }; // pt_SLA -FreqSettingsBundle FREQ_SETTINGS_BUNDLE_SLA = +SettingsBundle FREQ_SETTINGS_BUNDLE_SLA = { { L("Pad and Support") , { "supports_enable", "pad_enable" } } }; @@ -676,10 +676,7 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(object_item, wxString::FromUTF8(volume->name.c_str()), volume->type(), volume->get_mesh_errors_count()>0 , volume->config.has("extruder") ? volume->config.option("extruder")->value : 0); - auto opt_keys = volume->config.keys(); - if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder"))) - select_item(m_objects_model->AddSettingsChild(vol_item)); - + add_settings_item(vol_item, &volume->config); items.Add(vol_item); } @@ -991,7 +988,7 @@ std::vector ObjectList::get_options(const bool is_part) const std::vector& ObjectList::get_options_for_bundle(const wxString& bundle_name) { - const FreqSettingsBundle& bundle = printer_technology() == ptSLA ? + const SettingsBundle& bundle = printer_technology() == ptSLA ? FREQ_SETTINGS_BUNDLE_SLA : FREQ_SETTINGS_BUNDLE_FFF; for (auto& it : bundle) @@ -1001,7 +998,7 @@ const std::vector& ObjectList::get_options_for_bundle(const wxStrin } #if 0 // if "Quick menu" is selected - FreqSettingsBundle& bundle_quick = printer_technology() == ptSLA ? + SettingsBundle& bundle_quick = printer_technology() == ptSLA ? m_freq_settings_sla: m_freq_settings_fff; for (auto& it : bundle_quick) @@ -1077,7 +1074,7 @@ void ObjectList::get_settings_choice(const wxString& category_name) if (selection_cnt > 0) { // Add selected items to the "Quick menu" - FreqSettingsBundle& freq_settings = printer_technology() == ptSLA ? + SettingsBundle& freq_settings = printer_technology() == ptSLA ? m_freq_settings_sla : m_freq_settings_fff; bool changed_existing = false; @@ -1149,8 +1146,8 @@ void ObjectList::get_settings_choice(const wxString& category_name) } - // Add settings item for object - update_settings_item(); + // Add settings item for object/sub-object and show them + show_settings(add_settings_item(GetSelection(), m_config)); } void ObjectList::get_freq_settings_choice(const wxString& bundle_name) @@ -1186,13 +1183,21 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name) } } - // Add settings item for object - update_settings_item(); + // Add settings item for object/sub-object and show them + show_settings(add_settings_item(GetSelection(), m_config)); } -void ObjectList::update_settings_item() +void ObjectList::show_settings(const wxDataViewItem settings_item) { - auto item = GetSelection(); + if (!settings_item) + return; + + select_item(settings_item); + + // update object selection on Plater + if (!m_prevent_canvas_selection_update) + update_selections_on_canvas(); +/* auto item = GetSelection(); if (item) { if (m_objects_model->GetItemType(item) == itInstance) item = m_objects_model->GetTopParent(item); @@ -1204,12 +1209,14 @@ void ObjectList::update_settings_item() if (!m_prevent_canvas_selection_update) update_selections_on_canvas(); } - else { + else { + //# ys_FIXME ??? use case ??? auto panel = wxGetApp().sidebar().scrolled_panel(); panel->Freeze(); wxGetApp().obj_settings()->UpdateAndShow(true); panel->Thaw(); } + */ } wxMenu* ObjectList::append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type) { @@ -1520,7 +1527,7 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) { // Add default settings bundles - const FreqSettingsBundle& bundle = printer_technology() == ptFFF ? + const SettingsBundle& bundle = printer_technology() == ptFFF ? FREQ_SETTINGS_BUNDLE_FFF : FREQ_SETTINGS_BUNDLE_SLA; const int extruders_cnt = extruders_count(); @@ -1535,7 +1542,7 @@ void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) } #if 0 // Add "Quick" settings bundles - const FreqSettingsBundle& bundle_quick = printer_technology() == ptFFF ? + const SettingsBundle& bundle_quick = printer_technology() == ptFFF ? m_freq_settings_fff : m_freq_settings_sla; for (auto& it : bundle_quick) { @@ -1898,11 +1905,7 @@ void ObjectList::split() volume->config.option("extruder")->value : 0, false); // add settings to the part, if it has those - auto opt_keys = volume->config.keys(); - if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) { - select_item(m_objects_model->AddSettingsChild(vol_item)); - Expand(vol_item); - } + add_settings_item(vol_item, &volume->config); } if (parent == item) @@ -2148,6 +2151,77 @@ void ObjectList::part_selection_changed() panel.Thaw(); } +SettingsBundle ObjectList::get_item_settings_bundle(const DynamicPrintConfig* config, const bool is_layers_range_settings) +{ + auto opt_keys = config->keys(); + if (opt_keys.empty()) + return SettingsBundle(); + + update_opt_keys(opt_keys); // update options list according to print technology + + if (opt_keys.size() == 1 && opt_keys[0] == "extruder" || + is_layers_range_settings && opt_keys.size() == 2) + return SettingsBundle(); + + const int extruders_cnt = wxGetApp().extruders_edited_cnt(); + + SettingsBundle bundle; + for (auto& opt_key : opt_keys) + { + auto category = config->def()->get(opt_key)->category; + if (category.empty() || (category == "Extruders" && extruders_cnt == 1)) + continue; + + std::vector< std::string > new_category; + + auto& cat_opt = bundle.find(category) == bundle.end() ? new_category : bundle.at(category); + cat_opt.push_back(opt_key); + if (cat_opt.size() == 1) + bundle[category] = cat_opt; + } + + return bundle; +} + +wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const DynamicPrintConfig* config) +{ + wxDataViewItem ret = wxDataViewItem(0); + + if (!parent_item) + return ret; + + const bool is_layers_range_settings = m_objects_model->GetItemType(parent_item) == itLayer; + SettingsBundle cat_options = get_item_settings_bundle(config, is_layers_range_settings); + if (cat_options.empty()) + return ret; + + std::vector categories; + categories.reserve(cat_options.size()); + for (auto& cat : cat_options) + { + if (cat.second.size() == 1 && + (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) + continue; + + categories.push_back(cat.first); + } + + if (categories.empty()) + return ret; + + if (m_objects_model->GetItemType(parent_item) & itInstance) + parent_item = m_objects_model->GetTopParent(parent_item); + + ret = m_objects_model->IsSettingsItem(parent_item) ? parent_item : m_objects_model->GetSettingsItem(parent_item); + + if (!ret) ret = m_objects_model->AddSettingsChild(parent_item); + + m_objects_model->UpdateSettingsDigest(ret, categories); + Expand(parent_item); + + return ret; +} + void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) { auto model_object = (*m_objects)[obj_idx]; @@ -2167,13 +2241,7 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) !volume->config.has("extruder") ? 0 : volume->config.option("extruder")->value, false); - auto opt_keys = volume->config.keys(); - if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { - const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(vol_item); - if (call_selection_changed) - select_item(settings_item); - Expand(vol_item); - } + add_settings_item(vol_item, &volume->config); } Expand(item); } @@ -2183,13 +2251,7 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) increase_object_instances(obj_idx, model_object->instances.size()); // add settings to the object, if it has those - auto opt_keys = model_object->config.keys(); - if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { - const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(item); - if (call_selection_changed) - select_item(settings_item); - Expand(item); - } + add_settings_item(item, &model_object->config); // Add layers if it has add_layer_root_item(item); @@ -2491,11 +2553,7 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, range, config.opt_int("extruder"), layer_idx); - - if (config.keys().size() > 2) { - m_objects_model->AddSettingsChild(layer_item); - Expand(layer_item); - } + add_settings_item(layer_item, &config); } bool ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) @@ -3010,7 +3068,7 @@ void ObjectList::change_part_type() } else if (!settings_item && (new_type == ModelVolumeType::MODEL_PART || new_type == ModelVolumeType::PARAMETER_MODIFIER)) { - select_item(m_objects_model->AddSettingsChild(item)); + add_settings_item(item, &volume->config); } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 34efa9025..72bddeec8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -26,7 +26,7 @@ enum class ModelVolumeType : int; // FIXME: broken build on mac os because of this is missing: typedef std::vector t_config_option_keys; -typedef std::map> FreqSettingsBundle; +typedef std::map> SettingsBundle; // category -> vector ( option ; label ) typedef std::map< std::string, std::vector< std::pair > > settings_menu_hierarchy; @@ -152,8 +152,8 @@ class ObjectList : public wxDataViewCtrl wxDataViewItem m_last_selected_item {nullptr}; #if 0 - FreqSettingsBundle m_freq_settings_fff; - FreqSettingsBundle m_freq_settings_sla; + SettingsBundle m_freq_settings_fff; + SettingsBundle m_freq_settings_sla; #endif public: @@ -209,7 +209,7 @@ public: void get_settings_choice(const wxString& category_name); void get_freq_settings_choice(const wxString& bundle_name); - void update_settings_item(); + void show_settings(const wxDataViewItem settings_item); wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type); void append_menu_items_add_volume(wxMenu* menu); @@ -247,6 +247,7 @@ public: void layers_editing(); wxDataViewItem add_layer_root_item(const wxDataViewItem obj_item); + wxDataViewItem add_settings_item(wxDataViewItem parent_item, const DynamicPrintConfig* config); DynamicPrintConfig get_default_layer_config(const int obj_idx); bool get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); @@ -258,6 +259,7 @@ public: wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; + SettingsBundle get_item_settings_bundle(const DynamicPrintConfig* config, const bool is_layers_range_settings); void changed_object(const int obj_idx = -1) const; void part_selection_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index ab2614895..16c64360a 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -63,20 +63,28 @@ ObjectSettings::ObjectSettings(wxWindow* parent) : m_bmp_delete = ScalableBitmap(parent, "cross"); } -void ObjectSettings::update_settings_list() +bool ObjectSettings::update_settings_list() { m_settings_list_sizer->Clear(true); + m_og_settings.resize(0); auto objects_ctrl = wxGetApp().obj_list(); auto objects_model = wxGetApp().obj_list()->GetModel(); auto config = wxGetApp().obj_list()->config(); const auto item = objects_ctrl->GetSelection(); + + if (!item || !objects_model->IsSettingsItem(item) || !config || objects_ctrl->multiple_selection()) + return false; + const bool is_layers_range_settings = objects_model->GetItemType(objects_model->GetParent(item)) == itLayer; + SettingsBundle cat_options = objects_ctrl->get_item_settings_bundle(config, is_layers_range_settings); + + if (!cat_options.empty()) + { + std::vector categories; + categories.reserve(cat_options.size()); - if (item && !objects_ctrl->multiple_selection() && - config && objects_model->IsSettingsItem(item)) - { auto extra_column = [config, this](wxWindow* parent, const Line& line) { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line @@ -96,86 +104,61 @@ void ObjectSettings::update_settings_list() return btn; }; - std::map> cat_options; - auto opt_keys = config->keys(); - objects_ctrl->update_opt_keys(opt_keys); // update options list according to print technology - - m_og_settings.resize(0); - std::vector categories; - if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder"))// return; + for (auto& cat : cat_options) { - const int extruders_cnt = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : - wxGetApp().preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); - - for (auto& opt_key : opt_keys) { - auto category = config->def()->get(opt_key)->category; - if (category.empty() || - (category == "Extruders" && extruders_cnt == 1)) continue; - - std::vector< std::string > new_category; - - auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category); - cat_opt.push_back(opt_key); - if (cat_opt.size() == 1) - cat_options[category] = cat_opt; - } - - for (auto& cat : cat_options) { - if (cat.second.size() == 1 && - (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) + if (cat.second.size() == 1 && + (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) + continue; + + categories.push_back(cat.first); + + auto optgroup = std::make_shared(m_og->ctrl_parent(), _(cat.first), config, false, extra_column); + optgroup->label_width = 15; + optgroup->sidetext_width = 5.5; + + optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { + wxGetApp().obj_list()->changed_object(); }; + + // call back for rescaling of the extracolumn control + optgroup->rescale_extra_column_item = [this](wxWindow* win) { + auto *ctrl = dynamic_cast(win); + if (ctrl == nullptr) + return; + ctrl->SetBitmap_(m_bmp_delete); + }; + + const bool is_extruders_cat = cat.first == "Extruders"; + for (auto& opt : cat.second) + { + if (opt == "extruder" || is_layers_range_settings && opt == "layer_height") continue; - - auto optgroup = std::make_shared(m_og->ctrl_parent(), _(cat.first), config, false, extra_column); - optgroup->label_width = 15; - optgroup->sidetext_width = 5.5; - - optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { - wxGetApp().obj_list()->changed_object(); }; - - const bool is_extruders_cat = cat.first == "Extruders"; - for (auto& opt : cat.second) - { - if (opt == "extruder" || is_layers_range_settings && opt == "layer_height") - continue; - Option option = optgroup->get_option(opt); - option.opt.width = 12; - if (is_extruders_cat) - option.opt.max = wxGetApp().extruders_cnt(); - optgroup->append_single_option_line(option); - } - optgroup->reload_config(); - m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); - - // call back for rescaling of the extracolumn control - optgroup->rescale_extra_column_item = [this](wxWindow* win) { - auto *ctrl = dynamic_cast(win); - if (ctrl == nullptr) - return; - ctrl->SetBitmap_(m_bmp_delete); - }; - - m_og_settings.push_back(optgroup); - - categories.push_back(cat.first); + Option option = optgroup->get_option(opt); + option.opt.width = 12; + if (is_extruders_cat) + option.opt.max = wxGetApp().extruders_edited_cnt(); + optgroup->append_single_option_line(option); } - } + optgroup->reload_config(); - if (m_og_settings.empty()) { - objects_ctrl->select_item(objects_model->Delete(item)); + m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); + m_og_settings.push_back(optgroup); } - else { - if (!categories.empty()) - objects_model->UpdateSettingsDigest(item, categories); - } - } + + if (!categories.empty()) + objects_model->UpdateSettingsDigest(item, categories); + } + else + { + objects_ctrl->select_item(objects_model->Delete(item)); + return false; + } + + return true; } void ObjectSettings::UpdateAndShow(const bool show) { - if (show) - update_settings_list(); - - OG_Settings::UpdateAndShow(show); + OG_Settings::UpdateAndShow(show ? update_settings_list() : false); } void ObjectSettings::msw_rescale() diff --git a/src/slic3r/GUI/GUI_ObjectSettings.hpp b/src/slic3r/GUI/GUI_ObjectSettings.hpp index 3d49f13b7..01daa5622 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.hpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.hpp @@ -44,7 +44,7 @@ public: ObjectSettings(wxWindow* parent); ~ObjectSettings() {} - void update_settings_list(); + bool update_settings_list(); void UpdateAndShow(const bool show) override; void msw_rescale(); }; -- cgit v1.2.3 From 4d8a028262f2911327e371b7c2e4863fb75ecf5d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 12 Jul 2019 13:55:46 +0200 Subject: Finally fix for settings item selection --- src/slic3r/GUI/GUI_ObjectList.cpp | 52 ++++++++++++++++++++++------ src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 10 +++--- 3 files changed, 49 insertions(+), 14 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 53c0c653e..9e681257c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2183,6 +2183,7 @@ SettingsBundle ObjectList::get_item_settings_bundle(const DynamicPrintConfig* co return bundle; } +// Add new SettingsItem for parent_item if it doesn't exist, or just update a digest according to new config wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const DynamicPrintConfig* config) { wxDataViewItem ret = wxDataViewItem(0); @@ -3100,6 +3101,7 @@ bool ObjectList::has_multi_part_objects() return false; } +/* #lm_FIXME_delete_after_testing void ObjectList::update_settings_items() { m_prevent_canvas_selection_update = true; @@ -3125,22 +3127,52 @@ void ObjectList::update_settings_items() SetSelections(sel); m_prevent_canvas_selection_update = false; } +*/ +void ObjectList::update_and_show_object_settings_item() +{ + const wxDataViewItem item = GetSelection(); + if (!item) return; + + const wxDataViewItem& obj_item = m_objects_model->IsSettingsItem(item) ? m_objects_model->GetParent(item) : item; + select_item(add_settings_item(obj_item, &get_item_config(obj_item))); +} // Update settings item for item had it void ObjectList::update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections) { - const wxDataViewItem& settings_item = m_objects_model->GetSettingsItem(item); - select_item(settings_item ? settings_item : m_objects_model->AddSettingsChild(item)); + const wxDataViewItem old_settings_item = m_objects_model->GetSettingsItem(item); + const wxDataViewItem new_settings_item = add_settings_item(item, &get_item_config(item)); + + if (!new_settings_item && old_settings_item) + m_objects_model->Delete(old_settings_item); + + // if ols settings item was is selected area + if (selections.Index(old_settings_item) != wxNOT_FOUND) + { + // If settings item was just updated + if (old_settings_item == new_settings_item) + { + Sidebar& panel = wxGetApp().sidebar(); + panel.Freeze(); - // If settings item was deleted from the list, - // it's need to be deleted from selection array, if it was there - if (settings_item != m_objects_model->GetSettingsItem(item) && - selections.Index(settings_item) != wxNOT_FOUND) { - selections.Remove(settings_item); + // update settings list + wxGetApp().obj_settings()->UpdateAndShow(true); - // Select item, if settings_item doesn't exist for item anymore, but was selected - if (selections.Index(item) == wxNOT_FOUND) - selections.Add(item); + panel.Layout(); + panel.Thaw(); + } + else + // If settings item was deleted from the list, + // it's need to be deleted from selection array, if it was there + { + selections.Remove(old_settings_item); + + // Select item, if settings_item doesn't exist for item anymore, but was selected + if (selections.Index(item) == wxNOT_FOUND) { + selections.Add(item); + select_item(item); // to correct update of the SettingsList and ManipulationPanel sizers + } + } } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 72bddeec8..2d7e9f5f1 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -319,6 +319,7 @@ public: void last_volume_is_deleted(const int obj_idx); bool has_multi_part_objects(); void update_settings_items(); + void update_and_show_object_settings_item(); void update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections); void update_object_list_by_printer_technology(); void update_object_menu(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index a4a6d1459..028320982 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -928,10 +928,12 @@ RENDER_AGAIN: } if (value_changed) { // Update side panel - wxTheApp->CallAfter([]() { - wxGetApp().obj_settings()->UpdateAndShow(true); - wxGetApp().obj_list()->update_settings_items(); - }); +/* wxTheApp->CallAfter([]() { + * wxGetApp().obj_settings()->UpdateAndShow(true); + * wxGetApp().obj_list()->update_settings_items(); + * }); + * #lm_FIXME_delete_after_testing */ + wxGetApp().obj_list()->update_and_show_object_settings_item(); } bool generate = m_imgui->button(m_desc.at("auto_generate")); -- cgit v1.2.3 From de88db59180822ddffd3b94bbd7b370a4971f196 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 12 Jul 2019 15:36:01 +0200 Subject: #2616 - Added Recent projects item to File menu --- src/slic3r/GUI/AppConfig.cpp | 27 +++++++++++++++++++++++ src/slic3r/GUI/AppConfig.hpp | 3 +++ src/slic3r/GUI/MainFrame.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/MainFrame.hpp | 5 +++++ src/slic3r/GUI/Plater.cpp | 13 ++++++++--- src/slic3r/GUI/Plater.hpp | 1 + 6 files changed, 98 insertions(+), 3 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 3b6210058..dfdc79677 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -229,6 +229,33 @@ std::string AppConfig::get_last_dir() const return std::string(); } +std::vector AppConfig::get_recent_projects() const +{ + std::vector ret; + const auto it = m_storage.find("recent_projects"); + if (it != m_storage.end()) + { + for (const std::map::value_type& item : it->second) + { + ret.push_back(item.second); + } + } + return ret; +} + +void AppConfig::set_recent_projects(const std::vector& recent_projects) +{ + auto it = m_storage.find("recent_projects"); + if (it == m_storage.end()) + it = m_storage.insert(std::map>::value_type("recent_projects", std::map())).first; + + it->second.clear(); + for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i) + { + it->second[std::to_string(i + 1)] = recent_projects[i]; + } +} + void AppConfig::update_config_dir(const std::string &dir) { this->set("recent", "config_directory", dir); diff --git a/src/slic3r/GUI/AppConfig.hpp b/src/slic3r/GUI/AppConfig.hpp index 5af635a12..230a92294 100644 --- a/src/slic3r/GUI/AppConfig.hpp +++ b/src/slic3r/GUI/AppConfig.hpp @@ -122,6 +122,9 @@ public: // Does the config file exist? static bool exists(); + std::vector get_recent_projects() const; + void set_recent_projects(const std::vector& recent_projects); + private: // Map of section, name -> value std::map> m_storage; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d800f6f38..99389da41 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -35,6 +35,7 @@ namespace GUI { MainFrame::MainFrame() : DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "mainframe"), m_printhost_queue_dlg(new PrintHostQueueDialog(this)) + , m_recent_projects(9) { // Fonts were created by the DPIFrame constructor for the monitor, on which the window opened. wxGetApp().update_fonts(this); @@ -383,6 +384,40 @@ void MainFrame::init_menubar() append_menu_item(fileMenu, wxID_ANY, _(L("&Open Project")) + dots + "\tCtrl+O", _(L("Open a project file")), [this](wxCommandEvent&) { if (m_plater) m_plater->load_project(); }, menu_icon("open"), nullptr, [this](){return m_plater != nullptr; }, this); + + wxMenu* recent_projects_menu = new wxMenu(); + wxMenuItem* recent_projects_submenu = append_submenu(fileMenu, recent_projects_menu, wxID_ANY, _(L("Recent projects")), ""); + m_recent_projects.UseMenu(recent_projects_menu); + Bind(wxEVT_MENU, [this](wxCommandEvent& evt) { + size_t file_id = evt.GetId() - wxID_FILE1; + wxString filename = m_recent_projects.GetHistoryFile(file_id); + if (wxFileExists(filename)) + m_plater->load_project(filename); + else + { + wxMessageDialog msg(this, _(L("The selected project is no more available")), _(L("Error"))); + msg.ShowModal(); + + m_recent_projects.RemoveFileFromHistory(file_id); + std::vector recent_projects; + size_t count = m_recent_projects.GetCount(); + for (size_t i = 0; i < count; ++i) + { + recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); + } + wxGetApp().app_config->set_recent_projects(recent_projects); + wxGetApp().app_config->save(); + } + }, wxID_FILE1, wxID_FILE9); + + std::vector recent_projects = wxGetApp().app_config->get_recent_projects(); + for (const std::string& project : recent_projects) + { + m_recent_projects.AddFileToHistory(from_u8(project)); + } + + Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_recent_projects.GetCount() > 0); }, recent_projects_submenu->GetId()); + append_menu_item(fileMenu, wxID_ANY, _(L("&Save Project")) + "\tCtrl+S", _(L("Save current project file")), [this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(into_path(m_plater->get_project_filename(".3mf"))); }, menu_icon("save"), nullptr, [this](){return m_plater != nullptr && can_save(); }, this); @@ -1046,6 +1081,23 @@ void MainFrame::on_config_changed(DynamicPrintConfig* config) const m_plater->on_config_change(*config); // propagate config change events to the plater } +void MainFrame::add_to_recent_projects(const wxString& filename) +{ + if (wxFileExists(filename)) + { + m_recent_projects.AddFileToHistory(filename); + std::vector recent_projects; + size_t count = m_recent_projects.GetCount(); + for (size_t i = 0; i < count; ++i) + { + recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); + } + wxGetApp().app_config->set_recent_projects(recent_projects); + wxGetApp().app_config->save(); + } +} + +// // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. void MainFrame::update_ui_from_settings() diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 805b663bb..a41f33824 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,8 @@ class MainFrame : public DPIFrame // vector of a MenuBar items changeable in respect to printer technology std::vector m_changeable_menu_items; + wxFileHistory m_recent_projects; + protected: virtual void on_dpi_changed(const wxRect &suggested_rect); @@ -121,6 +124,8 @@ public: // Propagate changed configuration from the Tab to the Platter and save changes to the AppConfig void on_config_changed(DynamicPrintConfig* cfg) const ; + void add_to_recent_projects(const wxString& filename); + PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; } Plater* m_plater { nullptr }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 402acd59c..b99b3a6af 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3277,6 +3277,9 @@ void Plater::priv::set_project_filename(const wxString& filename) m_project_filename = from_path(full_path); wxGetApp().mainframe->update_title(); + + if (!filename.empty()) + wxGetApp().mainframe->add_to_recent_projects(filename); } bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/) @@ -3590,15 +3593,19 @@ void Plater::load_project() { wxString input_file; wxGetApp().load_project(this, input_file); + load_project(input_file); +} - if (input_file.empty()) +void Plater::load_project(const wxString& filename) +{ + if (filename.empty()) return; p->reset(); - p->set_project_filename(input_file); + p->set_project_filename(filename); std::vector input_paths; - input_paths.push_back(into_path(input_file)); + input_paths.push_back(into_path(filename)); load_files(input_paths); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 34fd7984e..9ba63461e 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -138,6 +138,7 @@ public: void new_project(); void load_project(); + void load_project(const wxString& filename); void add_model(); void extract_config_from_project(); -- cgit v1.2.3 From 44f0e387dcb42b279fb561238aa49fac00dc5bd3 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sat, 13 Jul 2019 10:37:21 +0200 Subject: Fix of #2621 --- src/slic3r/GUI/Plater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b99b3a6af..8c074709f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -496,7 +496,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : option = m_og->get_option("fill_density"); option.opt.label = L("Infill"); option.opt.width = 7/*6*/; - option.opt.sidetext = " "; + option.opt.sidetext = " "; line.append_option(option); m_brim_width = config->opt_float("brim_width"); @@ -507,7 +507,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : def.gui_type = ""; def.set_default_value(new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }); option = Option(def, "brim"); - option.opt.sidetext = " "; + option.opt.sidetext = ""; line.append_option(option); auto wiping_dialog_btn = [config, this](wxWindow* parent) { -- cgit v1.2.3 From a492360d198e5cee4bea21e6d1c44386ec3824a5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 15 Jul 2019 11:59:54 +0200 Subject: Fix of the merge - missing Undo / Redo toolbar buttons. --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c2948c262..a878527bb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3647,9 +3647,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "undo"; -#if ENABLE_SVG_ICONS item.icon_filename = "undo_toolbar.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.sprite_id = 11; item.left.toggable = false; @@ -3663,9 +3661,7 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "redo"; -#if ENABLE_SVG_ICONS item.icon_filename = "redo_toolbar.svg"; -#endif // ENABLE_SVG_ICONS item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.sprite_id = 12; item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; -- cgit v1.2.3 From d2a3a36013050cf0c7eaed9007a05556baea0b42 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 15 Jul 2019 15:51:25 +0200 Subject: Fix of the SLA Undo --- src/slic3r/GUI/GLCanvas3D.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a878527bb..a401cabba 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2016,9 +2016,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re assert(it != aux_volume_state.end() && it->geometry_id == key.geometry_id); if (it->new_geometry()) instances[istep].emplace_back(std::pair(instance_idx, print_instance_idx)); - else - // Recycling an old GLVolume. Update the Object/Instance indices into the current Model. - m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx); + else { + // Recycling an old GLVolume. Update the Object/Instance indices into the current Model. + m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx); + m_volumes.volumes[it->volume_idx]->set_instance_transformation(model_object->instances[instance_idx]->get_transformation()); + } } } -- cgit v1.2.3 From dc80616bf6b5f5232fe30d96dcfa024da83ab0b9 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 15 Jul 2019 17:09:06 +0200 Subject: Fixed a use-after-free problem in object list this was uncovered by ASAN when attempting to Delete All objects with multiple instances --- src/slic3r/GUI/wxExtensions.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 1def2915c..7e8a2d92d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -806,8 +806,12 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) if (node_parent) { if (node->m_type & (itInstanceRoot|itLayerRoot)) { - for (int i = node->GetChildCount() - 1; i >= (node->m_type & itInstanceRoot ? 1 : 0); i--) + // node can be deleted by the Delete, let's check its type while we safely can + bool is_instance_root = (node->m_type & itInstanceRoot); + + for (int i = node->GetChildCount() - 1; i >= (is_instance_root ? 1 : 0); i--) Delete(wxDataViewItem(node->GetNthChild(i))); + return parent; } -- cgit v1.2.3 From 21624f53058b1cdb8afba0a9c6eb97c1ad997b15 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 17 Jul 2019 08:38:48 +0200 Subject: Framework to serialize gizmos into undo/redo stack Serialization into undo/redo of Cut gizmo Refactoring of GLGizmosManager --- src/slic3r/GUI/GLCanvas3D.cpp | 36 ++--- src/slic3r/GUI/GLCanvas3D.hpp | 3 + src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 6 + src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 1 - src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 2 + src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 211 ++++++++++++++++++------------ src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 80 ++++++++--- src/slic3r/GUI/Plater.cpp | 25 ++-- 9 files changed, 226 insertions(+), 139 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a401cabba..9e05f60ad 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1719,7 +1719,7 @@ void GLCanvas3D::deselect_all() m_selection.set_mode(Selection::Instance); wxGetApp().obj_manipul()->set_dirty(); m_gizmos.reset_all_states(); - m_gizmos.update_data(*this); + m_gizmos.update_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); } @@ -2082,8 +2082,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_selection.volumes_changed(map_glvolume_old_to_new); } - m_gizmos.update_data(*this); - m_gizmos.refresh_on_off_state(m_selection); + m_gizmos.update_data(); + m_gizmos.refresh_on_off_state(); // Update the toolbar if (update_object_list) @@ -2323,7 +2323,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) if ((keyCode == WXK_ESCAPE) && _deactivate_undo_redo_toolbar_items()) return; - if (m_gizmos.on_char(evt, *this)) + if (m_gizmos.on_char(evt)) return; //#ifdef __APPLE__ @@ -2450,7 +2450,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) } else { - if (!m_gizmos.on_key(evt, *this)) + if (!m_gizmos.on_key(evt)) { if (evt.GetEventType() == wxEVT_KEY_UP) { if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) { @@ -2560,7 +2560,7 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) } // Inform gizmos about the event so they have the opportunity to react. - if (m_gizmos.on_mouse_wheel(evt, *this)) + if (m_gizmos.on_mouse_wheel(evt)) return; // Calculate the zoom delta and apply it to the current zoom factor @@ -2688,7 +2688,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) return; } - if (m_gizmos.on_mouse(evt, *this)) + if (m_gizmos.on_mouse(evt)) { if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) mouse_up_cleanup(); @@ -2815,9 +2815,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (m_selection.is_empty()) m_gizmos.reset_all_states(); else - m_gizmos.refresh_on_off_state(m_selection); + m_gizmos.refresh_on_off_state(); - m_gizmos.update_data(*this); + m_gizmos.update_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_dirty = true; } @@ -2985,9 +2985,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { // forces the selection of the volume m_selection.add(volume_idx); - m_gizmos.refresh_on_off_state(m_selection); + m_gizmos.refresh_on_off_state(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); - m_gizmos.update_data(*this); + m_gizmos.update_data(); wxGetApp().obj_manipul()->set_dirty(); // forces a frame render to update the view before the context menu is shown render(); @@ -3355,8 +3355,8 @@ void GLCanvas3D::set_camera_zoom(double zoom) void GLCanvas3D::update_gizmos_on_off_state() { set_as_dirty(); - m_gizmos.update_data(*this); - m_gizmos.refresh_on_off_state(get_selection()); + m_gizmos.update_data(); + m_gizmos.refresh_on_off_state(); } void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool focus_on) @@ -3762,7 +3762,7 @@ void GLCanvas3D::_picking_pass() const if (m_camera_clipping_plane.is_active()) ::glDisable(GL_CLIP_PLANE0); - m_gizmos.render_current_gizmo_for_picking_pass(m_selection); + m_gizmos.render_current_gizmo_for_picking_pass(); if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); @@ -4072,7 +4072,7 @@ void GLCanvas3D::_render_volumes_for_picking() const void GLCanvas3D::_render_current_gizmo() const { - m_gizmos.render_current_gizmo(m_selection); + m_gizmos.render_current_gizmo(); } void GLCanvas3D::_render_gizmos_overlay() const @@ -4088,7 +4088,7 @@ void GLCanvas3D::_render_gizmos_overlay() const m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment #endif /* __WXMSW__ */ - m_gizmos.render_overlay(*this, m_selection); + m_gizmos.render_overlay(); } void GLCanvas3D::_render_toolbar() const @@ -5661,9 +5661,9 @@ void GLCanvas3D::_update_selection_from_hover() if (m_selection.is_empty()) m_gizmos.reset_all_states(); else - m_gizmos.refresh_on_off_state(m_selection); + m_gizmos.refresh_on_off_state(); - m_gizmos.update_data(*this); + m_gizmos.update_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_dirty = true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index f5a53c6a5..6bb17da4a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -517,6 +517,9 @@ public: const Selection& get_selection() const { return m_selection; } Selection& get_selection() { return m_selection; } + const GLGizmosManager& get_gizmos_manager() const { return m_gizmos; } + GLGizmosManager& get_gizmos_manager() { return m_gizmos; } + void bed_shape_changed(); void set_clipping_plane(unsigned int id, const ClippingPlane& plane) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 7da3dec8a..ba0ea4825 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -132,6 +132,7 @@ void GLGizmoBase::Grabber::render_face(float half_size) const glsafe(::glEnd()); } + GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : m_parent(parent) , m_group_id(-1) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 73c73a2c9..88927aee2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -6,6 +6,7 @@ #include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/Selection.hpp" +#include class wxWindow; class GLUquadric; @@ -105,6 +106,9 @@ public: bool init() { return on_init(); } + void load(cereal::BinaryInputArchive& ar) { m_state = On; on_load(ar); } + void save(cereal::BinaryOutputArchive& ar) const { on_save(ar); } + std::string get_name() const { return on_get_name(); } int get_group_id() const { return m_group_id; } @@ -144,6 +148,8 @@ public: protected: virtual bool on_init() = 0; + virtual void on_load(cereal::BinaryInputArchive& ar) {} + virtual void on_save(cereal::BinaryOutputArchive& ar) const {} virtual std::string on_get_name() const = 0; virtual void on_set_state() {} virtual void on_set_hover_id() {} diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index b1c295098..52174d2d6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -28,7 +28,6 @@ GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, uns , m_rotate_lower(false) {} - bool GLGizmoCut::on_init() { m_grabbers.emplace_back(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 79a7c58e2..628bcf508 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -27,6 +27,8 @@ public: protected: virtual bool on_init(); + virtual void on_load(cereal::BinaryInputArchive& ar) { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } + virtual void on_save(cereal::BinaryOutputArchive& ar) const { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } virtual std::string on_get_name() const; virtual void on_set_state(); virtual bool on_is_activable(const Selection& selection) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 602235d4a..5922f9600 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -15,7 +15,8 @@ namespace GUI { const float GLGizmosManager::Default_Icons_Size = 64; GLGizmosManager::GLGizmosManager() - : m_enabled(false) + : m_parent(nullptr) + , m_enabled(false) , m_icons_texture_dirty(true) , m_current(Undefined) , m_overlay_icons_size(Default_Icons_Size) @@ -23,6 +24,7 @@ GLGizmosManager::GLGizmosManager() , m_overlay_border(5.0f) , m_overlay_gap_y(5.0f) , m_tooltip("") + , m_serializing(false) { } @@ -33,6 +35,8 @@ GLGizmosManager::~GLGizmosManager() bool GLGizmosManager::init(GLCanvas3D& parent) { + m_parent = &parent; + m_background_texture.metadata.filename = "toolbar_background.png"; m_background_texture.metadata.left = 16; m_background_texture.metadata.top = 16; @@ -135,12 +139,18 @@ void GLGizmosManager::set_overlay_scale(float scale) } } -void GLGizmosManager::refresh_on_off_state(const Selection& selection) +void GLGizmosManager::refresh_on_off_state() { + if (m_parent == nullptr) + return; + + if (m_serializing) + return; + GizmosMap::iterator it = m_gizmos.find(m_current); if ((it != m_gizmos.end()) && (it->second != nullptr)) { - if (!it->second->is_activable(selection)) + if (!it->second->is_activable(m_parent->get_selection())) { it->second->set_state(GLGizmoBase::Off); m_current = Undefined; @@ -153,6 +163,9 @@ void GLGizmosManager::reset_all_states() if (!m_enabled) return; + if (m_serializing) + return; + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if (it->second != nullptr) @@ -192,22 +205,22 @@ void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) } } -void GLGizmosManager::update(const Linef3& mouse_ray, const Selection& selection, const Point* mouse_pos) +void GLGizmosManager::update(const Linef3& mouse_ray, const Point* mouse_pos) { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos), selection); + curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos), m_parent->get_selection()); } -void GLGizmosManager::update_data(GLCanvas3D& canvas) +void GLGizmosManager::update_data() { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; - const Selection& selection = canvas.get_selection(); + const Selection& selection = m_parent->get_selection(); bool is_wipe_tower = selection.is_wipe_tower(); enable_grabber(Move, 2, !is_wipe_tower); @@ -228,7 +241,7 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) set_rotation(Vec3d::Zero()); ModelObject* model_object = selection.get_model()->objects[selection.get_object_idx()]; set_flattening_data(model_object); - set_sla_support_data(model_object, selection); + set_sla_support_data(model_object); } else if (selection.is_single_volume() || selection.is_single_modifier()) { @@ -236,7 +249,7 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) set_scale(volume->get_volume_scaling_factor()); set_rotation(Vec3d::Zero()); set_flattening_data(nullptr); - set_sla_support_data(nullptr, selection); + set_sla_support_data(nullptr); } else if (is_wipe_tower) { @@ -244,14 +257,14 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) set_scale(Vec3d::Ones()); set_rotation(Vec3d(0., 0., (M_PI/180.) * dynamic_cast(config.option("wipe_tower_rotation_angle"))->value)); set_flattening_data(nullptr); - set_sla_support_data(nullptr, selection); + set_sla_support_data(nullptr); } else { set_scale(Vec3d::Ones()); set_rotation(Vec3d::Zero()); set_flattening_data(selection.is_from_single_object() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr); - set_sla_support_data(nullptr, selection); + set_sla_support_data(nullptr); } } @@ -264,9 +277,13 @@ bool GLGizmosManager::is_running() const return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; } -bool GLGizmosManager::handle_shortcut(int key, const Selection& selection) +bool GLGizmosManager::handle_shortcut(int key) { - if (!m_enabled || selection.is_empty()) + if (!m_enabled || (m_parent == nullptr)) + return false; + + const Selection& selection = m_parent->get_selection(); + if (selection.is_empty()) return false; EType old_current = m_current; @@ -314,14 +331,14 @@ bool GLGizmosManager::is_dragging() const return (curr != nullptr) ? curr->is_dragging() : false; } -void GLGizmosManager::start_dragging(const Selection& selection) +void GLGizmosManager::start_dragging() { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->start_dragging(selection); + curr->start_dragging(m_parent->get_selection()); } void GLGizmosManager::stop_dragging() @@ -409,14 +426,14 @@ void GLGizmosManager::set_flattening_data(const ModelObject* model_object) reinterpret_cast(it->second)->set_flattening_data(model_object); } -void GLGizmosManager::set_sla_support_data(ModelObject* model_object, const Selection& selection) +void GLGizmosManager::set_sla_support_data(ModelObject* model_object) { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_sla_support_data(model_object, selection); + reinterpret_cast(it->second)->set_sla_support_data(model_object, m_parent->get_selection()); } // Returns true if the gizmo used the event to do something, false otherwise. @@ -445,39 +462,42 @@ ClippingPlane GLGizmosManager::get_sla_clipping_plane() const } -void GLGizmosManager::render_current_gizmo(const Selection& selection) const +void GLGizmosManager::render_current_gizmo() const { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->render(selection); + curr->render(m_parent->get_selection()); } -void GLGizmosManager::render_current_gizmo_for_picking_pass(const Selection& selection) const +void GLGizmosManager::render_current_gizmo_for_picking_pass() const { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->render_for_picking(selection); + curr->render_for_picking(m_parent->get_selection()); } -void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& selection) const +void GLGizmosManager::render_overlay() const { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; if (m_icons_texture_dirty) generate_icons_texture(); - do_render_overlay(canvas, selection); + do_render_overlay(); } -bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt, GLCanvas3D& canvas) +bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt) { + if (m_parent == nullptr) + return false; + bool processed = false; if (m_current == SlaSupports) { @@ -489,14 +509,15 @@ bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt, GLCanvas3D& canvas) return processed; } - - -bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) +bool GLGizmosManager::on_mouse(wxMouseEvent& evt) { + if (m_parent == nullptr) + return false; + Point pos(evt.GetX(), evt.GetY()); Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); - Selection& selection = canvas.get_selection(); + Selection& selection = m_parent->get_selection(); int selected_object_idx = selection.get_object_idx(); bool processed = false; @@ -512,7 +533,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) // mouse anywhere if (evt.Moving()) - m_tooltip = update_hover_state(canvas, mouse_pos); + m_tooltip = update_hover_state(mouse_pos); else if (evt.LeftUp()) m_mouse_capture.left = false; else if (evt.MiddleUp()) @@ -523,7 +544,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) // if the button down was done on this toolbar, prevent from dragging into the scene processed = true; - if (!overlay_contains_mouse(canvas, mouse_pos)) + if (!overlay_contains_mouse(mouse_pos)) { // mouse is outside the toolbar m_tooltip = ""; @@ -535,40 +556,40 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) processed = true; else if (!selection.is_empty() && grabber_contains_mouse()) { - update_data(canvas); + update_data(); selection.start_dragging(); - start_dragging(selection); + start_dragging(); if (m_current == Flatten) { // Rotate the object so the normal points downward: - canvas.do_flatten(get_flattening_normal(), "Place on Face"); + m_parent->do_flatten(get_flattening_normal(), "Gizmo - Place on Face"); wxGetApp().obj_manipul()->set_dirty(); } - canvas.set_as_dirty(); + m_parent->set_as_dirty(); processed = true; } } else if (evt.RightDown() && (selected_object_idx != -1) && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::RightDown)) // event was taken care of by the SlaSupports gizmo processed = true; - else if (evt.Dragging() && (canvas.get_move_volume_id() != -1) && (m_current == SlaSupports)) + else if (evt.Dragging() && (m_parent->get_move_volume_id() != -1) && (m_current == SlaSupports)) // don't allow dragging objects with the Sla gizmo on processed = true; else if (evt.Dragging() && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) { // the gizmo got the event and took some action, no need to do anything more here - canvas.set_as_dirty(); + m_parent->set_as_dirty(); processed = true; } else if (evt.Dragging() && is_dragging()) { - if (!canvas.get_wxglcanvas()->HasCapture()) - canvas.get_wxglcanvas()->CaptureMouse(); + if (!m_parent->get_wxglcanvas()->HasCapture()) + m_parent->get_wxglcanvas()->CaptureMouse(); - canvas.set_mouse_as_dragging(); - update(canvas.mouse_ray(pos), selection, &pos); + m_parent->set_mouse_as_dragging(); + update(m_parent->mouse_ray(pos), &pos); switch (m_current) { @@ -605,7 +626,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) break; } - canvas.set_as_dirty(); + m_parent->set_as_dirty(); processed = true; } else if (evt.LeftUp() && is_dragging()) @@ -614,18 +635,18 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { case Move: { - canvas.disable_regenerate_volumes(); - canvas.do_move("Gizmo-Move Object"); + m_parent->disable_regenerate_volumes(); + m_parent->do_move("Gizmo-Move Object"); break; } case Scale: { - canvas.do_scale("Gizmo-Scale Object"); + m_parent->do_scale("Gizmo-Scale Object"); break; } case Rotate: { - canvas.do_rotate("Gizmo-Rotate Object"); + m_parent->do_rotate("Gizmo-Rotate Object"); break; } default: @@ -633,25 +654,25 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) } stop_dragging(); - update_data(canvas); + update_data(); wxGetApp().obj_manipul()->set_dirty(); // Let the platter know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. - canvas.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); + m_parent->post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); // updates camera target constraints - canvas.refresh_camera_scene_box(); + m_parent->refresh_camera_scene_box(); processed = true; } - else if (evt.LeftUp() && (m_current == SlaSupports) && !canvas.is_mouse_dragging()) + else if (evt.LeftUp() && (m_current == SlaSupports) && !m_parent->is_mouse_dragging()) { // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither // object moving or selecting is suppressed in that case gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()); processed = true; } - else if (evt.LeftUp() && (m_current == Flatten) && ((canvas.get_first_hover_volume_idx() != -1) || grabber_contains_mouse())) + else if (evt.LeftUp() && (m_current == Flatten) && ((m_parent->get_first_hover_volume_idx() != -1) || grabber_contains_mouse())) { // to avoid to loose the selection when user clicks an object while the Flatten gizmo is active processed = true; @@ -663,24 +684,24 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) if (evt.LeftDown() || evt.LeftDClick()) { m_mouse_capture.left = true; - m_mouse_capture.parent = &canvas; + m_mouse_capture.parent = m_parent; processed = true; if (!selection.is_empty()) { - update_on_off_state(canvas, mouse_pos, selection); - update_data(canvas); - canvas.set_as_dirty(); + update_on_off_state(mouse_pos); + update_data(); + m_parent->set_as_dirty(); } } else if (evt.MiddleDown()) { m_mouse_capture.middle = true; - m_mouse_capture.parent = &canvas; + m_mouse_capture.parent = m_parent; } else if (evt.RightDown()) { m_mouse_capture.right = true; - m_mouse_capture.parent = &canvas; + m_mouse_capture.parent = m_parent; } else if (evt.LeftUp()) processed = true; @@ -689,8 +710,11 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) return processed; } -bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) +bool GLGizmosManager::on_char(wxKeyEvent& evt) { + if (m_parent == nullptr) + return false; + // see include/wx/defs.h enum wxKeyCode int keyCode = evt.GetKeyCode(); int ctrlMask = wxMOD_CONTROL; @@ -797,21 +821,24 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) if (!processed && !evt.HasModifiers()) { - if (handle_shortcut(keyCode, canvas.get_selection())) + if (handle_shortcut(keyCode)) { - update_data(canvas); + update_data(); processed = true; } } if (processed) - canvas.set_as_dirty(); + m_parent->set_as_dirty(); return processed; } -bool GLGizmosManager::on_key(wxKeyEvent& evt, GLCanvas3D& canvas) +bool GLGizmosManager::on_key(wxKeyEvent& evt) { + if (m_parent == nullptr) + return false; + const int keyCode = evt.GetKeyCode(); bool processed = false; @@ -836,23 +863,29 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt, GLCanvas3D& canvas) } // if (processed) -// canvas.set_cursor(GLCanvas3D::Standard); +// m_parent->set_cursor(GLCanvas3D::Standard); } else if (evt.GetEventType() == wxEVT_KEY_DOWN) { if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) && reinterpret_cast(get_current())->is_in_editing_mode()) { -// canvas.set_cursor(GLCanvas3D::Cross); +// m_parent->set_cursor(GLCanvas3D::Cross); processed = true; } } if (processed) - canvas.set_as_dirty(); + m_parent->set_as_dirty(); return processed; } +void GLGizmosManager::update_after_undo_redo() +{ + update_data(); + m_serializing = false; +} + void GLGizmosManager::reset() { for (GizmosMap::value_type& gizmo : m_gizmos) @@ -864,14 +897,16 @@ void GLGizmosManager::reset() m_gizmos.clear(); } -void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const +void GLGizmosManager::do_render_overlay() const { - if (m_gizmos.empty()) + if ((m_parent == nullptr) || m_gizmos.empty()) return; - float cnv_w = (float)canvas.get_canvas_size().get_width(); - float cnv_h = (float)canvas.get_canvas_size().get_height(); - float zoom = (float)canvas.get_camera().get_zoom(); + const Selection& selection = m_parent->get_selection(); + + float cnv_w = (float)m_parent->get_canvas_size().get_width(); + float cnv_h = (float)m_parent->get_canvas_size().get_height(); + float zoom = (float)m_parent->get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float height = get_total_overlay_height(); @@ -984,7 +1019,7 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); if (it->second->get_state() == GLGizmoBase::On) { - float toolbar_top = (float)cnv_h - canvas.get_view_toolbar_height(); + float toolbar_top = (float)cnv_h - m_parent->get_view_toolbar_height(); it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); } top_y -= scaled_stride_y; @@ -1047,12 +1082,14 @@ bool GLGizmosManager::generate_icons_texture() const return res; } -void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) +void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return; - float cnv_h = (float)canvas.get_canvas_size().get_height(); + const Selection& selection = m_parent->get_selection(); + + float cnv_h = (float)m_parent->get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; @@ -1091,16 +1128,16 @@ void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& it->second->set_state(GLGizmoBase::On); } -std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos) +std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) { std::string name = ""; - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return name; - const Selection& selection = canvas.get_selection(); + const Selection& selection = m_parent->get_selection(); - float cnv_h = (float)canvas.get_canvas_size().get_height(); + float cnv_h = (float)m_parent->get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; float scaled_border = m_overlay_border * m_overlay_scale; @@ -1126,12 +1163,12 @@ std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const return name; } -bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const +bool GLGizmosManager::overlay_contains_mouse(const Vec2d& mouse_pos) const { - if (!m_enabled) + if (!m_enabled || (m_parent == nullptr)) return false; - float cnv_h = (float)canvas.get_canvas_size().get_height(); + float cnv_h = (float)m_parent->get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 87be7da41..db73345ae 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -4,14 +4,13 @@ #include "slic3r/GUI/GLTexture.hpp" #include "slic3r/GUI/GLToolbar.hpp" #include "slic3r/GUI/Gizmos/GLGizmos.hpp" +#include "libslic3r/ObjectID.hpp" #include namespace Slic3r { namespace GUI { -class Selection; -class GLGizmoBase; class GLCanvas3D; class ClippingPlane; @@ -43,7 +42,7 @@ public: float get_height() const { return m_top - m_bottom; } }; -class GLGizmosManager +class GLGizmosManager : public Slic3r::ObjectBase { public: static const float Default_Icons_Size; @@ -61,6 +60,7 @@ public: }; private: + GLCanvas3D* m_parent; bool m_enabled; typedef std::map GizmosMap; GizmosMap m_gizmos; @@ -89,6 +89,7 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; + bool m_serializing; public: GLGizmosManager(); @@ -96,29 +97,59 @@ public: bool init(GLCanvas3D& parent); + template + void load(Archive& ar) + { + if (!m_enabled) + return; + + m_serializing = true; + + ar(m_current); + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + { + curr->set_state(GLGizmoBase::On); + curr->load(ar); + } + } + + template + void save(Archive& ar) const + { + if (!m_enabled) + return; + + ar(m_current); + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + curr->save(ar); + } + bool is_enabled() const { return m_enabled; } void set_enabled(bool enable) { m_enabled = enable; } void set_overlay_icon_size(float size); void set_overlay_scale(float scale); - void refresh_on_off_state(const Selection& selection); + void refresh_on_off_state(); void reset_all_states(); void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); - void update(const Linef3& mouse_ray, const Selection& selection, const Point* mouse_pos = nullptr); - void update_data(GLCanvas3D& canvas); + void update(const Linef3& mouse_ray, const Point* mouse_pos = nullptr); + void update_data(); - Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; EType get_current_type() const { return m_current; } bool is_running() const; - bool handle_shortcut(int key, const Selection& selection); + bool handle_shortcut(int key); bool is_dragging() const; - void start_dragging(const Selection& selection); + void start_dragging(); void stop_dragging(); Vec3d get_displacement() const; @@ -135,26 +166,28 @@ public: void set_flattening_data(const ModelObject* model_object); - void set_sla_support_data(ModelObject* model_object, const Selection& selection); + void set_sla_support_data(ModelObject* model_object); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false); ClippingPlane get_sla_clipping_plane() const; - void render_current_gizmo(const Selection& selection) const; - void render_current_gizmo_for_picking_pass(const Selection& selection) const; + void render_current_gizmo() const; + void render_current_gizmo_for_picking_pass() const; - void render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; + void render_overlay() const; const std::string& get_tooltip() const { return m_tooltip; } - bool on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas); - bool on_mouse_wheel(wxMouseEvent& evt, GLCanvas3D& canvas); - bool on_char(wxKeyEvent& evt, GLCanvas3D& canvas); - bool on_key(wxKeyEvent& evt, GLCanvas3D& canvas); + bool on_mouse(wxMouseEvent& evt); + bool on_mouse_wheel(wxMouseEvent& evt); + bool on_char(wxKeyEvent& evt); + bool on_key(wxKeyEvent& evt); + + void update_after_undo_redo(); private: void reset(); - void do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; + void do_render_overlay() const; float get_total_overlay_height() const; float get_total_overlay_width() const; @@ -163,13 +196,18 @@ private: bool generate_icons_texture() const; - void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); - std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos); - bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; + void update_on_off_state(const Vec2d& mouse_pos); + std::string update_hover_state(const Vec2d& mouse_pos); + bool overlay_contains_mouse(const Vec2d& mouse_pos) const; bool grabber_contains_mouse() const; }; } // namespace GUI } // namespace Slic3r +namespace cereal +{ + template struct specialize {}; +} + #endif // slic3r_GUI_GLGizmosManager_hpp_ diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f5f245471..c5a4ccead 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1633,8 +1633,8 @@ struct Plater::priv if (this->m_prevent_snapshots > 0) return; assert(this->m_prevent_snapshots >= 0); - this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection()); - } + this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager()); + } void take_snapshot(const wxString& snapshot_name) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data())); } int get_active_snapshot_index(); void undo(); @@ -3611,34 +3611,35 @@ int Plater::priv::get_active_snapshot_index() void Plater::priv::undo() { - if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection())) - this->update_after_undo_redo(); + if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager())) + this->update_after_undo_redo(); } void Plater::priv::redo() { - if (this->undo_redo_stack.redo(model)) - this->update_after_undo_redo(); + if (this->undo_redo_stack.redo(model, this->view3D->get_canvas3d()->get_gizmos_manager())) + this->update_after_undo_redo(); } void Plater::priv::undo_to(size_t time_to_load) { - if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection(), time_to_load)) - this->update_after_undo_redo(); + if (this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager(), time_to_load)) + this->update_after_undo_redo(); } void Plater::priv::redo_to(size_t time_to_load) { - if (this->undo_redo_stack.redo(model, time_to_load)) - this->update_after_undo_redo(); + if (this->undo_redo_stack.redo(model, this->view3D->get_canvas3d()->get_gizmos_manager(), time_to_load)) + this->update_after_undo_redo(); } void Plater::priv::update_after_undo_redo() { - this->view3D->get_canvas3d()->get_selection().clear(); + this->view3D->get_canvas3d()->get_selection().clear(); this->update(false); // update volumes from the deserializd model //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack.selection_deserialized().mode), this->undo_redo_stack.selection_deserialized().volumes_and_instances); + this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(); wxGetApp().obj_list()->update_after_undo_redo(); @@ -3884,7 +3885,7 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe return; } - this->take_snapshot(_(L("Cut"))); + this->take_snapshot(_(L("Gizmo - Cut"))); wxBusyCursor wait; const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower); -- cgit v1.2.3 From 0a530ab7bc3913d3b1d3333c110d0dafd18393de Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 17 Jul 2019 10:03:00 +0200 Subject: Added undo/redo snapshot for layers height editing --- src/slic3r/GUI/GLCanvas3D.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9e05f60ad..9bb9c2158 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -604,6 +604,7 @@ void GLCanvas3D::LayersEditing::accept_changes(GLCanvas3D& canvas) { if (last_object_id >= 0) { if (m_layer_height_profile_modified) { + wxGetApp().plater()->take_snapshot(_(L("Layers heights"))); const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } -- cgit v1.2.3 From da1fa0b6e339163836cc7a8165c0a05b58c5f0d3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 17 Jul 2019 12:06:23 +0200 Subject: Refactoring of GLGizmosXX classes to cleanup their interface --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 8 +++---- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 30 ++++++++++++------------ src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 24 ++++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 12 +++++----- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 17 +++++++++----- src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp | 9 ++++---- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 22 ++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoMove.hpp | 12 ++++++---- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 34 ++++++++++++++++------------ src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 26 ++++++++++----------- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 30 ++++++++++++++---------- src/slic3r/GUI/Gizmos/GLGizmoScale.hpp | 14 +++++++----- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 23 +++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 12 +++++----- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 31 ++++++++++--------------- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 +- 16 files changed, 165 insertions(+), 141 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index ba0ea4825..4b975e87e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -180,7 +180,7 @@ void GLGizmoBase::disable_grabber(unsigned int id) on_disable_grabber(id); } -void GLGizmoBase::start_dragging(const Selection& selection) +void GLGizmoBase::start_dragging() { m_dragging = true; @@ -189,7 +189,7 @@ void GLGizmoBase::start_dragging(const Selection& selection) m_grabbers[i].dragging = (m_hover_id == i); } - on_start_dragging(selection); + on_start_dragging(); } void GLGizmoBase::stop_dragging() @@ -204,10 +204,10 @@ void GLGizmoBase::stop_dragging() on_stop_dragging(); } -void GLGizmoBase::update(const UpdateData& data, const Selection& selection) +void GLGizmoBase::update(const UpdateData& data) { if (m_hover_id != -1) - on_update(data, selection); + on_update(data); } std::array GLGizmoBase::picking_color_component(unsigned int id) const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 88927aee2..b84442b94 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -76,10 +76,10 @@ public: struct UpdateData { - const Linef3 mouse_ray; - const Point* mouse_pos; + const Linef3& mouse_ray; + const Point& mouse_pos; - UpdateData(const Linef3& mouse_ray, const Point* mouse_pos = nullptr) + UpdateData(const Linef3& mouse_ray, const Point& mouse_pos) : mouse_ray(mouse_ray), mouse_pos(mouse_pos) {} }; @@ -122,7 +122,7 @@ public: const std::string& get_icon_filename() const { return m_icon_filename; } - bool is_activable(const Selection& selection) const { return on_is_activable(selection); } + bool is_activable() const { return on_is_activable(); } bool is_selectable() const { return on_is_selectable(); } unsigned int get_sprite_id() const { return m_sprite_id; } @@ -135,16 +135,16 @@ public: void enable_grabber(unsigned int id); void disable_grabber(unsigned int id); - void start_dragging(const Selection& selection); + void start_dragging(); void stop_dragging(); bool is_dragging() const { return m_dragging; } - void update(const UpdateData& data, const Selection& selection); + void update(const UpdateData& data); - void render(const Selection& selection) const { on_render(selection); } - void render_for_picking(const Selection& selection) const { on_render_for_picking(selection); } - void render_input_window(float x, float y, float bottom_limit, const Selection& selection) { on_render_input_window(x, y, bottom_limit, selection); } + void render() const { on_render(); } + void render_for_picking() const { on_render_for_picking(); } + void render_input_window(float x, float y, float bottom_limit) { on_render_input_window(x, y, bottom_limit); } protected: virtual bool on_init() = 0; @@ -153,16 +153,16 @@ protected: virtual std::string on_get_name() const = 0; virtual void on_set_state() {} virtual void on_set_hover_id() {} - virtual bool on_is_activable(const Selection& selection) const { return true; } + virtual bool on_is_activable() const { return true; } virtual bool on_is_selectable() const { return true; } virtual void on_enable_grabber(unsigned int id) {} virtual void on_disable_grabber(unsigned int id) {} - virtual void on_start_dragging(const Selection& selection) {} + virtual void on_start_dragging() {} virtual void on_stop_dragging() {} - virtual void on_update(const UpdateData& data, const Selection& selection) = 0; - virtual void on_render(const Selection& selection) const = 0; - virtual void on_render_for_picking(const Selection& selection) const = 0; - virtual void on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) {} + virtual void on_update(const UpdateData& data) {} + virtual void on_render() const = 0; + virtual void on_render_for_picking() const = 0; + virtual void on_render_input_window(float x, float y, float bottom_limit) {} // Returns the picking color for the given id, based on the BASE_ID constant // No check is made for clashing with other picking color (i.e. GLVolumes) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 52174d2d6..39399fc0d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -48,15 +48,18 @@ void GLGizmoCut::on_set_state() } } -bool GLGizmoCut::on_is_activable(const Selection& selection) const +bool GLGizmoCut::on_is_activable() const { + const Selection& selection = m_parent.get_selection(); return selection.is_single_full_instance() && !selection.is_wipe_tower(); } -void GLGizmoCut::on_start_dragging(const Selection& selection) +void GLGizmoCut::on_start_dragging() { - if (m_hover_id == -1) { return; } + if (m_hover_id == -1) + return; + const Selection& selection = m_parent.get_selection(); const BoundingBoxf3& box = selection.get_bounding_box(); m_start_z = m_cut_z; update_max_z(selection); @@ -65,19 +68,21 @@ void GLGizmoCut::on_start_dragging(const Selection& selection) m_drag_center(2) = m_cut_z; } -void GLGizmoCut::on_update(const UpdateData& data, const Selection& selection) +void GLGizmoCut::on_update(const UpdateData& data) { if (m_hover_id != -1) { set_cut_z(m_start_z + calc_projection(data.mouse_ray)); } } -void GLGizmoCut::on_render(const Selection& selection) const +void GLGizmoCut::on_render() const { if (m_grabbers[0].dragging) { set_tooltip("Z: " + format(m_cut_z, 2)); } + const Selection& selection = m_parent.get_selection(); + update_max_z(selection); const BoundingBoxf3& box = selection.get_bounding_box(); @@ -123,14 +128,13 @@ void GLGizmoCut::on_render(const Selection& selection) const m_grabbers[0].render(m_hover_id == 0, (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); } -void GLGizmoCut::on_render_for_picking(const Selection& selection) const +void GLGizmoCut::on_render_for_picking() const { glsafe(::glDisable(GL_DEPTH_TEST)); - - render_grabbers_for_picking(selection.get_bounding_box()); + render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); } -void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) +void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit) { const float approx_height = m_imgui->scaled(11.0f); y = std::min(y, bottom_limit - approx_height); @@ -153,7 +157,7 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, co m_imgui->end(); if (cut_clicked && (m_keep_upper || m_keep_lower)) { - perform_cut(selection); + perform_cut(m_parent.get_selection()); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 628bcf508..5bfeda526 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -31,12 +31,12 @@ protected: virtual void on_save(cereal::BinaryOutputArchive& ar) const { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } virtual std::string on_get_name() const; virtual void on_set_state(); - virtual bool on_is_activable(const Selection& selection) const; - virtual void on_start_dragging(const Selection& selection); - virtual void on_update(const UpdateData& data, const Selection& selection); - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const; - virtual void on_render_input_window(float x, float y, float bottom_limit, const Selection& selection); + virtual bool on_is_activable() const; + virtual void on_start_dragging(); + virtual void on_update(const UpdateData& data); + virtual void on_render() const; + virtual void on_render_for_picking() const; + virtual void on_render_input_window(float x, float y, float bottom_limit); private: void update_max_z(const Selection& selection) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 6bb81a703..78f5da58b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -1,5 +1,6 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoFlatten.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include @@ -27,23 +28,25 @@ std::string GLGizmoFlatten::on_get_name() const return (_(L("Place on face")) + " [F]").ToUTF8().data(); } -bool GLGizmoFlatten::on_is_activable(const Selection& selection) const +bool GLGizmoFlatten::on_is_activable() const { - return selection.is_single_full_instance(); + return m_parent.get_selection().is_single_full_instance(); } -void GLGizmoFlatten::on_start_dragging(const Selection& selection) +void GLGizmoFlatten::on_start_dragging() { if (m_hover_id != -1) { assert(m_planes_valid); m_normal = m_planes[m_hover_id].normal; - m_starting_center = selection.get_bounding_box().center(); + m_starting_center = m_parent.get_selection().get_bounding_box().center(); } } -void GLGizmoFlatten::on_render(const Selection& selection) const +void GLGizmoFlatten::on_render() const { + const Selection& selection = m_parent.get_selection(); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -78,8 +81,10 @@ void GLGizmoFlatten::on_render(const Selection& selection) const glsafe(::glDisable(GL_BLEND)); } -void GLGizmoFlatten::on_render_for_picking(const Selection& selection) const +void GLGizmoFlatten::on_render_for_picking() const { + const Selection& selection = m_parent.get_selection(); + glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_BLEND)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index 926dc3457..c8bd056bc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -45,11 +45,10 @@ public: protected: virtual bool on_init(); virtual std::string on_get_name() const; - virtual bool on_is_activable(const Selection& selection) const; - virtual void on_start_dragging(const Selection& selection); - virtual void on_update(const UpdateData& data, const Selection& selection) {} - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const; + virtual bool on_is_activable() const; + virtual void on_start_dragging(); + virtual void on_render() const; + virtual void on_render_for_picking() const; virtual void on_set_state() { if (m_state == On && is_plane_update_necessary()) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index b97f578b3..11bdcd4f8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -1,5 +1,6 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoMove.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include @@ -47,12 +48,12 @@ std::string GLGizmoMove3D::on_get_name() const return (_(L("Move")) + " [M]").ToUTF8().data(); } -void GLGizmoMove3D::on_start_dragging(const Selection& selection) +void GLGizmoMove3D::on_start_dragging() { if (m_hover_id != -1) { m_displacement = Vec3d::Zero(); - const BoundingBoxf3& box = selection.get_bounding_box(); + const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); m_starting_drag_position = m_grabbers[m_hover_id].center; m_starting_box_center = box.center(); m_starting_box_bottom_center = box.center(); @@ -65,7 +66,7 @@ void GLGizmoMove3D::on_stop_dragging() m_displacement = Vec3d::Zero(); } -void GLGizmoMove3D::on_update(const UpdateData& data, const Selection& selection) +void GLGizmoMove3D::on_update(const UpdateData& data) { if (m_hover_id == 0) m_displacement(0) = calc_projection(data); @@ -75,8 +76,10 @@ void GLGizmoMove3D::on_update(const UpdateData& data, const Selection& selection m_displacement(2) = calc_projection(data); } -void GLGizmoMove3D::on_render(const Selection& selection) const +void GLGizmoMove3D::on_render() const { + const Selection& selection = m_parent.get_selection(); + bool show_position = selection.is_single_full_instance(); const Vec3d& position = selection.get_bounding_box().center(); @@ -152,20 +155,21 @@ void GLGizmoMove3D::on_render(const Selection& selection) const } } -void GLGizmoMove3D::on_render_for_picking(const Selection& selection) const +void GLGizmoMove3D::on_render_for_picking() const { glsafe(::glDisable(GL_DEPTH_TEST)); - const BoundingBoxf3& box = selection.get_bounding_box(); + const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); render_grabbers_for_picking(box); render_grabber_extension(X, box, true); render_grabber_extension(Y, box, true); render_grabber_extension(Z, box, true); } -void GLGizmoMove3D::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) -{ #if !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI +void GLGizmoMove3D::on_render_input_window(float x, float y, float bottom_limit) +{ + const Selection& selection = m_parent.get_selection(); bool show_position = selection.is_single_full_instance(); const Vec3d& position = selection.get_bounding_box().center(); @@ -178,8 +182,8 @@ void GLGizmoMove3D::on_render_input_window(float x, float y, float bottom_limit, m_imgui->input_vec3("", displacement, 100.0f, "%.2f"); m_imgui->end(); -#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI } +#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI double GLGizmoMove3D::calc_projection(const UpdateData& data) const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 771496780..21b1d397b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -33,12 +33,14 @@ public: protected: virtual bool on_init(); virtual std::string on_get_name() const; - virtual void on_start_dragging(const Selection& selection); + virtual void on_start_dragging(); virtual void on_stop_dragging(); - virtual void on_update(const UpdateData& data, const Selection& selection); - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const; - virtual void on_render_input_window(float x, float y, float bottom_limit, const Selection& selection); + virtual void on_update(const UpdateData& data); + virtual void on_render() const; + virtual void on_render_for_picking() const; +#if !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI + virtual void on_render_input_window(float x, float y, float bottom_limit); +#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI private: double calc_projection(const UpdateData& data) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index f84c3886d..f481bb5d7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -1,5 +1,6 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoRotate.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include @@ -72,9 +73,9 @@ bool GLGizmoRotate::on_init() return true; } -void GLGizmoRotate::on_start_dragging(const Selection& selection) +void GLGizmoRotate::on_start_dragging() { - const BoundingBoxf3& box = selection.get_bounding_box(); + const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); m_center = box.center(); m_radius = Offset + box.radius(); m_snap_coarse_in_radius = m_radius / 3.0f; @@ -83,9 +84,9 @@ void GLGizmoRotate::on_start_dragging(const Selection& selection) m_snap_fine_out_radius = m_snap_fine_in_radius + m_radius * ScaleLongTooth; } -void GLGizmoRotate::on_update(const UpdateData& data, const Selection& selection) +void GLGizmoRotate::on_update(const UpdateData& data) { - Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, selection)); + Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, m_parent.get_selection())); Vec2d orig_dir = Vec2d::UnitX(); Vec2d new_dir = mouse_pos.normalized(); @@ -118,11 +119,12 @@ void GLGizmoRotate::on_update(const UpdateData& data, const Selection& selection m_angle = theta; } -void GLGizmoRotate::on_render(const Selection& selection) const +void GLGizmoRotate::on_render() const { if (!m_grabbers[0].enabled) return; + const Selection& selection = m_parent.get_selection(); const BoundingBoxf3& box = selection.get_bounding_box(); std::string axis; @@ -175,8 +177,10 @@ void GLGizmoRotate::on_render(const Selection& selection) const glsafe(::glPopMatrix()); } -void GLGizmoRotate::on_render_for_picking(const Selection& selection) const +void GLGizmoRotate::on_render_for_picking() const { + const Selection& selection = m_parent.get_selection(); + glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glPushMatrix()); @@ -445,10 +449,10 @@ std::string GLGizmoRotate3D::on_get_name() const return (_(L("Rotate")) + " [R]").ToUTF8().data(); } -void GLGizmoRotate3D::on_start_dragging(const Selection& selection) +void GLGizmoRotate3D::on_start_dragging() { if ((0 <= m_hover_id) && (m_hover_id < 3)) - m_gizmos[m_hover_id].start_dragging(selection); + m_gizmos[m_hover_id].start_dragging(); } void GLGizmoRotate3D::on_stop_dragging() @@ -457,23 +461,23 @@ void GLGizmoRotate3D::on_stop_dragging() m_gizmos[m_hover_id].stop_dragging(); } -void GLGizmoRotate3D::on_render(const Selection& selection) const +void GLGizmoRotate3D::on_render() const { glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); if ((m_hover_id == -1) || (m_hover_id == 0)) - m_gizmos[X].render(selection); + m_gizmos[X].render(); if ((m_hover_id == -1) || (m_hover_id == 1)) - m_gizmos[Y].render(selection); + m_gizmos[Y].render(); if ((m_hover_id == -1) || (m_hover_id == 2)) - m_gizmos[Z].render(selection); + m_gizmos[Z].render(); } -void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) -{ #if !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI +void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit) +{ Vec3d rotation(Geometry::rad2deg(m_gizmos[0].get_angle()), Geometry::rad2deg(m_gizmos[1].get_angle()), Geometry::rad2deg(m_gizmos[2].get_angle())); wxString label = _(L("Rotation (deg)")); @@ -482,8 +486,8 @@ void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limi m_imgui->begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); m_imgui->input_vec3("", rotation, 100.0f, "%.2f"); m_imgui->end(); -#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI } +#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index d2e564966..7846edb22 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -52,10 +52,10 @@ public: protected: virtual bool on_init(); virtual std::string on_get_name() const { return ""; } - virtual void on_start_dragging(const Selection& selection); - virtual void on_update(const UpdateData& data, const Selection& selection); - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const; + virtual void on_start_dragging(); + virtual void on_update(const UpdateData& data); + virtual void on_render() const; + virtual void on_render_for_picking() const; private: void render_circle() const; @@ -98,7 +98,6 @@ protected: m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1); } } - virtual bool on_is_activable(const Selection& selection) const { return true; } virtual void on_enable_grabber(unsigned int id) { if ((0 <= id) && (id < 3)) @@ -109,25 +108,26 @@ protected: if ((0 <= id) && (id < 3)) m_gizmos[id].disable_grabber(0); } - virtual void on_start_dragging(const Selection& selection); + virtual void on_start_dragging(); virtual void on_stop_dragging(); - virtual void on_update(const UpdateData& data, const Selection& selection) + virtual void on_update(const UpdateData& data) { for (GLGizmoRotate& g : m_gizmos) { - g.update(data, selection); + g.update(data); } } - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const + virtual void on_render() const; + virtual void on_render_for_picking() const { for (const GLGizmoRotate& g : m_gizmos) { - g.render_for_picking(selection); + g.render_for_picking(); } } - - virtual void on_render_input_window(float x, float y, float bottom_limit, const Selection& selection); +#if !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI + virtual void on_render_input_window(float x, float y, float bottom_limit); +#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index d30ceb092..7dc38b801 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -1,7 +1,6 @@ - - // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoScale.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include @@ -48,13 +47,18 @@ std::string GLGizmoScale3D::on_get_name() const return (_(L("Scale")) + " [S]").ToUTF8().data(); } -void GLGizmoScale3D::on_start_dragging(const Selection& selection) +bool GLGizmoScale3D::on_is_activable() const +{ + return !m_parent.get_selection().is_wipe_tower(); +} + +void GLGizmoScale3D::on_start_dragging() { if (m_hover_id != -1) { m_starting.drag_position = m_grabbers[m_hover_id].center; m_starting.ctrl_down = wxGetKeyState(WXK_CONTROL); - m_starting.box = (m_starting.ctrl_down && (m_hover_id < 6)) ? m_box : selection.get_bounding_box(); + m_starting.box = (m_starting.ctrl_down && (m_hover_id < 6)) ? m_box : m_parent.get_selection().get_bounding_box(); const Vec3d& center = m_starting.box.center(); m_starting.pivots[0] = m_transform * Vec3d(m_starting.box.max(0), center(1), center(2)); @@ -66,7 +70,7 @@ void GLGizmoScale3D::on_start_dragging(const Selection& selection) } } -void GLGizmoScale3D::on_update(const UpdateData& data, const Selection& selection) +void GLGizmoScale3D::on_update(const UpdateData& data) { if ((m_hover_id == 0) || (m_hover_id == 1)) do_scale_along_axis(X, data); @@ -78,8 +82,10 @@ void GLGizmoScale3D::on_update(const UpdateData& data, const Selection& selectio do_scale_uniform(data); } -void GLGizmoScale3D::on_render(const Selection& selection) const +void GLGizmoScale3D::on_render() const { + const Selection& selection = m_parent.get_selection(); + bool single_instance = selection.is_single_full_instance(); bool single_volume = selection.is_single_modifier() || selection.is_single_volume(); bool single_selection = single_instance || single_volume; @@ -272,16 +278,16 @@ void GLGizmoScale3D::on_render(const Selection& selection) const } } -void GLGizmoScale3D::on_render_for_picking(const Selection& selection) const +void GLGizmoScale3D::on_render_for_picking() const { glsafe(::glDisable(GL_DEPTH_TEST)); - - render_grabbers_for_picking(selection.get_bounding_box()); + render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); } -void GLGizmoScale3D::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) -{ #if !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI +void GLGizmoScale3D::on_render_input_window(float x, float y, float bottom_limit) +{ + const Selection& selection = m_parent.get_selection(); bool single_instance = selection.is_single_full_instance(); wxString label = _(L("Scale (%)")); @@ -290,8 +296,8 @@ void GLGizmoScale3D::on_render_input_window(float x, float y, float bottom_limit m_imgui->begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); m_imgui->input_vec3("", m_scale * 100.f, 100.0f, "%.2f"); m_imgui->end(); -#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI } +#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2) const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index 16307165f..7b77fe559 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -45,12 +45,14 @@ public: protected: virtual bool on_init(); virtual std::string on_get_name() const; - virtual bool on_is_activable(const Selection& selection) const { return !selection.is_wipe_tower(); } - virtual void on_start_dragging(const Selection& selection); - virtual void on_update(const UpdateData& data, const Selection& selection); - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const; - virtual void on_render_input_window(float x, float y, float bottom_limit, const Selection& selection); + virtual bool on_is_activable() const; + virtual void on_start_dragging(); + virtual void on_update(const UpdateData& data); + virtual void on_render() const; + virtual void on_render_for_picking() const; +#if !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI + virtual void on_render_input_window(float x, float y, float bottom_limit); +#endif // !DISABLE_MOVE_ROTATE_SCALE_GIZMOS_IMGUI private: void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index fdc15e928..3e6530d30 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -94,8 +94,10 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S } } -void GLGizmoSlaSupports::on_render(const Selection& selection) const +void GLGizmoSlaSupports::on_render() const { + const Selection& selection = m_parent.get_selection(); + // If current m_model_object does not match selection, ask GLCanvas3D to turn us off if (m_state == On && (m_model_object != selection.get_model()->objects[selection.get_object_idx()] @@ -252,8 +254,9 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const } -void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const +void GLGizmoSlaSupports::on_render_for_picking() const { + const Selection& selection = m_parent.get_selection(); #if ENABLE_RENDER_PICKING_PASS m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z(); #endif @@ -702,12 +705,12 @@ void GLGizmoSlaSupports::delete_selected_points(bool force) //m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } -void GLGizmoSlaSupports::on_update(const UpdateData& data, const Selection& selection) +void GLGizmoSlaSupports::on_update(const UpdateData& data) { - if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_editing_mode_cache[m_hover_id].support_point.is_new_island || !m_lock_unique_islands)) { + if (m_editing_mode && m_hover_id != -1 && (!m_editing_mode_cache[m_hover_id].support_point.is_new_island || !m_lock_unique_islands)) { std::pair pos_and_normal; try { - pos_and_normal = unproject_on_mesh(Vec2d((*data.mouse_pos)(0), (*data.mouse_pos)(1))); + pos_and_normal = unproject_on_mesh(data.mouse_pos.cast()); } catch (...) { return; } m_editing_mode_cache[m_hover_id].support_point.pos = pos_and_normal.first; @@ -822,7 +825,7 @@ void GLGizmoSlaSupports::make_line_segments() const */ -void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) +void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit) { if (!m_model_object) return; @@ -1002,11 +1005,13 @@ RENDER_AGAIN: m_parent.set_as_dirty(); } -bool GLGizmoSlaSupports::on_is_activable(const Selection& selection) const +bool GLGizmoSlaSupports::on_is_activable() const { + const Selection& selection = m_parent.get_selection(); + if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA || !selection.is_from_single_instance()) - return false; + return false; // Check that none of the selected volumes is outside. Only SLA auxiliaries (supports) are allowed outside. const Selection::IndicesList& list = selection.get_volume_idxs(); @@ -1075,7 +1080,7 @@ void GLGizmoSlaSupports::on_set_state() -void GLGizmoSlaSupports::on_start_dragging(const Selection& selection) +void GLGizmoSlaSupports::on_start_dragging() { if (m_hover_id != -1) { select_point(NoPoints); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 5e50eae0b..b0a505b82 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -70,9 +70,9 @@ public: private: bool on_init(); - void on_update(const UpdateData& data, const Selection& selection); - virtual void on_render(const Selection& selection) const; - virtual void on_render_for_picking(const Selection& selection) const; + void on_update(const UpdateData& data); + virtual void on_render() const; + virtual void on_render_for_picking() const; //void render_selection_rectangle() const; void render_points(const Selection& selection, bool picking = false) const; @@ -133,11 +133,11 @@ protected: if ((int)m_editing_mode_cache.size() <= m_hover_id) m_hover_id = -1; } - void on_start_dragging(const Selection& selection) override; - virtual void on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) override; + void on_start_dragging() override; + virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual std::string on_get_name() const; - virtual bool on_is_activable(const Selection& selection) const; + virtual bool on_is_activable() const; virtual bool on_is_selectable() const; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 5922f9600..22b49ee5d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -150,7 +150,7 @@ void GLGizmosManager::refresh_on_off_state() GizmosMap::iterator it = m_gizmos.find(m_current); if ((it != m_gizmos.end()) && (it->second != nullptr)) { - if (!it->second->is_activable(m_parent->get_selection())) + if (!it->second->is_activable()) { it->second->set_state(GLGizmoBase::Off); m_current = Undefined; @@ -205,14 +205,14 @@ void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) } } -void GLGizmosManager::update(const Linef3& mouse_ray, const Point* mouse_pos) +void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos) { if (!m_enabled || (m_parent == nullptr)) return; GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos), m_parent->get_selection()); + curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos)); } void GLGizmosManager::update_data() @@ -282,8 +282,7 @@ bool GLGizmosManager::handle_shortcut(int key) if (!m_enabled || (m_parent == nullptr)) return false; - const Selection& selection = m_parent->get_selection(); - if (selection.is_empty()) + if (m_parent->get_selection().is_empty()) return false; EType old_current = m_current; @@ -295,7 +294,7 @@ bool GLGizmosManager::handle_shortcut(int key) int it_key = it->second->get_shortcut_key(); - if (it->second->is_activable(selection) && ((it_key == key - 64) || (it_key == key - 96))) + if (it->second->is_activable() && ((it_key == key - 64) || (it_key == key - 96))) { if ((it->second->get_state() == GLGizmoBase::On)) { @@ -338,7 +337,7 @@ void GLGizmosManager::start_dragging() GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->start_dragging(m_parent->get_selection()); + curr->start_dragging(); } void GLGizmosManager::stop_dragging() @@ -469,7 +468,7 @@ void GLGizmosManager::render_current_gizmo() const GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->render(m_parent->get_selection()); + curr->render(); } void GLGizmosManager::render_current_gizmo_for_picking_pass() const @@ -479,7 +478,7 @@ void GLGizmosManager::render_current_gizmo_for_picking_pass() const GLGizmoBase* curr = get_current(); if (curr != nullptr) - curr->render_for_picking(m_parent->get_selection()); + curr->render_for_picking(); } void GLGizmosManager::render_overlay() const @@ -589,7 +588,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) m_parent->get_wxglcanvas()->CaptureMouse(); m_parent->set_mouse_as_dragging(); - update(m_parent->mouse_ray(pos), &pos); + update(m_parent->mouse_ray(pos), pos); switch (m_current) { @@ -902,8 +901,6 @@ void GLGizmosManager::do_render_overlay() const if ((m_parent == nullptr) || m_gizmos.empty()) return; - const Selection& selection = m_parent->get_selection(); - float cnv_w = (float)m_parent->get_canvas_size().get_width(); float cnv_h = (float)m_parent->get_canvas_size().get_height(); float zoom = (float)m_parent->get_camera().get_zoom(); @@ -1020,7 +1017,7 @@ void GLGizmosManager::do_render_overlay() const GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); if (it->second->get_state() == GLGizmoBase::On) { float toolbar_top = (float)cnv_h - m_parent->get_view_toolbar_height(); - it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); + it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top); } top_y -= scaled_stride_y; } @@ -1087,8 +1084,6 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) if (!m_enabled || (m_parent == nullptr)) return; - const Selection& selection = m_parent->get_selection(); - float cnv_h = (float)m_parent->get_canvas_size().get_height(); float height = get_total_overlay_height(); @@ -1104,7 +1099,7 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) continue; bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); - if (it->second->is_activable(selection) && inside) + if (it->second->is_activable() && inside) { if ((it->second->get_state() == GLGizmoBase::On)) { @@ -1135,8 +1130,6 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) if (!m_enabled || (m_parent == nullptr)) return name; - const Selection& selection = m_parent->get_selection(); - float cnv_h = (float)m_parent->get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; @@ -1154,7 +1147,7 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) if (inside) name = it->second->get_name(); - if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On)) + if (it->second->is_activable() && (it->second->get_state() != GLGizmoBase::On)) it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); top_y += scaled_stride_y; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index db73345ae..f41bed1e6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -140,7 +140,7 @@ public: void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); - void update(const Linef3& mouse_ray, const Point* mouse_pos = nullptr); + void update(const Linef3& mouse_ray, const Point& mouse_pos); void update_data(); EType get_current_type() const { return m_current; } -- cgit v1.2.3 From 401707a6fed24f44e468b10538092e74bd17d9ab Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 17 Jul 2019 12:43:27 +0200 Subject: Another refactoring of GLGizmosManager --- src/slic3r/GUI/GLCanvas3D.cpp | 3 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 133 +++++++++++++----------------- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 6 +- src/slic3r/GUI/Plater.cpp | 2 +- 4 files changed, 64 insertions(+), 80 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9bb9c2158..192112ba7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1203,6 +1203,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar , m_camera(camera) , m_view_toolbar(view_toolbar) , m_toolbar(GLToolbar::Normal, "Top") + , m_gizmos(*this) , m_use_clipping_planes(false) , m_sidebar_field("") , m_keep_dirty(false) @@ -1319,7 +1320,7 @@ bool GLCanvas3D::init() // if (!m_volumes.empty()) // m_volumes.finalize_geometry(); - if (m_gizmos.is_enabled() && !m_gizmos.init(*this)) + if (m_gizmos.is_enabled() && !m_gizmos.init()) std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl; if (!_init_toolbar()) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 22b49ee5d..622fdb2d8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -14,8 +14,8 @@ namespace GUI { const float GLGizmosManager::Default_Icons_Size = 64; -GLGizmosManager::GLGizmosManager() - : m_parent(nullptr) +GLGizmosManager::GLGizmosManager(GLCanvas3D& parent) + : m_parent(parent) , m_enabled(false) , m_icons_texture_dirty(true) , m_current(Undefined) @@ -33,10 +33,8 @@ GLGizmosManager::~GLGizmosManager() reset(); } -bool GLGizmosManager::init(GLCanvas3D& parent) +bool GLGizmosManager::init() { - m_parent = &parent; - m_background_texture.metadata.filename = "toolbar_background.png"; m_background_texture.metadata.left = 16; m_background_texture.metadata.top = 16; @@ -52,7 +50,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) } } - GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "move.svg", 0); + GLGizmoBase* gizmo = new GLGizmoMove3D(m_parent, "move.svg", 0); if (gizmo == nullptr) return false; @@ -61,7 +59,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Move, gizmo)); - gizmo = new GLGizmoScale3D(parent, "scale.svg", 1); + gizmo = new GLGizmoScale3D(m_parent, "scale.svg", 1); if (gizmo == nullptr) return false; @@ -70,7 +68,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); - gizmo = new GLGizmoRotate3D(parent, "rotate.svg", 2); + gizmo = new GLGizmoRotate3D(m_parent, "rotate.svg", 2); if (gizmo == nullptr) { reset(); @@ -85,7 +83,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); - gizmo = new GLGizmoFlatten(parent, "place.svg", 3); + gizmo = new GLGizmoFlatten(m_parent, "place.svg", 3); if (gizmo == nullptr) return false; @@ -96,7 +94,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); - gizmo = new GLGizmoCut(parent, "cut.svg", 4); + gizmo = new GLGizmoCut(m_parent, "cut.svg", 4); if (gizmo == nullptr) return false; @@ -107,7 +105,7 @@ bool GLGizmosManager::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); - gizmo = new GLGizmoSlaSupports(parent, "sla_supports.svg", 5); + gizmo = new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5); if (gizmo == nullptr) return false; @@ -141,9 +139,6 @@ void GLGizmosManager::set_overlay_scale(float scale) void GLGizmosManager::refresh_on_off_state() { - if (m_parent == nullptr) - return; - if (m_serializing) return; @@ -207,7 +202,7 @@ void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos) { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; GLGizmoBase* curr = get_current(); @@ -217,10 +212,10 @@ void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos) void GLGizmosManager::update_data() { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; - const Selection& selection = m_parent->get_selection(); + const Selection& selection = m_parent.get_selection(); bool is_wipe_tower = selection.is_wipe_tower(); enable_grabber(Move, 2, !is_wipe_tower); @@ -279,10 +274,10 @@ bool GLGizmosManager::is_running() const bool GLGizmosManager::handle_shortcut(int key) { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return false; - if (m_parent->get_selection().is_empty()) + if (m_parent.get_selection().is_empty()) return false; EType old_current = m_current; @@ -332,7 +327,7 @@ bool GLGizmosManager::is_dragging() const void GLGizmosManager::start_dragging() { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; GLGizmoBase* curr = get_current(); @@ -427,12 +422,12 @@ void GLGizmosManager::set_flattening_data(const ModelObject* model_object) void GLGizmosManager::set_sla_support_data(ModelObject* model_object) { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_sla_support_data(model_object, m_parent->get_selection()); + reinterpret_cast(it->second)->set_sla_support_data(model_object, m_parent.get_selection()); } // Returns true if the gizmo used the event to do something, false otherwise. @@ -463,7 +458,7 @@ ClippingPlane GLGizmosManager::get_sla_clipping_plane() const void GLGizmosManager::render_current_gizmo() const { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; GLGizmoBase* curr = get_current(); @@ -473,7 +468,7 @@ void GLGizmosManager::render_current_gizmo() const void GLGizmosManager::render_current_gizmo_for_picking_pass() const { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; GLGizmoBase* curr = get_current(); @@ -483,7 +478,7 @@ void GLGizmosManager::render_current_gizmo_for_picking_pass() const void GLGizmosManager::render_overlay() const { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; if (m_icons_texture_dirty) @@ -494,9 +489,6 @@ void GLGizmosManager::render_overlay() const bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt) { - if (m_parent == nullptr) - return false; - bool processed = false; if (m_current == SlaSupports) { @@ -510,13 +502,10 @@ bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt) bool GLGizmosManager::on_mouse(wxMouseEvent& evt) { - if (m_parent == nullptr) - return false; - Point pos(evt.GetX(), evt.GetY()); Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); - Selection& selection = m_parent->get_selection(); + Selection& selection = m_parent.get_selection(); int selected_object_idx = selection.get_object_idx(); bool processed = false; @@ -562,33 +551,33 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) if (m_current == Flatten) { // Rotate the object so the normal points downward: - m_parent->do_flatten(get_flattening_normal(), "Gizmo - Place on Face"); + m_parent.do_flatten(get_flattening_normal(), "Gizmo-Place on Face"); wxGetApp().obj_manipul()->set_dirty(); } - m_parent->set_as_dirty(); + m_parent.set_as_dirty(); processed = true; } } else if (evt.RightDown() && (selected_object_idx != -1) && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::RightDown)) // event was taken care of by the SlaSupports gizmo processed = true; - else if (evt.Dragging() && (m_parent->get_move_volume_id() != -1) && (m_current == SlaSupports)) - // don't allow dragging objects with the Sla gizmo on + else if (evt.Dragging() && (m_parent.get_move_volume_id() != -1) && (m_current == SlaSupports)) + // don't allow dragging objects with the Sla gizmo on processed = true; else if (evt.Dragging() && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) { // the gizmo got the event and took some action, no need to do anything more here - m_parent->set_as_dirty(); + m_parent.set_as_dirty(); processed = true; } else if (evt.Dragging() && is_dragging()) { - if (!m_parent->get_wxglcanvas()->HasCapture()) - m_parent->get_wxglcanvas()->CaptureMouse(); + if (!m_parent.get_wxglcanvas()->HasCapture()) + m_parent.get_wxglcanvas()->CaptureMouse(); - m_parent->set_mouse_as_dragging(); - update(m_parent->mouse_ray(pos), pos); + m_parent.set_mouse_as_dragging(); + update(m_parent.mouse_ray(pos), pos); switch (m_current) { @@ -625,7 +614,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) break; } - m_parent->set_as_dirty(); + m_parent.set_as_dirty(); processed = true; } else if (evt.LeftUp() && is_dragging()) @@ -634,18 +623,18 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) { case Move: { - m_parent->disable_regenerate_volumes(); - m_parent->do_move("Gizmo-Move Object"); + m_parent.disable_regenerate_volumes(); + m_parent.do_move("Gizmo-Move"); break; } case Scale: { - m_parent->do_scale("Gizmo-Scale Object"); + m_parent.do_scale("Gizmo-Scale"); break; } case Rotate: { - m_parent->do_rotate("Gizmo-Rotate Object"); + m_parent.do_rotate("Gizmo-Rotate"); break; } default: @@ -658,20 +647,20 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) wxGetApp().obj_manipul()->set_dirty(); // Let the platter know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. - m_parent->post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); // updates camera target constraints - m_parent->refresh_camera_scene_box(); + m_parent.refresh_camera_scene_box(); processed = true; } - else if (evt.LeftUp() && (m_current == SlaSupports) && !m_parent->is_mouse_dragging()) + else if (evt.LeftUp() && (m_current == SlaSupports) && !m_parent.is_mouse_dragging()) { // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither // object moving or selecting is suppressed in that case gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()); processed = true; } - else if (evt.LeftUp() && (m_current == Flatten) && ((m_parent->get_first_hover_volume_idx() != -1) || grabber_contains_mouse())) + else if (evt.LeftUp() && (m_current == Flatten) && ((m_parent.get_first_hover_volume_idx() != -1) || grabber_contains_mouse())) { // to avoid to loose the selection when user clicks an object while the Flatten gizmo is active processed = true; @@ -683,24 +672,24 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) if (evt.LeftDown() || evt.LeftDClick()) { m_mouse_capture.left = true; - m_mouse_capture.parent = m_parent; + m_mouse_capture.parent = &m_parent; processed = true; if (!selection.is_empty()) { update_on_off_state(mouse_pos); update_data(); - m_parent->set_as_dirty(); + m_parent.set_as_dirty(); } } else if (evt.MiddleDown()) { m_mouse_capture.middle = true; - m_mouse_capture.parent = m_parent; + m_mouse_capture.parent = &m_parent; } else if (evt.RightDown()) { m_mouse_capture.right = true; - m_mouse_capture.parent = m_parent; + m_mouse_capture.parent = &m_parent; } else if (evt.LeftUp()) processed = true; @@ -711,9 +700,6 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) bool GLGizmosManager::on_char(wxKeyEvent& evt) { - if (m_parent == nullptr) - return false; - // see include/wx/defs.h enum wxKeyCode int keyCode = evt.GetKeyCode(); int ctrlMask = wxMOD_CONTROL; @@ -828,16 +814,13 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) } if (processed) - m_parent->set_as_dirty(); + m_parent.set_as_dirty(); return processed; } bool GLGizmosManager::on_key(wxKeyEvent& evt) { - if (m_parent == nullptr) - return false; - const int keyCode = evt.GetKeyCode(); bool processed = false; @@ -862,19 +845,19 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) } // if (processed) -// m_parent->set_cursor(GLCanvas3D::Standard); +// m_parent.set_cursor(GLCanvas3D::Standard); } else if (evt.GetEventType() == wxEVT_KEY_DOWN) { if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) && reinterpret_cast(get_current())->is_in_editing_mode()) { -// m_parent->set_cursor(GLCanvas3D::Cross); +// m_parent.set_cursor(GLCanvas3D::Cross); processed = true; } } if (processed) - m_parent->set_as_dirty(); + m_parent.set_as_dirty(); return processed; } @@ -898,12 +881,12 @@ void GLGizmosManager::reset() void GLGizmosManager::do_render_overlay() const { - if ((m_parent == nullptr) || m_gizmos.empty()) + if (m_gizmos.empty()) return; - float cnv_w = (float)m_parent->get_canvas_size().get_width(); - float cnv_h = (float)m_parent->get_canvas_size().get_height(); - float zoom = (float)m_parent->get_camera().get_zoom(); + float cnv_w = (float)m_parent.get_canvas_size().get_width(); + float cnv_h = (float)m_parent.get_canvas_size().get_height(); + float zoom = (float)m_parent.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float height = get_total_overlay_height(); @@ -1016,7 +999,7 @@ void GLGizmosManager::do_render_overlay() const GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); if (it->second->get_state() == GLGizmoBase::On) { - float toolbar_top = (float)cnv_h - m_parent->get_view_toolbar_height(); + float toolbar_top = (float)cnv_h - m_parent.get_view_toolbar_height(); it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top); } top_y -= scaled_stride_y; @@ -1081,10 +1064,10 @@ bool GLGizmosManager::generate_icons_texture() const void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return; - float cnv_h = (float)m_parent->get_canvas_size().get_height(); + float cnv_h = (float)m_parent.get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; @@ -1127,10 +1110,10 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) { std::string name = ""; - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return name; - float cnv_h = (float)m_parent->get_canvas_size().get_height(); + float cnv_h = (float)m_parent.get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; float scaled_border = m_overlay_border * m_overlay_scale; @@ -1158,10 +1141,10 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) bool GLGizmosManager::overlay_contains_mouse(const Vec2d& mouse_pos) const { - if (!m_enabled || (m_parent == nullptr)) + if (!m_enabled) return false; - float cnv_h = (float)m_parent->get_canvas_size().get_height(); + float cnv_h = (float)m_parent.get_canvas_size().get_height(); float height = get_total_overlay_height(); float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index f41bed1e6..803613ec7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -60,7 +60,7 @@ public: }; private: - GLCanvas3D* m_parent; + GLCanvas3D& m_parent; bool m_enabled; typedef std::map GizmosMap; GizmosMap m_gizmos; @@ -92,10 +92,10 @@ private: bool m_serializing; public: - GLGizmosManager(); + explicit GLGizmosManager(GLCanvas3D& parent); ~GLGizmosManager(); - bool init(GLCanvas3D& parent); + bool init(); template void load(Archive& ar) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c5a4ccead..8fefca00c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3885,7 +3885,7 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe return; } - this->take_snapshot(_(L("Gizmo - Cut"))); + this->take_snapshot(_(L("Gizmo-Cut"))); wxBusyCursor wait; const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower); -- cgit v1.2.3 From f97a61cdcfaabf573feafbb4a0d1a7b36c2bf5be Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 17 Jul 2019 14:13:50 +0200 Subject: Fixed use of translate macros --- src/slic3r/GUI/GLCanvas3D.cpp | 16 ++++++++-------- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 10 +++++----- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 8 ++++---- src/slic3r/GUI/Selection.cpp | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 192112ba7..31372659f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1795,7 +1795,7 @@ std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) void GLCanvas3D::mirror_selection(Axis axis) { m_selection.mirror(axis); - do_mirror("Mirror Object"); + do_mirror(L("Mirror Object")); wxGetApp().obj_manipul()->set_dirty(); } @@ -2950,7 +2950,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) { m_regenerate_volumes = false; - do_move("Move Object"); + do_move(L("Move Object")); wxGetApp().obj_manipul()->set_dirty(); // Let the plater know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. @@ -3115,7 +3115,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) return; if (!snapshot_type.empty()) - wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + wxGetApp().plater()->take_snapshot(_(snapshot_type)); std::set> done; // keeps track of modified instances bool object_moved = false; @@ -3177,7 +3177,7 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) return; if (!snapshot_type.empty()) - wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + wxGetApp().plater()->take_snapshot(_(snapshot_type)); std::set> done; // keeps track of modified instances @@ -3237,7 +3237,7 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) return; if (!snapshot_type.empty()) - wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + wxGetApp().plater()->take_snapshot(_(snapshot_type)); std::set> done; // keeps track of modified instances @@ -3291,10 +3291,10 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) void GLCanvas3D::do_flatten(const Vec3d& normal, const std::string& snapshot_type) { if (!snapshot_type.empty()) - wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + wxGetApp().plater()->take_snapshot(_(snapshot_type)); m_selection.flattening_rotate(normal); - do_rotate(""); // avoid taking another snapshot + do_rotate(L("")); // avoid taking another snapshot } void GLCanvas3D::do_mirror(const std::string& snapshot_type) @@ -3303,7 +3303,7 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type) return; if (!snapshot_type.empty()) - wxGetApp().plater()->take_snapshot(_(L(snapshot_type))); + wxGetApp().plater()->take_snapshot(_(snapshot_type)); std::set> done; // keeps track of modified instances diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 1141ad907..fcb047139 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -242,7 +242,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL); selection.synchronize_unselected_volumes(); // Copy mirroring values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. - canvas->do_mirror("Set Mirror"); + canvas->do_mirror(L("Set Mirror")); UpdateAndShow(true); }); return sizer; @@ -323,7 +323,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL); selection.synchronize_unselected_volumes(); // Copy rotation values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. - canvas->do_rotate("Set Rotation"); + canvas->do_rotate(L("Set Rotation")); UpdateAndShow(true); }); @@ -709,7 +709,7 @@ void ObjectManipulation::change_position_value(int axis, double value) Selection& selection = canvas->get_selection(); selection.start_dragging(); selection.translate(position - m_cache.position, selection.requires_local_axes()); - canvas->do_move("Set Position"); + canvas->do_move(L("Set Position")); m_cache.position = position; m_cache.position_rounded(axis) = DBL_MAX; @@ -740,7 +740,7 @@ void ObjectManipulation::change_rotation_value(int axis, double value) selection.rotate( (M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation), transformation_type); - canvas->do_rotate("Set Orientation"); + canvas->do_rotate(L("Set Orientation")); m_cache.rotation = rotation; m_cache.rotation_rounded(axis) = DBL_MAX; @@ -805,7 +805,7 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const selection.start_dragging(); selection.scale(scaling_factor * 0.01, transformation_type); - wxGetApp().plater()->canvas3D()->do_scale("Set Scale"); + wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale")); } void ObjectManipulation::on_change(t_config_option_key opt_key, const boost::any& value) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 622fdb2d8..df53b40aa 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -551,7 +551,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) if (m_current == Flatten) { // Rotate the object so the normal points downward: - m_parent.do_flatten(get_flattening_normal(), "Gizmo-Place on Face"); + m_parent.do_flatten(get_flattening_normal(), L("Gizmo-Place on Face")); wxGetApp().obj_manipul()->set_dirty(); } @@ -624,17 +624,17 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) case Move: { m_parent.disable_regenerate_volumes(); - m_parent.do_move("Gizmo-Move"); + m_parent.do_move(L("Gizmo-Move")); break; } case Scale: { - m_parent.do_scale("Gizmo-Scale"); + m_parent.do_scale(L("Gizmo-Scale")); break; } case Rotate: { - m_parent.do_rotate("Gizmo-Rotate"); + m_parent.do_rotate(L("Gizmo-Rotate")); break; } default: diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index b960f8369..b990f28b8 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -816,12 +816,12 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config) // apply scale start_dragging(); scale(s * Vec3d::Ones(), type); - wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot + wxGetApp().plater()->canvas3D()->do_scale(L("")); // avoid storing another snapshot // center selection on print bed start_dragging(); translate(print_volume.center() - get_bounding_box().center()); - wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot + wxGetApp().plater()->canvas3D()->do_move(L("")); // avoid storing another snapshot wxGetApp().obj_manipul()->set_dirty(); } -- cgit v1.2.3 From 81dde630ea6d4ed353f0e01b19ab9996b4549edc Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 17 Jul 2019 15:38:19 +0200 Subject: SLA support points edits are now pushed onto undo/redo stack --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 138 ++++++++++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 13 +++ 2 files changed, 108 insertions(+), 43 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 3e6530d30..833ba3ee2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -106,6 +106,9 @@ void GLGizmoSlaSupports::on_render() const return; } + if (! m_its || ! m_mesh) + const_cast(this)->update_mesh(); + glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -387,18 +390,26 @@ bool GLGizmoSlaSupports::is_mesh_update_necessary() const void GLGizmoSlaSupports::update_mesh() { + if (! m_model_object) + return; + wxBusyCursor wait; // this way we can use that mesh directly. // This mesh does not account for the possible Z up SLA offset. m_mesh = &m_model_object->volumes.front()->mesh(); m_its = &m_mesh->its; + + // If this is different mesh than last time or if the AABB tree is uninitialized, recalculate it. + if (m_current_mesh_object_id != m_model_object->id() || (m_AABB.m_left == NULL && m_AABB.m_right == NULL)) + { + m_AABB.deinit(); + m_AABB.init( + MapMatrixXfUnaligned(m_its->vertices.front().data(), m_its->vertices.size(), 3), + MapMatrixXiUnaligned(m_its->indices.front().data(), m_its->indices.size(), 3)); + } + m_current_mesh_object_id = m_model_object->id(); m_editing_mode = false; - - m_AABB.deinit(); - m_AABB.init( - MapMatrixXfUnaligned(m_its->vertices.front().data(), m_its->vertices.size(), 3), - MapMatrixXiUnaligned(m_its->indices.front().data(), m_its->indices.size(), 3)); } // Unprojects the mouse position on the mesh and return the hit point and normal of the facet. @@ -1034,48 +1045,67 @@ std::string GLGizmoSlaSupports::on_get_name() const void GLGizmoSlaSupports::on_set_state() { - if (m_state == On && m_old_state != On) { // the gizmo was just turned on - if (is_mesh_update_necessary()) - update_mesh(); + // m_model_object pointer can be invalid (for instance because of undo/redo action), + // we should recover it from the object id + const ModelObject* old_model_object = m_model_object; + m_model_object = nullptr; + for (const auto mo : *wxGetApp().model_objects()) { + if (mo->id() == m_current_mesh_object_id) { + m_model_object = mo; + break; + } + } - // we'll now reload support points: - if (m_model_object) - editing_mode_reload_cache(); + // If ModelObject pointer really changed, invalidate mesh and do everything + // as if the gizmo was switched from Off state + if (m_model_object == nullptr || old_model_object != m_model_object) { + m_mesh = nullptr; + m_its = nullptr; + m_old_state = Off; + } - m_parent.toggle_model_objects_visibility(false); - if (m_model_object) - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + if (m_state == On && m_old_state != On) { // the gizmo was just turned on + if (is_mesh_update_necessary()) + update_mesh(); - // Set default head diameter from config. - const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; - m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; - } - if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off - wxGetApp().CallAfter([this]() { - // Following is called through CallAfter, because otherwise there was a problem - // on OSX with the wxMessageDialog being shown several times when clicked into. - if (m_model_object) { - if (m_unsaved_changes) { - wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually edited support points?")) + "\n", - _(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO); - if (dlg.ShowModal() == wxID_YES) - editing_mode_apply_changes(); - else - editing_mode_discard_changes(); - } + // we'll now reload support points: + if (m_model_object) + editing_mode_reload_cache(); + + m_parent.toggle_model_objects_visibility(false); + if (m_model_object) + m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + + // Set default head diameter from config. + const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; + m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; + } + if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off + wxGetApp().CallAfter([this]() { + // Following is called through CallAfter, because otherwise there was a problem + // on OSX with the wxMessageDialog being shown several times when clicked into. + if (m_model_object) { + if (m_unsaved_changes) { + wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually edited support points?")) + "\n", + _(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO); + if (dlg.ShowModal() == wxID_YES) + editing_mode_apply_changes(); + else + editing_mode_discard_changes(); } - m_parent.toggle_model_objects_visibility(true); - m_editing_mode = false; // so it is not active next time the gizmo opens - m_editing_mode_cache.clear(); - m_clipping_plane_distance = 0.f; - // Release triangle mesh slicer and the AABB spatial search structure. - m_AABB.deinit(); - m_its = nullptr; - m_tms.reset(); - m_supports_tms.reset(); - }); - } - m_old_state = m_state; + } + m_parent.toggle_model_objects_visibility(true); + m_editing_mode = false; // so it is not active next time the gizmo opens + m_editing_mode_cache.clear(); + m_clipping_plane_distance = 0.f; + // Release triangle mesh slicer and the AABB spatial search structure. + m_AABB.deinit(); + m_its = nullptr; + m_tms.reset(); + m_supports_tms.reset(); + }); + } + m_old_state = m_state; } @@ -1090,6 +1120,26 @@ void GLGizmoSlaSupports::on_start_dragging() +void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar) +{ + ar(m_clipping_plane_distance, + m_clipping_plane_normal, + m_current_mesh_object_id + ); +} + + + +void GLGizmoSlaSupports::on_save(cereal::BinaryOutputArchive& ar) const +{ + ar(m_clipping_plane_distance, + m_clipping_plane_normal, + m_current_mesh_object_id + ); +} + + + void GLGizmoSlaSupports::select_point(int i) { if (i == AllPoints || i == NoPoints) { @@ -1146,6 +1196,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() // If there are no changes, don't touch the front-end. The data in the cache could have been // taken from the backend and copying them to ModelObject would needlessly invalidate them. if (m_unsaved_changes) { + wxGetApp().plater()->take_snapshot(_(L("Support points edit"))); m_model_object->sla_points_status = sla::PointsStatus::UserModified; m_model_object->sla_support_points.clear(); for (const CacheEntry& cache_entry : m_editing_mode_cache) @@ -1204,6 +1255,7 @@ void GLGizmoSlaSupports::auto_generate() )), _(L("Warning")), wxICON_WARNING | wxYES | wxNO); if (m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_editing_mode_cache.empty() || dlg.ShowModal() == wxID_YES) { + wxGetApp().plater()->take_snapshot(_(L("Autogenerate support points"))); m_model_object->sla_support_points.clear(); m_model_object->sla_points_status = sla::PointsStatus::Generating; m_editing_mode_cache.clear(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index b0a505b82..fbc438f1d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -14,6 +14,8 @@ #include "libslic3r/SLAPrint.hpp" #include +#include + namespace Slic3r { namespace GUI { @@ -49,12 +51,21 @@ private: class CacheEntry { public: + CacheEntry() : + support_point(sla::SupportPoint()), selected(false), normal(Vec3f::Zero()) {} + CacheEntry(const sla::SupportPoint& point, bool sel, const Vec3f& norm = Vec3f::Zero()) : support_point(point), selected(sel), normal(norm) {} sla::SupportPoint support_point; bool selected; // whether the point is selected Vec3f normal; + + template + void serialize(Archive & ar) + { + ar(support_point, selected, normal); + } }; public: @@ -139,6 +150,8 @@ protected: virtual std::string on_get_name() const; virtual bool on_is_activable() const; virtual bool on_is_selectable() const; + virtual void on_load(cereal::BinaryInputArchive& ar) override; + virtual void on_save(cereal::BinaryOutputArchive& ar) const override; }; -- cgit v1.2.3 From 2b9d285a16302fd3555a3ead6293baa3d3b4c769 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 17 Jul 2019 15:39:10 +0200 Subject: 'Place on face' gizmo fix (it used invalid pointer after undo/redo was implemented) --- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 18 ++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp | 7 ++----- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src/slic3r/GUI') diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 78f5da58b..cb996a104 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -1,6 +1,7 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoFlatten.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" #include @@ -23,6 +24,22 @@ bool GLGizmoFlatten::on_init() return true; } +void GLGizmoFlatten::on_set_state() +{ + // m_model_object pointer can be invalid (for instance because of undo/redo action), + // we should recover it from the object id + m_model_object = nullptr; + for (const auto mo : *wxGetApp().model_objects()) { + if (mo->id() == m_model_object_id) { + m_model_object = mo; + break; + } + } + + if (m_state == On && is_plane_update_necessary()) + update_planes(); +} + std::string GLGizmoFlatten::on_get_name() const { return (_(L("Place on face")) + " [F]").ToUTF8().data(); @@ -120,6 +137,7 @@ void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object) m_planes_valid = false; } m_model_object = model_object; + m_model_object_id = model_object ? model_object->id() : 0; } void GLGizmoFlatten::update_planes() diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index c8bd056bc..c69d64134 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -31,6 +31,7 @@ private: bool m_planes_valid = false; mutable Vec3d m_starting_center; const ModelObject* m_model_object = nullptr; + ObjectID m_model_object_id = 0; std::vector instances_matrices; void update_planes(); @@ -49,11 +50,7 @@ protected: virtual void on_start_dragging(); virtual void on_render() const; virtual void on_render_for_picking() const; - virtual void on_set_state() - { - if (m_state == On && is_plane_update_necessary()) - update_planes(); - } + virtual void on_set_state() override; }; } // namespace GUI -- cgit v1.2.3