From fb6a08cfb0cf8a2599279efeaecc2f73bb6f4158 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 5 Nov 2018 08:31:54 +0100 Subject: [PATCH 1/5] Rotate of ModelVolume as transformation component (without modifying the mesh) --- src/libslic3r/Model.cpp | 39 +++++++++++++++++++++++++++++++++------ src/libslic3r/Model.hpp | 6 ++++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 36403b8de..e86e09463 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -864,31 +864,33 @@ void ModelObject::scale(const Vec3d &versor) this->invalidate_bounding_box(); } -void ModelObject::rotate(float angle, const Axis& axis) +void ModelObject::rotate(double angle, Axis axis) { for (ModelVolume *v : this->volumes) { - v->mesh.rotate(angle, axis); - v->m_convex_hull.rotate(angle, axis); + v->rotate(angle, axis); } center_around_origin(); +#if !ENABLE_MODELVOLUME_TRANSFORM this->origin_translation = Vec3d::Zero(); +#endif // !ENABLE_MODELVOLUME_TRANSFORM this->invalidate_bounding_box(); } -void ModelObject::rotate(float angle, const Vec3d& axis) +void ModelObject::rotate(double angle, const Vec3d& axis) { for (ModelVolume *v : this->volumes) { - v->mesh.rotate(angle, axis); - v->m_convex_hull.rotate(angle, axis); + v->rotate(angle, axis); } center_around_origin(); +#if !ENABLE_MODELVOLUME_TRANSFORM this->origin_translation = Vec3d::Zero(); +#endif // !ENABLE_MODELVOLUME_TRANSFORM this->invalidate_bounding_box(); } @@ -1249,6 +1251,31 @@ void ModelVolume::scale(const Vec3d& scaling_factors) #endif // ENABLE_MODELVOLUME_TRANSFORM } +void ModelVolume::rotate(double angle, Axis axis) +{ +#if ENABLE_MODELVOLUME_TRANSFORM + switch (axis) + { + case X: { rotate(angle, Vec3d::UnitX()); break; } + case Y: { rotate(angle, Vec3d::UnitY()); break; } + case Z: { rotate(angle, Vec3d::UnitZ()); break; } + } +#else + mesh.rotate(angle, axis); + m_convex_hull.rotate(angle, axis); +#endif // ENABLE_MODELVOLUME_TRANSFORM +} + +void ModelVolume::rotate(double angle, const Vec3d& axis) +{ +#if ENABLE_MODELVOLUME_TRANSFORM + m_transformation.set_rotation(m_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix())); +#else + mesh.rotate(angle, axis); + m_convex_hull.rotate(angle, axis); +#endif // ENABLE_MODELVOLUME_TRANSFORM +} + #if !ENABLE_MODELVOLUME_TRANSFORM void ModelInstance::set_rotation(const Vec3d& rotation) { diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 828dfc817..c420c5ead 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -231,8 +231,8 @@ public: void scale(const Vec3d &versor); void scale(const double s) { this->scale(Vec3d(s, s, s)); } void scale(double x, double y, double z) { this->scale(Vec3d(x, y, z)); } - void rotate(float angle, const Axis &axis); - void rotate(float angle, const Vec3d& axis); + void rotate(double angle, Axis axis); + void rotate(double angle, const Vec3d& axis); void mirror(const Axis &axis); size_t materials_count() const; size_t facets_count() const; @@ -319,6 +319,8 @@ public: void scale(const Vec3d& scaling_factors); void scale(double x, double y, double z) { scale(Vec3d(x, y, z)); } void scale(double s) { scale(Vec3d(s, s, s)); } + void rotate(double angle, Axis axis); + void rotate(double angle, const Vec3d& axis); ModelMaterial* assign_unique_material(); From 864bc6ad485481a4dd45ca98d528fe5538c17e9b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 5 Nov 2018 08:51:00 +0100 Subject: [PATCH 2/5] Mirror of ModelVolume as transformation component (without modifying the mesh) --- src/libslic3r/Model.cpp | 24 +++++++++++++++++++++--- src/libslic3r/Model.hpp | 3 ++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index e86e09463..c42691395 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -894,15 +894,16 @@ void ModelObject::rotate(double angle, const Vec3d& axis) this->invalidate_bounding_box(); } -void ModelObject::mirror(const Axis &axis) +void ModelObject::mirror(Axis axis) { for (ModelVolume *v : this->volumes) { - v->mesh.mirror(axis); - v->m_convex_hull.mirror(axis); + v->mirror(axis); } +#if !ENABLE_MODELVOLUME_TRANSFORM this->origin_translation = Vec3d::Zero(); +#endif // !ENABLE_MODELVOLUME_TRANSFORM this->invalidate_bounding_box(); } @@ -1276,6 +1277,23 @@ void ModelVolume::rotate(double angle, const Vec3d& axis) #endif // ENABLE_MODELVOLUME_TRANSFORM } +void ModelVolume::mirror(Axis axis) +{ +#if ENABLE_MODELVOLUME_TRANSFORM + Vec3d mirror = m_transformation.get_mirror(); + switch (axis) + { + case X: { mirror(0) *= -1.0; break; } + case Y: { mirror(1) *= -1.0; break; } + case Z: { mirror(2) *= -1.0; break; } + } + m_transformation.set_mirror(mirror); +#else + mesh.mirror(axis); + m_convex_hull.mirror(axis); +#endif // ENABLE_MODELVOLUME_TRANSFORM +} + #if !ENABLE_MODELVOLUME_TRANSFORM void ModelInstance::set_rotation(const Vec3d& rotation) { diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index c420c5ead..a3aeab739 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -233,7 +233,7 @@ public: void scale(double x, double y, double z) { this->scale(Vec3d(x, y, z)); } void rotate(double angle, Axis axis); void rotate(double angle, const Vec3d& axis); - void mirror(const Axis &axis); + void mirror(Axis axis); size_t materials_count() const; size_t facets_count() const; bool needed_repair() const; @@ -321,6 +321,7 @@ public: void scale(double s) { scale(Vec3d(s, s, s)); } void rotate(double angle, Axis axis); void rotate(double angle, const Vec3d& axis); + void mirror(Axis axis); ModelMaterial* assign_unique_material(); From a9e7b5c645ced9974477aa976a792f6b010d93a1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 2 Nov 2018 12:35:26 +0100 Subject: [PATCH 3/5] Implemented adding of support enforcer/blocker to the object list --- resources/icons/support_blocker_.png | Bin 0 -> 1955 bytes resources/icons/support_enforcer_.png | Bin 0 -> 1744 bytes src/slic3r/GUI/GUI_ObjectList.cpp | 142 ++++++++++---------------- src/slic3r/GUI/GUI_ObjectList.hpp | 9 +- 4 files changed, 58 insertions(+), 93 deletions(-) create mode 100644 resources/icons/support_blocker_.png create mode 100644 resources/icons/support_enforcer_.png diff --git a/resources/icons/support_blocker_.png b/resources/icons/support_blocker_.png new file mode 100644 index 0000000000000000000000000000000000000000..0873c5e6edbf7cb9232723e54f43202eacfa208f GIT binary patch literal 1955 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 literal 0 HcmV?d00001 diff --git a/resources/icons/support_enforcer_.png b/resources/icons/support_enforcer_.png new file mode 100644 index 0000000000000000000000000000000000000000..265cebcb953919dcd947496a4cd36d4683012ee8 GIT binary patch literal 1744 zcmV;>1~2)EP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1b>7V{_w{m&|92?52&a!k~7W(TwUxmxpV()OD( z@iY=ZAY84#-AYd8H=Jn{x z&`;p&zQEhTpU-^q%diuMq1Ey*XqsmMG4#SPWaP!?@l0{7OZM%ee&V5YeYPIS z$O?N#NQz-I;qICjg9uD833tXF9BG^hv>M;}?ml<4k(cCc)FpRQ8hmq31x;=!xJ!-( zpY=X>Jwq4NR?jDa^5m!Eb;w<78glIpEdauGYVeg^{C{Hw_d&T-UlCj3MSZ~!37^eh#^IZ1}#jZi=JYLF{T8k z38oWPCupQJ%WP&l>+EJfhdIt^LHR6p(Zwx(2}@j3mTWS%e|FhZ4msvjxS*7ZEm~ah zC6riFMXgm+ZPn_kuc5}8Hq-{HXVmzD+-KBypw~`cn;znx!2se2`jv93T2XfS) z8_2!mc7s|@{X{VxptcKJPA5~**r1doq;?+lDYdidHR}*emw8jHXnZe{wncTWWfxyf z9;EhawVR@Yvde6>9eA-#I7MYJS^?^iJssHXA9+An94X)?du8dh}~NC&LH%*$}UQ<7>$e zl2=x)7l01cwHF-S*WrOH&sBPy>9XvtC=W3rwt5M73wxpCE7W~4KQBH>%Sw{xyeS0! z#rM4v`bF)R2x$#*&54E`V)Ln{E~P+^iahTg^?Q_`UahQfY1+NZU6iQ9VaWVeOK#ua zoX^{z&fA{f+tXQ^R?-~`wcHit+865mwt7q?oimA!e4ERS|Cr1d{2K2uzxv&F?RzTe z$6S6*C7s1uLr_Cx4?xA510gmjLzPI2ZAI!UT@*DN-DKUBg(_|TLjFW|{(?e5w_;Wn+O1g#uG>Y> zKafS}LM%iSnnfsvLWG9*-f`i3;Tb9(80OxYd(S<0=F0Y4+nc~p5+#PVn<0cYfbEW? zHjvux+8zQ|lKQg!swfI@mm()HuIOqUK8UqvHF1FvgTdf0{|}eXY`)f#45 z)~S@_dENoO0eS6Bc7WvojH^IN`=!~Glx11=0U(3`unYtiFh7_~CY@fdSGnU5!krl7 z5B`HWL6Rit*4EZhsb~fWn3mTmFer-R!9NLXQ=0?wJnz-wn!v>N=MA6* zTvmex+?RA!Dok%x09@4x7f~xPM^gKR8%eWT@EWjIx)*t#KLftr*1{&h($dm+I-S0# zB*qw3BOk>W`$>}QFXXQ#z`5_4Vu8)IJO$T>b`QSLC<~(D)qy0000 menu_items = { L("Add part"), L("Add modifier"), L("Add generic") }; + std::vector menu_object_types_items = {L("Add part"), + L("Add modifier"), + L("Add support enforcer"), + L("Add support bloker"), + L("Add generic") }; + const int obj_types_count = menu_object_types_items.size(); + const int generics_count = 4; - wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size() + 4 + 2); + wxWindowID config_id_base = wxWindow::NewControlId(menu_object_types_items.size() + 4 + 2); + // Add first 4 menu items int i = 0; - for (auto& item : menu_items) { + for (i = 0; i < obj_types_count - 1; i++) { + auto& item = menu_object_types_items[i]; auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); - menu_item->SetBitmap(i == 0 ? m_bmp_solidmesh : m_bmp_modifiermesh); - if (item == "Add generic") - menu_item_add_generic(menu_item, config_id_base + i); + menu_item->SetBitmap(*m_bmp_vector[i]); menu->Append(menu_item); - i++; } + // Add generic modifier + auto& item = menu_object_types_items[i]; + auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); + menu_item->SetBitmap(*m_bmp_vector[1]); // set modifier's icon + menu_item_add_generic(menu_item, config_id_base + i); + menu->Append(menu_item); + // Split object to parts menu->AppendSeparator(); - auto menu_item = menu_item_split(menu, config_id_base + i + 4); + menu_item = menu_item_split(menu, config_id_base + obj_types_count + generics_count); menu->Append(menu_item); menu_item->Enable(is_splittable_object(false)); + // Settings menu->AppendSeparator(); // Append settings popupmenu - menu->Append(menu_item_settings(menu, config_id_base + i + 5, false)); + menu->Append(menu_item_settings(menu, config_id_base + obj_types_count + generics_count+1, false)); menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) { switch (event.GetId() - config_id_base) { - case 0: - load_subobject(); + case 0: // ~ModelVolume::MODEL_PART + case 1: // ~ModelVolume::PARAMETER_MODIFIER + case 2: // ~ModelVolume::SUPPORT_ENFORCER + case 3: // ~ModelVolume::SUPPORT_BLOCKER + load_subobject(event.GetId() - config_id_base); break; - case 1: - load_subobject(true); - break; - case 2: - case 3: case 4: case 5: case 6: + case 7: + case 8: #ifdef __WXMSW__ load_lambda(menu->GetLabel(event.GetId()).ToStdString()); #endif // __WXMSW__ break; - case 7: //3: + case 9: split(false); break; default: @@ -655,31 +677,21 @@ wxMenu* ObjectList::create_add_settings_popupmenu(bool is_part) return menu; } - -// Load SubObjects (parts and modifiers) -void ObjectList::load_subobject(bool is_modifier /*= false*/, bool is_lambda/* = false*/) +void ObjectList::load_subobject(int type) { auto item = GetSelection(); - if (!item) - return; - int obj_idx = -1; - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) - obj_idx = m_objects_model->GetIdByItem(item); - else + if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0)) return; + int obj_idx = m_objects_model->GetIdByItem(item); if (obj_idx < 0) return; wxArrayString part_names; - if (is_lambda) - load_lambda((*m_objects)[obj_idx], part_names, is_modifier); - else - load_part((*m_objects)[obj_idx], part_names, is_modifier); + load_part((*m_objects)[obj_idx], part_names, type); parts_changed(obj_idx); for (int i = 0; i < part_names.size(); ++i) { - const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), - is_modifier ? m_bmp_modifiermesh : m_bmp_solidmesh); + const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), *m_bmp_vector[type]); if (i == part_names.size() - 1) select_item(sel_item); @@ -688,11 +700,12 @@ void ObjectList::load_subobject(bool is_modifier /*= false*/, bool is_lambda/* = #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME // selection_changed(); #endif //no __WXOSX__//__WXMSW__ + } void ObjectList::load_part( ModelObject* model_object, wxArrayString& part_names, - const bool is_modifier) + int type) { wxWindow* parent = wxGetApp().tab_panel()->GetPage(0); @@ -722,7 +735,7 @@ void ObjectList::load_part( ModelObject* model_object, } for (auto volume : object->volumes) { auto new_volume = model_object->add_volume(*volume); - new_volume->set_type(is_modifier ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART); + new_volume->set_type(static_cast(type)); boost::filesystem::path(input_file).filename().string(); new_volume->name = boost::filesystem::path(input_file).filename().string(); @@ -738,58 +751,7 @@ void ObjectList::load_part( ModelObject* model_object, } } } -} -void ObjectList::load_lambda( ModelObject* model_object, - wxArrayString& part_names, - const bool is_modifier) -{ - auto dlg = new LambdaObjectDialog(GetMainWindow()); - if (dlg->ShowModal() == wxID_CANCEL) { - m_parts_changed = false; - return; - } - - std::string name = "lambda-"; - TriangleMesh mesh; - - auto params = dlg->ObjectParameters(); - switch (params.type) - { - case LambdaTypeBox:{ - mesh = make_cube(params.dim[0], params.dim[1], params.dim[2]); - name += "Box"; - break; } - case LambdaTypeCylinder:{ - mesh = make_cylinder(params.cyl_r, params.cyl_h); - name += "Cylinder"; - break; } - case LambdaTypeSphere:{ - mesh = make_sphere(params.sph_rho); - name += "Sphere"; - break; } - case LambdaTypeSlab:{ - const auto& size = model_object->bounding_box().size(); - mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h); - // box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z - mesh.translate(-size(0)*1.5 / 2.0, -size(1)*1.5 / 2.0, params.slab_z); - name += "Slab"; - break; } - default: - break; - } - mesh.repair(); - - auto new_volume = model_object->add_volume(mesh); - new_volume->set_type(is_modifier ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART); - - new_volume->name = name; - // set a default extruder value, since user can't add it manually - new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); - - part_names.Add(name); - - m_parts_changed = true; } void ObjectList::load_lambda(const std::string& type_name) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 3a7de9e3b..63bf3efd0 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -28,10 +28,14 @@ class ObjectList : public wxDataViewCtrl wxBitmap m_bmp_modifiermesh; wxBitmap m_bmp_solidmesh; + wxBitmap m_bmp_support_enforcer; + wxBitmap m_bmp_support_blocker; wxBitmap m_bmp_manifold_warning; wxBitmap m_bmp_cog; wxBitmap m_bmp_split; + std::vector m_bmp_vector; + int m_selected_object_id = -1; bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler @@ -85,9 +89,8 @@ public: wxMenu* create_part_settings_popupmenu(); wxMenu* create_add_settings_popupmenu(bool is_part); - void load_subobject(bool is_modifier = false, bool is_lambda = false); - void load_part(ModelObject* model_object, wxArrayString& part_names, const bool is_modifier); - void load_lambda(ModelObject* model_object, wxArrayString& part_names, const bool is_modifier); + void load_subobject(int type); + void load_part(ModelObject* model_object, wxArrayString& part_names, int type); void load_lambda(const std::string& type_name); void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(); From 4eae6c0189c71e67a8bbeb1b2f6e4e6192a3fa2b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 2 Nov 2018 23:27:31 +0100 Subject: [PATCH 4/5] Changing of a type of a volume in the object list --- src/slic3r/GUI/GUI_ObjectList.cpp | 76 ++++++++++++++++++++++++------- src/slic3r/GUI/GUI_ObjectList.hpp | 3 ++ src/slic3r/GUI/wxExtensions.cpp | 33 +++++++++++--- src/slic3r/GUI/wxExtensions.hpp | 9 +++- 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 082a9f66d..6bb7d2785 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -36,11 +36,11 @@ ObjectList::ObjectList(wxWindow* parent) : CATEGORY_ICON[L("Advanced")] = wxBitmap(from_u8(var("wand.png")), wxBITMAP_TYPE_PNG); } - init_icons(); - // create control create_objects_ctrl(); + init_icons(); + // describe control behavior Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) { selection_changed(); @@ -224,6 +224,7 @@ void ObjectList::init_icons() m_bmp_vector.push_back(&m_bmp_modifiermesh); // Add modifier m_bmp_vector.push_back(&m_bmp_support_enforcer); // Add support enforcer m_bmp_vector.push_back(&m_bmp_support_blocker); // Add support blocker + m_objects_model->SetVolumeBitmaps(m_bmp_vector); // init icon for manifold warning m_bmp_manifold_warning = wxBitmap(from_u8(var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); @@ -569,10 +570,10 @@ wxMenu* ObjectList::create_add_part_popupmenu() const int obj_types_count = menu_object_types_items.size(); const int generics_count = 4; - wxWindowID config_id_base = wxWindow::NewControlId(menu_object_types_items.size() + 4 + 2); + wxWindowID config_id_base = NewControlId(menu_object_types_items.size() + 4 + 2); // Add first 4 menu items - int i = 0; + int i; for (i = 0; i < obj_types_count - 1; i++) { auto& item = menu_object_types_items[i]; auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); @@ -631,24 +632,33 @@ wxMenu* ObjectList::create_add_part_popupmenu() wxMenu* ObjectList::create_part_settings_popupmenu() { wxMenu *menu = new wxMenu; - wxWindowID config_id_base = wxWindow::NewControlId(2); + wxWindowID config_id_base = NewControlId(3); auto menu_item = menu_item_split(menu, config_id_base); menu->Append(menu_item); menu_item->Enable(is_splittable_object(true)); + // Append change part type menu->AppendSeparator(); + menu->Append(new wxMenuItem(menu, config_id_base + 1, _(L("Change type")))); + // Append settings popupmenu - menu->Append(menu_item_settings(menu, config_id_base + 1, true)); + menu->AppendSeparator(); + menu_item = menu_item_settings(menu, config_id_base + 2, true); + menu->Append(menu_item); + menu_item->Enable(get_selected_model_volume()->type() <= ModelVolume::PARAMETER_MODIFIER); menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) { switch (event.GetId() - config_id_base) { case 0: split(true); break; - default:{ + case 1: + change_part_type(); + break; + default: get_settings_choice(menu, event.GetId(), true); - break; } + break; } }); @@ -691,7 +701,7 @@ void ObjectList::load_subobject(int type) parts_changed(obj_idx); for (int i = 0; i < part_names.size(); ++i) { - const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), *m_bmp_vector[type]); + const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), /**m_bmp_vector[*/type/*]*/); if (i == part_names.size() - 1) select_item(sel_item); @@ -790,8 +800,7 @@ void ObjectList::load_lambda(const std::string& type_name) m_parts_changed = true; parts_changed(m_selected_object_id); - select_item(m_objects_model->AddVolumeChild(GetSelection(), - name, m_bmp_modifiermesh)); + select_item(m_objects_model->AddVolumeChild(GetSelection(), name, ModelVolume::PARAMETER_MODIFIER/*m_bmp_modifiermesh*/)); #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME selection_changed(); #endif //no __WXOSX__ //__WXMSW__ @@ -908,7 +917,7 @@ void ObjectList::split(const bool split_part) for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddVolumeChild(parent, model_object->volumes[id]->name, - model_object->volumes[id]->is_modifier() ? m_bmp_modifiermesh : m_bmp_solidmesh, + model_object->volumes[id]->is_modifier() ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART, model_object->volumes[id]->config.has("extruder") ? model_object->volumes[id]->config.option("extruder")->value : 0, false); @@ -918,7 +927,7 @@ void ObjectList::split(const bool split_part) else { for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddVolumeChild(item, model_object->volumes[id]->name, - m_bmp_solidmesh, + ModelVolume::MODEL_PART, model_object->volumes[id]->config.has("extruder") ? model_object->volumes[id]->config.option("extruder")->value : 0, false); @@ -929,7 +938,7 @@ void ObjectList::split(const bool split_part) parts_changed(m_selected_object_id); // restores selection - _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection().add_object(m_selected_object_id); +// _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection().add_object(m_selected_object_id); } bool ObjectList::get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume) @@ -979,7 +988,7 @@ void ObjectList::part_settings_changed() void ObjectList::parts_changed(int obj_idx) { - wxGetApp().plater()->changed_object(get_selected_obj_idx()); + wxGetApp().plater()->changed_object(obj_idx); m_parts_changed = false; } @@ -1071,7 +1080,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddVolumeChild(item, model_object->volumes[id]->name, - m_bmp_solidmesh, + ModelVolume::MODEL_PART, model_object->volumes[id]->config.option("extruder")->value, false); Expand(item); @@ -1296,5 +1305,40 @@ void ObjectList::fix_multiselection_conflicts() m_prevent_list_events = false; } +ModelVolume* ObjectList::get_selected_model_volume() +{ + auto item = GetSelection(); + if (!item || m_objects_model->GetItemType(item) != itVolume) + return nullptr; + + const auto vol_idx = m_objects_model->GetVolumeIdByItem(item); + const auto obj_idx = get_selected_obj_idx(); + if (vol_idx < 0 || obj_idx < 0) + return nullptr; + + return (*m_objects)[obj_idx]->volumes[vol_idx]; +} + +void ObjectList::change_part_type() +{ + ModelVolume* volume = get_selected_model_volume(); + if (!volume) + return; + const auto type = volume->type(); + + const wxString names[] = { "Part", "Modifier", "Support Enforcer", "Support Blocker" }; + + auto new_type = wxGetSingleChoiceIndex("Type: ", _(L("Select type of part")), wxArrayString(4, names), type); + + if (new_type == type || new_type < 0) + return; + + volume->set_type(static_cast(new_type)); + m_objects_model->SetVolumeType(GetSelection(), new_type); + + m_parts_changed = true; + parts_changed(get_selected_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 63bf3efd0..ca9de5f76 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -145,6 +145,9 @@ public: void select_all(); // correct current selections to avoid of the possible conflicts void fix_multiselection_conflicts(); + + ModelVolume* get_selected_model_volume(); + void change_part_type(); }; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 8d7498170..8d6a0408e 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -9,6 +9,7 @@ #include #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" +#include "Model.hpp" wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const std::string& icon, wxEvtHandler* event_handler) @@ -400,10 +401,9 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON;//Slic3r::GUI::get_category_icon(); + std::map& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON; for (auto& cat : m_opt_categories) m_name += cat + "; "; @@ -453,19 +453,18 @@ wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name) wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &parent_item, const wxString &name, - const wxBitmap& icon, + const int volume_type, const int extruder/* = 0*/, const bool create_frst_child/* = true*/) { PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); - const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); + wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); if (create_frst_child && root->m_volumes_cnt == 0) { - const auto bmp_solid_mesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG); - const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, bmp_solid_mesh, extruder_str, 0); + const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, *m_volume_bmps[0], extruder_str, 0); root->Append(node); // notify control const wxDataViewItem child((void*)node); @@ -474,7 +473,10 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa root->m_volumes_cnt++; } - const auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, root->m_volumes_cnt); +// if (volume_type >= Slic3r::ModelVolume::SUPPORT_ENFORCER) +// extruder_str = ""; + + const auto node = new PrusaObjectDataViewModelNode(root, name, *m_volume_bmps[volume_type], extruder_str, root->m_volumes_cnt); root->Append(node); // notify control const wxDataViewItem child((void*)node); @@ -563,6 +565,10 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) auto id = node_parent->GetChildren().Index(node); auto idx = node->GetIdx(); node_parent->GetChildren().Remove(node); + + if (node->m_type == itVolume) + node_parent->m_volumes_cnt--; + if (id > 0) { if(id == node_parent->GetChildCount()) id--; ret_item = wxDataViewItem(node_parent->GetChildren().Item(id)); @@ -692,6 +698,9 @@ void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent) auto item = wxDataViewItem(node); children.RemoveAt(id); + if (node->m_type == itVolume) + root->m_volumes_cnt--; + // free the node delete node; @@ -1050,6 +1059,16 @@ void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, ItemChanged(item); } +void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const int type) +{ + if (!item.IsOk() || GetItemType(item) != itVolume) + return; + + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + node->SetBitmap(*m_volume_bmps[type]); + ItemChanged(item); +} + //----------------------------------------------------------------------------- // PrusaDataViewBitmapText //----------------------------------------------------------------------------- diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 60bc083fe..3c9159233 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -424,7 +424,9 @@ private: class PrusaObjectDataViewModel :public wxDataViewModel { - std::vector m_objects; + std::vector m_objects; + std::vector m_volume_bmps; + public: PrusaObjectDataViewModel(); ~PrusaObjectDataViewModel(); @@ -432,7 +434,7 @@ public: wxDataViewItem Add(const wxString &name); wxDataViewItem AddVolumeChild(const wxDataViewItem &parent_item, const wxString &name, - const wxBitmap& icon, + const int volume_type, const int extruder = 0, const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); @@ -491,6 +493,9 @@ public: wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; bool IsSettingsItem(const wxDataViewItem &item) const; void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector& categories); + + void SetVolumeBitmaps(const std::vector& volume_bmps) { m_volume_bmps = volume_bmps; } + void SetVolumeType(const wxDataViewItem &item, const int type); }; // ---------------------------------------------------------------------------- From be57bb5c0ebabd9bdd136230aa5a92eb8d7ab703 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 5 Nov 2018 08:55:44 +0100 Subject: [PATCH 5/5] Update showing of the settings after part type changing --- src/slic3r/GUI/GUI_ObjectList.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 6bb7d2785..da5095bb6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1333,11 +1333,24 @@ void ObjectList::change_part_type() if (new_type == type || new_type < 0) return; + const auto item = GetSelection(); volume->set_type(static_cast(new_type)); - m_objects_model->SetVolumeType(GetSelection(), new_type); + m_objects_model->SetVolumeType(item, new_type); m_parts_changed = true; parts_changed(get_selected_obj_idx()); + + // Update settings showing, if we have it + //(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer) + const auto settings_item = m_objects_model->GetSettingsItem(item); + if (settings_item && + new_type == ModelVolume::SUPPORT_ENFORCER || new_type == ModelVolume::SUPPORT_BLOCKER) { + m_objects_model->Delete(settings_item); + } + else if (!settings_item && + new_type == ModelVolume::MODEL_PART || new_type == ModelVolume::PARAMETER_MODIFIER) { + select_item(m_objects_model->AddSettingsChild(item)); + } } } //namespace GUI