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();