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); + const t_layer_height_range& next_range = (++ranges.find(current_range))->first; - // 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; - } - - 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; }; // ----------------------------------------------------------------------------