From bdd694ddcb28665c2182690e1c774cd09c40334e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Jul 2019 08:36:08 +0200 Subject: [PATCH 01/20] Added member bool printable to ModelObject and ModelInstance --- src/libslic3r/Model.cpp | 3 +++ src/libslic3r/Model.hpp | 53 +++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 858ae52b2..97d045ae0 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -644,6 +644,9 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs) this->sla_points_status = rhs.sla_points_status; this->layer_config_ranges = rhs.layer_config_ranges; // #ys_FIXME_experiment this->layer_height_profile = rhs.layer_height_profile; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + this->printable = rhs.printable; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->origin_translation = rhs.origin_translation; m_bounding_box = rhs.m_bounding_box; m_bounding_box_valid = rhs.m_bounding_box_valid; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index a3281e522..18e3f8fb6 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -192,6 +192,10 @@ public: // Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers. // The pairs of are packed into a 1D array. std::vector layer_height_profile; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Whether or not this object is printable + bool printable; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // This vector holds position of selected support points for SLA. The data are // saved in mesh coordinates to allow using them for several instances. @@ -304,11 +308,17 @@ public: private: friend class Model; // This constructor assigns new ID to this ModelObject and its config. - explicit ModelObject(Model *model) : m_model(model), origin_translation(Vec3d::Zero()), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + explicit ModelObject(Model* model) : m_model(model), printable(true), origin_translation(Vec3d::Zero()), +// explicit ModelObject(Model* model) : m_model(model), origin_translation(Vec3d::Zero()), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) - { assert(this->id().valid()); } - explicit ModelObject(int) : ObjectBase(-1), config(-1), m_model(nullptr), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) - { assert(this->id().invalid()); assert(this->config.id().invalid()); } + { assert(this->id().valid()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + explicit ModelObject(int) : ObjectBase(-1), config(-1), m_model(nullptr), printable(true), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) +// explicit ModelObject(int) : ObjectBase(-1), config(-1), m_model(nullptr), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + { assert(this->id().invalid()); assert(this->config.id().invalid()); } ~ModelObject(); void assign_new_unique_ids_recursive() override; @@ -370,8 +380,11 @@ private: template void serialize(Archive &ar) { ar(cereal::base_class(this)); Internal::StaticSerializationWrapper config_wrapper(config); - ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_height_profile, sla_support_points, sla_points_status, origin_translation, - m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_height_profile, sla_support_points, sla_points_status, printable, origin_translation, +// ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_height_profile, sla_support_points, sla_points_status, origin_translation, +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid); } }; @@ -595,6 +608,10 @@ private: public: // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state()) EPrintVolumeState print_volume_state; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Whether or not this instance is printable + bool printable; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ModelObject* get_object() const { return this->object; } @@ -639,8 +656,11 @@ public: const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } - bool is_printable() const { return print_volume_state == PVS_Inside; } - +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool is_printable() const { return printable && (print_volume_state == PVS_Inside); } +// bool is_printable() const { return print_volume_state == PVS_Inside; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Getting the input polygon for arrange arrangement::ArrangePolygon get_arrange_polygon() const; @@ -667,10 +687,16 @@ private: ModelObject* object; // Constructor, which assigns a new unique ID. - explicit ModelInstance(ModelObject *object) : print_volume_state(PVS_Inside), object(object) { assert(this->id().valid()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + explicit ModelInstance(ModelObject* object) : print_volume_state(PVS_Inside), printable(true), object(object) { assert(this->id().valid()); } +// explicit ModelInstance(ModelObject* object) : print_volume_state(PVS_Inside), object(object) { assert(this->id().valid()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Constructor, which assigns a new unique ID. explicit ModelInstance(ModelObject *object, const ModelInstance &other) : - m_transformation(other.m_transformation), print_volume_state(PVS_Inside), object(object) { assert(this->id().valid() && this->id() != other.id()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_transformation(other.m_transformation), print_volume_state(PVS_Inside), printable(true), object(object) {assert(this->id().valid() && this->id() != other.id());} +// m_transformation(other.m_transformation), print_volume_state(PVS_Inside), object(object) { assert(this->id().valid() && this->id() != other.id()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ explicit ModelInstance(ModelInstance &&rhs) = delete; ModelInstance& operator=(const ModelInstance &rhs) = delete; @@ -681,8 +707,11 @@ private: // Used for deserialization, therefore no IDs are allocated. ModelInstance() : ObjectBase(-1), object(nullptr) { assert(this->id().invalid()); } template void serialize(Archive &ar) { - ar(m_transformation, print_volume_state); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + ar(m_transformation, print_volume_state, printable); +// ar(m_transformation, print_volume_state); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + } }; class ModelWipeTower final : public ObjectBase From b1a1ed63945971ac1b97c049a5f80173b1cf426d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Jul 2019 10:12:13 +0200 Subject: [PATCH 02/20] Toggle instance printable member by 3D scene context menu --- src/slic3r/GUI/GUI_ObjectList.cpp | 15 +++++++++++++++ src/slic3r/GUI/GUI_ObjectList.hpp | 3 +++ src/slic3r/GUI/Plater.cpp | 15 +++++++++++++++ src/slic3r/GUI/wxExtensions.cpp | 20 ++++++++++++++++++++ src/slic3r/GUI/wxExtensions.hpp | 5 +++++ 5 files changed, 58 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a7d4ab16d..2a6dd6a19 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1378,6 +1378,21 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu, wxWind [this](wxCommandEvent&) { split_instances(); }, "", menu, [](){return wxGetApp().plater()->can_set_instance_to_object(); }, parent); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +wxMenuItem* ObjectList::append_menu_item_printable(wxMenu* menu, wxWindow* parent) +{ + return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [this](wxCommandEvent&) { + int instance_idx = wxGetApp().plater()->canvas3D()->get_selection().get_instance_idx(); + if (instance_idx != -1) + { + int obj_idx = wxGetApp().plater()->get_selected_object_idx(); + (*m_objects)[obj_idx]->instances[instance_idx]->printable = !(*m_objects)[obj_idx]->instances[instance_idx]->printable; + + } + }, menu); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void ObjectList::append_menu_items_osx(wxMenu* menu) { append_menu_item(menu, wxID_ANY, _(L("Rename")), "", diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 39558d1c5..9802adddf 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -225,6 +225,9 @@ public: 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); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + wxMenuItem* append_menu_item_printable(wxMenu* menu, wxWindow* parent); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void append_menu_items_osx(wxMenu* menu); wxMenuItem* append_menu_item_fix_through_netfabb(wxMenu* menu); void append_menu_item_export_stl(wxMenu* menu) const ; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 38ad58037..a0995c892 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3490,6 +3490,11 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ sidebar->obj_list()->append_menu_item_instance_to_object(menu, q); menu->AppendSeparator(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + wxMenuItem* menu_item_printable = sidebar->obj_list()->append_menu_item_printable(menu, q); + menu->AppendSeparator(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + append_menu_item(menu, wxID_ANY, _(L("Reload from Disk")), _(L("Reload the selected file from Disk")), [this](wxCommandEvent&) { reload_from_disk(); }); @@ -3497,6 +3502,16 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ [this](wxCommandEvent&) { q->export_stl(false, true); }); menu->AppendSeparator(); + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { + const Selection& selection = get_selection(); + int instance_idx = selection.get_instance_idx(); + evt.Enable(instance_idx != -1); + if (instance_idx != -1) + evt.Check(model.objects[selection.get_object_idx()]->instances[instance_idx]->printable); + }, menu_item_printable->GetId()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 9f36eceb9..e707a7476 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -157,6 +157,26 @@ wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, return item; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const wxString& description, + std::function cb, wxEvtHandler* event_handler) +{ + if (id == wxID_ANY) + id = wxNewId(); + + wxMenuItem* item = menu->AppendCheckItem(id, string, description); + +#ifdef __WXMSW__ + if (event_handler != nullptr && event_handler != menu) + event_handler->Bind(wxEVT_MENU, cb, id); + else +#endif // __WXMSW__ + menu->Bind(wxEVT_MENU, cb, id); + + return item; +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index d7d5fcac2..56349f9e2 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -43,6 +43,11 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const wxString& description, + std::function cb, wxEvtHandler* event_handler); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + class wxDialog; void edit_tooltip(wxString& tooltip); void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector& btn_ids); From 03820a38cf4c551d29c22b854a769373f5492fa1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Jul 2019 11:01:50 +0200 Subject: [PATCH 03/20] Render non printable instances with a darker color --- src/slic3r/GUI/3DScene.cpp | 19 +++++++++++++++++++ src/slic3r/GUI/3DScene.hpp | 7 +++++++ src/slic3r/GUI/GUI_ObjectList.cpp | 15 ++++++++------- src/slic3r/GUI/Plater.cpp | 3 +++ src/slic3r/GUI/Selection.cpp | 26 ++++++++++++++++++++++++++ src/slic3r/GUI/Selection.hpp | 4 ++++ 6 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index dba595846..d27d4a78c 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -200,6 +200,9 @@ const float GLVolume::HOVER_DESELECT_COLOR[4] = { 1.0f, 0.75f, 0.75f, 1.0f }; const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f }; const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f }; const float GLVolume::DISABLED_COLOR[4] = { 0.25f, 0.25f, 0.25f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +const float GLVolume::NON_PRINTABLE_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const float GLVolume::MODEL_COLOR[4][4] = { { 1.0f, 1.0f, 0.0f, 1.f }, { 1.0f, 0.5f, 0.5f, 1.f }, @@ -218,6 +221,9 @@ GLVolume::GLVolume(float r, float g, float b, float a) , extruder_id(0) , selected(false) , disabled(false) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + , printable(true) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ , is_active(true) , zoom_to_volumes(true) , shader_outside_printer_detection_enabled(false) @@ -271,10 +277,23 @@ void GLVolume::set_render_color() set_render_color(DISABLED_COLOR, 4); else if (is_outside && shader_outside_printer_detection_enabled) set_render_color(OUTSIDE_COLOR, 4); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// else if (!printable) +// set_render_color(NON_PRINTABLE_COLOR, 4); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else set_render_color(color, 4); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (!printable) + { + render_color[0] /= 4; + render_color[1] /= 4; + render_color[2] /= 4; + } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (force_transparent) render_color[3] = color[3]; } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 8ae57eeae..723c55501 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -231,6 +231,9 @@ public: static const float OUTSIDE_COLOR[4]; static const float SELECTED_OUTSIDE_COLOR[4]; static const float DISABLED_COLOR[4]; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + static const float NON_PRINTABLE_COLOR[4]; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const float MODEL_COLOR[4][4]; static const float SLA_SUPPORT_COLOR[4]; static const float SLA_PAD_COLOR[4]; @@ -294,6 +297,10 @@ public: bool selected; // Is this object disabled from selection? bool disabled; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Is this object printable? + bool printable; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Whether or not this volume is active for rendering bool is_active; // Whether or not to use this volume when applying zoom_to_volumes() diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2a6dd6a19..58e96e4bc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1382,13 +1382,14 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu, wxWind wxMenuItem* ObjectList::append_menu_item_printable(wxMenu* menu, wxWindow* parent) { return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [this](wxCommandEvent&) { - int instance_idx = wxGetApp().plater()->canvas3D()->get_selection().get_instance_idx(); - if (instance_idx != -1) - { - int obj_idx = wxGetApp().plater()->get_selected_object_idx(); - (*m_objects)[obj_idx]->instances[instance_idx]->printable = !(*m_objects)[obj_idx]->instances[instance_idx]->printable; - - } + wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); +// int instance_idx = wxGetApp().plater()->canvas3D()->get_selection().get_instance_idx(); +// if (instance_idx != -1) +// { +// int obj_idx = wxGetApp().plater()->get_selected_object_idx(); +// (*m_objects)[obj_idx]->instances[instance_idx]->printable = !(*m_objects)[obj_idx]->instances[instance_idx]->printable; +// +// } }, menu); } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a0995c892..50c6f5b67 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3509,7 +3509,10 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ int instance_idx = selection.get_instance_idx(); evt.Enable(instance_idx != -1); if (instance_idx != -1) + { evt.Check(model.objects[selection.get_object_idx()]->instances[instance_idx]->printable); + view3D->set_as_dirty(); + } }, menu_item_printable->GetId()); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 211863627..4db126b80 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1459,6 +1459,32 @@ std::vector Selection::get_unselected_volume_idxs_from(const std:: return idxs; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void Selection::toggle_instance_printable_state() +{ + int instance_idx = get_instance_idx(); + if (instance_idx == -1) + return; + + int obj_idx = get_object_idx(); + if ((0 <= obj_idx) && (obj_idx < (int)m_model->objects.size())) + { + ModelObject* model_object = m_model->objects[obj_idx]; + if ((0 <= instance_idx) && (instance_idx < (int)model_object->instances.size())) + { + ModelInstance* instance = model_object->instances[instance_idx]; + instance->printable = !instance->printable; + + for (GLVolume* volume : *m_volumes) + { + if ((volume->object_idx() == obj_idx) && (volume->instance_idx() == instance_idx)) + volume->printable = instance->printable; + } + } + } +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Selection::update_valid() { m_valid = (m_volumes != nullptr) && (m_model != nullptr); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 0f71cefc4..94fa56909 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -336,6 +336,10 @@ public: // returns the list of idxs of the volumes contained in the given list but not in the selection std::vector get_unselected_volume_idxs_from(const std::vector& volume_idxs) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void toggle_instance_printable_state(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + private: void update_valid(); void update_type(); From 0647d3ac1ed5a60e97cfee23f4edb5a402cba6b3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 31 Jul 2019 11:12:50 +0200 Subject: [PATCH 04/20] Code cleanup --- src/libslic3r/Model.cpp | 2 -- src/libslic3r/Model.hpp | 25 ------------------------- src/slic3r/GUI/3DScene.cpp | 11 ----------- src/slic3r/GUI/3DScene.hpp | 5 ----- src/slic3r/GUI/GUI_ObjectList.cpp | 9 --------- src/slic3r/GUI/GUI_ObjectList.hpp | 2 -- src/slic3r/GUI/Plater.cpp | 4 ---- src/slic3r/GUI/Selection.cpp | 2 -- src/slic3r/GUI/Selection.hpp | 2 -- src/slic3r/GUI/wxExtensions.cpp | 2 -- src/slic3r/GUI/wxExtensions.hpp | 2 -- 11 files changed, 66 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 97d045ae0..25cd92d86 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -644,9 +644,7 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs) this->sla_points_status = rhs.sla_points_status; this->layer_config_ranges = rhs.layer_config_ranges; // #ys_FIXME_experiment this->layer_height_profile = rhs.layer_height_profile; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->printable = rhs.printable; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->origin_translation = rhs.origin_translation; m_bounding_box = rhs.m_bounding_box; m_bounding_box_valid = rhs.m_bounding_box_valid; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 18e3f8fb6..239ede489 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -192,10 +192,8 @@ public: // Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers. // The pairs of are packed into a 1D array. std::vector layer_height_profile; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Whether or not this object is printable bool printable; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // This vector holds position of selected support points for SLA. The data are // saved in mesh coordinates to allow using them for several instances. @@ -308,16 +306,10 @@ public: private: friend class Model; // This constructor assigns new ID to this ModelObject and its config. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ explicit ModelObject(Model* model) : m_model(model), printable(true), origin_translation(Vec3d::Zero()), -// explicit ModelObject(Model* model) : m_model(model), origin_translation(Vec3d::Zero()), -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) { assert(this->id().valid()); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ explicit ModelObject(int) : ObjectBase(-1), config(-1), m_model(nullptr), printable(true), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) -// explicit ModelObject(int) : ObjectBase(-1), config(-1), m_model(nullptr), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { assert(this->id().invalid()); assert(this->config.id().invalid()); } ~ModelObject(); void assign_new_unique_ids_recursive() override; @@ -380,10 +372,7 @@ private: template void serialize(Archive &ar) { ar(cereal::base_class(this)); Internal::StaticSerializationWrapper config_wrapper(config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_height_profile, sla_support_points, sla_points_status, printable, origin_translation, -// ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_height_profile, sla_support_points, sla_points_status, origin_translation, -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid); } }; @@ -608,10 +597,8 @@ private: public: // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state()) EPrintVolumeState print_volume_state; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Whether or not this instance is printable bool printable; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ModelObject* get_object() const { return this->object; } @@ -656,10 +643,7 @@ public: const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool is_printable() const { return printable && (print_volume_state == PVS_Inside); } -// bool is_printable() const { return print_volume_state == PVS_Inside; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Getting the input polygon for arrange arrangement::ArrangePolygon get_arrange_polygon() const; @@ -687,16 +671,10 @@ private: ModelObject* object; // Constructor, which assigns a new unique ID. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ explicit ModelInstance(ModelObject* object) : print_volume_state(PVS_Inside), printable(true), object(object) { assert(this->id().valid()); } -// explicit ModelInstance(ModelObject* object) : print_volume_state(PVS_Inside), object(object) { assert(this->id().valid()); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Constructor, which assigns a new unique ID. explicit ModelInstance(ModelObject *object, const ModelInstance &other) : -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_transformation(other.m_transformation), print_volume_state(PVS_Inside), printable(true), object(object) {assert(this->id().valid() && this->id() != other.id());} -// m_transformation(other.m_transformation), print_volume_state(PVS_Inside), object(object) { assert(this->id().valid() && this->id() != other.id()); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ explicit ModelInstance(ModelInstance &&rhs) = delete; ModelInstance& operator=(const ModelInstance &rhs) = delete; @@ -707,10 +685,7 @@ private: // Used for deserialization, therefore no IDs are allocated. ModelInstance() : ObjectBase(-1), object(nullptr) { assert(this->id().invalid()); } template void serialize(Archive &ar) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ar(m_transformation, print_volume_state, printable); -// ar(m_transformation, print_volume_state); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } }; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index d27d4a78c..92137d1a6 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -200,9 +200,6 @@ const float GLVolume::HOVER_DESELECT_COLOR[4] = { 1.0f, 0.75f, 0.75f, 1.0f }; const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f }; const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f }; const float GLVolume::DISABLED_COLOR[4] = { 0.25f, 0.25f, 0.25f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -const float GLVolume::NON_PRINTABLE_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const float GLVolume::MODEL_COLOR[4][4] = { { 1.0f, 1.0f, 0.0f, 1.f }, { 1.0f, 0.5f, 0.5f, 1.f }, @@ -221,9 +218,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) , extruder_id(0) , selected(false) , disabled(false) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ , printable(true) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ , is_active(true) , zoom_to_volumes(true) , shader_outside_printer_detection_enabled(false) @@ -277,22 +272,16 @@ void GLVolume::set_render_color() set_render_color(DISABLED_COLOR, 4); else if (is_outside && shader_outside_printer_detection_enabled) set_render_color(OUTSIDE_COLOR, 4); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (!printable) -// set_render_color(NON_PRINTABLE_COLOR, 4); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else set_render_color(color, 4); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!printable) { render_color[0] /= 4; render_color[1] /= 4; render_color[2] /= 4; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (force_transparent) render_color[3] = color[3]; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 723c55501..8dc7b9649 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -231,9 +231,6 @@ public: static const float OUTSIDE_COLOR[4]; static const float SELECTED_OUTSIDE_COLOR[4]; static const float DISABLED_COLOR[4]; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - static const float NON_PRINTABLE_COLOR[4]; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const float MODEL_COLOR[4][4]; static const float SLA_SUPPORT_COLOR[4]; static const float SLA_PAD_COLOR[4]; @@ -297,10 +294,8 @@ public: bool selected; // Is this object disabled from selection? bool disabled; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Is this object printable? bool printable; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Whether or not this volume is active for rendering bool is_active; // Whether or not to use this volume when applying zoom_to_volumes() diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 58e96e4bc..a33e442ff 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1378,21 +1378,12 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu, wxWind [this](wxCommandEvent&) { split_instances(); }, "", menu, [](){return wxGetApp().plater()->can_set_instance_to_object(); }, parent); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxMenuItem* ObjectList::append_menu_item_printable(wxMenu* menu, wxWindow* parent) { return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [this](wxCommandEvent&) { wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); -// int instance_idx = wxGetApp().plater()->canvas3D()->get_selection().get_instance_idx(); -// if (instance_idx != -1) -// { -// int obj_idx = wxGetApp().plater()->get_selected_object_idx(); -// (*m_objects)[obj_idx]->instances[instance_idx]->printable = !(*m_objects)[obj_idx]->instances[instance_idx]->printable; -// -// } }, menu); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void ObjectList::append_menu_items_osx(wxMenu* menu) { diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 9802adddf..cbffaaa0c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -225,9 +225,7 @@ public: 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); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxMenuItem* append_menu_item_printable(wxMenu* menu, wxWindow* parent); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void append_menu_items_osx(wxMenu* menu); wxMenuItem* append_menu_item_fix_through_netfabb(wxMenu* menu); void append_menu_item_export_stl(wxMenu* menu) const ; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 50c6f5b67..f6289efbc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3490,10 +3490,8 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ sidebar->obj_list()->append_menu_item_instance_to_object(menu, q); menu->AppendSeparator(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxMenuItem* menu_item_printable = sidebar->obj_list()->append_menu_item_printable(menu, q); menu->AppendSeparator(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ append_menu_item(menu, wxID_ANY, _(L("Reload from Disk")), _(L("Reload the selected file from Disk")), [this](wxCommandEvent&) { reload_from_disk(); }); @@ -3503,7 +3501,6 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ menu->AppendSeparator(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { const Selection& selection = get_selection(); int instance_idx = selection.get_instance_idx(); @@ -3514,7 +3511,6 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ view3D->set_as_dirty(); } }, menu_item_printable->GetId()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 4db126b80..4e7b4e4ad 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1459,7 +1459,6 @@ std::vector Selection::get_unselected_volume_idxs_from(const std:: return idxs; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::toggle_instance_printable_state() { int instance_idx = get_instance_idx(); @@ -1483,7 +1482,6 @@ void Selection::toggle_instance_printable_state() } } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::update_valid() { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 94fa56909..c27b4cc29 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -336,9 +336,7 @@ public: // returns the list of idxs of the volumes contained in the given list but not in the selection std::vector get_unselected_volume_idxs_from(const std::vector& volume_idxs) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void toggle_instance_printable_state(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: void update_valid(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index e707a7476..3886a35aa 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -157,7 +157,6 @@ wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, return item; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler) { @@ -175,7 +174,6 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, return item; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 56349f9e2..785634b30 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -43,10 +43,8 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class wxDialog; void edit_tooltip(wxString& tooltip); From 59db1f7f3678a58314f515d2729bcbb4fef03a92 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 1 Aug 2019 14:58:04 +0200 Subject: [PATCH 05/20] Code refactoring to add PrintableItem column to ObjectList --- resources/icons/eye_closed.svg | 13 ++++ resources/icons/eye_open.svg | 11 ++++ src/slic3r/GUI/GUI_ObjectList.cpp | 73 +++++++++++--------- src/slic3r/GUI/wxExtensions.cpp | 106 ++++++++++++++++++------------ src/slic3r/GUI/wxExtensions.hpp | 43 +++++++----- 5 files changed, 159 insertions(+), 87 deletions(-) create mode 100644 resources/icons/eye_closed.svg create mode 100644 resources/icons/eye_open.svg diff --git a/resources/icons/eye_closed.svg b/resources/icons/eye_closed.svg new file mode 100644 index 000000000..127d53ca3 --- /dev/null +++ b/resources/icons/eye_closed.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/resources/icons/eye_open.svg b/resources/icons/eye_open.svg new file mode 100644 index 000000000..a87cf3a83 --- /dev/null +++ b/resources/icons/eye_open.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index bb824ab00..bbb7d7115 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -212,16 +212,20 @@ void ObjectList::create_objects_ctrl() EnableDropTarget(wxDF_UNICODETEXT); #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - // column 0(Icon+Text) of the view control: + // column ItemName(Icon+Text) of the view control: // And Icon can be consisting of several bitmaps AppendColumn(new wxDataViewColumn(_(L("Name")), new BitmapTextRenderer(), - 0, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); + colName, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); - // column 1 of the view control: + // column PrintableProperty (Icon) of the view control: + AppendBitmapColumn(" ", colPrint, wxDATAVIEW_CELL_INERT, int(2 * wxGetApp().em_unit()), + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + + // column Extruder of the view control: AppendColumn(create_objects_list_extruder_column(4)); - // column 2 of the view control: - AppendBitmapColumn(" ", 2, wxDATAVIEW_CELL_INERT, int(2.5 * wxGetApp().em_unit())/*25*/, + // column ItemEditing of the view control: + AppendBitmapColumn("Editing", colEditing, wxDATAVIEW_CELL_INERT, int(2.5 * wxGetApp().em_unit())/*25*/, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); } @@ -321,7 +325,7 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt) return; } - if (col->GetTitle() == " " && GetSelectedItemsCount()<2) + if (col->GetTitle() == _(L("Editing")) && GetSelectedItemsCount()<2) GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings"))); else if (col->GetTitle() == _("Name")) { @@ -377,7 +381,7 @@ wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_ choices.Add(wxString::Format("%d", i)); wxDataViewChoiceRenderer *c = new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL); - wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, 1, + wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, colExtruder, 8*wxGetApp().em_unit()/*80*/, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); return column; } @@ -397,7 +401,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder) else extruder = wxString::Format("%d", object->config.option("extruder")->value); - m_objects_model->SetValue(extruder, item, 1); + m_objects_model->SetValue(extruder, item, colExtruder); if (object->volumes.size() > 1) { for (auto id = 0; id < object->volumes.size(); id++) { @@ -409,7 +413,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder) else extruder = wxString::Format("%d", object->volumes[id]->config.option("extruder")->value); - m_objects_model->SetValue(extruder, item, 1); + m_objects_model->SetValue(extruder, item, colExtruder); } } } @@ -421,7 +425,7 @@ void ObjectList::update_objects_list_extruder_column(int extruders_count) if (printer_technology() == ptSLA) extruders_count = 1; - wxDataViewChoiceRenderer* ch_render = dynamic_cast(GetColumn(1)->GetRenderer()); + wxDataViewChoiceRenderer* ch_render = dynamic_cast(GetColumn(colExtruder)->GetRenderer()); if (ch_render->GetChoices().GetCount() - 1 == extruders_count) return; @@ -430,21 +434,21 @@ void ObjectList::update_objects_list_extruder_column(int extruders_count) if (m_objects && extruders_count > 1) update_extruder_values_for_items(extruders_count); - // delete old 2nd column - DeleteColumn(GetColumn(1)); - // insert new created 3rd column - InsertColumn(1, create_objects_list_extruder_column(extruders_count)); + // delete old extruder column + DeleteColumn(GetColumn(colExtruder)); + // insert new created extruder column + InsertColumn(colExtruder, create_objects_list_extruder_column(extruders_count)); // set show/hide for this column set_extruder_column_hidden(extruders_count <= 1); //a workaround for a wrong last column width updating under OSX - GetColumn(2)->SetWidth(25); + GetColumn(colEditing)->SetWidth(25); m_prevent_update_extruder_in_config = false; } void ObjectList::set_extruder_column_hidden(const bool hide) const { - GetColumn(1)->SetHidden(hide); + GetColumn(colExtruder)->SetHidden(hide); } void ObjectList::update_extruder_in_config(const wxDataViewItem& item) @@ -471,7 +475,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item) } wxVariant variant; - m_objects_model->GetValue(variant, item, 1); + m_objects_model->GetValue(variant, item, colExtruder); const wxString selection = variant.GetString(); if (!m_config || selection.empty()) @@ -748,7 +752,9 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) #endif // __WXOSX__ const wxString title = col->GetTitle(); - if (title == " ") + if (title == " "); + // show_context_menu(); + else if (title == _("Editing")) show_context_menu(); else if (title == _("Name")) { @@ -2260,7 +2266,13 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) // add instances to the object, if it has those if (model_object->instances.size()>1) - increase_object_instances(obj_idx, model_object->instances.size()); + { + std::vector print_idicator(model_object->instances.size()); + for (int i = 0; i < model_object->instances.size(); ++i) + print_idicator[i] = model_object->instances[i]->is_printable(); + + select_item(m_objects_model->AddInstanceChild(m_objects_model->GetItemById(obj_idx), print_idicator)); + } // add settings to the object, if it has those add_settings_item(item, &model_object->config); @@ -2342,7 +2354,7 @@ void ObjectList::delete_from_model_and_list(const std::vector& it (*m_objects)[item->obj_idx]->config.has("extruder")) { const wxString extruder = wxString::Format("%d", (*m_objects)[item->obj_idx]->config.option("extruder")->value); - m_objects_model->SetValue(extruder, m_objects_model->GetItemById(item->obj_idx), 1); + m_objects_model->SetValue(extruder, m_objects_model->GetItemById(item->obj_idx), colExtruder); } wxGetApp().plater()->canvas3D()->ensure_on_bed(item->obj_idx); } @@ -3415,7 +3427,7 @@ void ObjectList::rename_item() // The icon can't be edited so get its old value and reuse it. wxVariant valueOld; - m_objects_model->GetValue(valueOld, item, 0); + m_objects_model->GetValue(valueOld, item, colName); DataViewBitmapText bmpText; bmpText << valueOld; @@ -3425,7 +3437,7 @@ void ObjectList::rename_item() wxVariant value; value << bmpText; - m_objects_model->SetValue(value, item, 0); + m_objects_model->SetValue(value, item, colName); m_objects_model->ItemChanged(item); update_name_in_model(item); @@ -3466,9 +3478,10 @@ void ObjectList::msw_rescale() // update min size !!! A width of control shouldn't be a wxDefaultCoord SetMinSize(wxSize(1, 15 * em)); - GetColumn(0)->SetWidth(19 * em); - GetColumn(1)->SetWidth( 8 * em); - GetColumn(2)->SetWidth( 2 * em); + GetColumn(colName)->SetWidth(19 * em); + GetColumn(colPrint)->SetWidth( 2 * em); + GetColumn(colExtruder)->SetWidth( 8 * em); + GetColumn(colEditing)->SetWidth( 2 * em); // rescale all icons, used by ObjectList msw_rescale_icons(); @@ -3489,18 +3502,18 @@ void ObjectList::msw_rescale() void ObjectList::ItemValueChanged(wxDataViewEvent &event) { - if (event.GetColumn() == 0) + if (event.GetColumn() == colName) update_name_in_model(event.GetItem()); - else if (event.GetColumn() == 1) + else if (event.GetColumn() == colExtruder) update_extruder_in_config(event.GetItem()); } void ObjectList::OnEditingDone(wxDataViewEvent &event) { - if (event.GetColumn() != 0) + if (event.GetColumn() != colName) return; - const auto renderer = dynamic_cast(GetColumn(0)->GetRenderer()); + const auto renderer = dynamic_cast(GetColumn(colName)->GetRenderer()); if (renderer->WasCanceled()) wxTheApp->CallAfter([this]{ @@ -3582,7 +3595,7 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const /* We can change extruder for Object/Volume only. * So, if Instance is selected, get its Object item and change it */ - m_objects_model->SetValue(extruder_str, type & itInstance ? m_objects_model->GetTopParent(item) : item, 1); + m_objects_model->SetValue(extruder_str, type & itInstance ? m_objects_model->GetTopParent(item) : item, colExtruder); const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) : m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 3886a35aa..5bb85e86d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -450,6 +450,16 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, // ObjectDataViewModelNode // ---------------------------------------------------------------------------- +void ObjectDataViewModelNode::init_container() +{ +#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__ +} + ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type) : m_parent(parent), m_type(type), @@ -472,13 +482,8 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_name = _(L("Layers")); } -#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)) - m_container = true; -#endif //__WXGTK__ + init_container(); } ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, @@ -504,14 +509,8 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_name = _(L("Range")) + label_range + "(" + _(L("mm")) + ")"; m_bmp = create_scaled_bitmap(nullptr, "edit_layers_some"); // 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(); + init_container(); } void ObjectDataViewModelNode::set_action_icon() @@ -521,6 +520,13 @@ void ObjectDataViewModelNode::set_action_icon() m_action_icon = create_scaled_bitmap(nullptr, m_action_icon_name); // FIXME: pass window ptr } +void ObjectDataViewModelNode::set_printable_icon(PrintIndicator printable) +{ + m_printable = printable; + m_printable_icon = m_printable == piUndef ? m_empty_bmp : + create_scaled_bitmap(nullptr, m_printable == piPrintable ? "eye_open.png" : "eye_closed.png"); +} + Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; void ObjectDataViewModelNode::update_settings_digest_bitmaps() { @@ -574,17 +580,20 @@ bool ObjectDataViewModelNode::SetValue(const wxVariant& variant, unsigned col) { switch (col) { - case 0: { + case colPrint: + m_printable_icon << variant; + return true; + case colName: { DataViewBitmapText data; data << variant; m_bmp = data.GetBitmap(); m_name = data.GetText(); return true; } - case 1: { + case colExtruder: { const wxString & val = variant.GetString(); m_extruder = val == "0" ? _(L("default")) : val; return true; } - case 2: + case colEditing: m_action_icon << variant; return true; default: @@ -744,26 +753,49 @@ static bool append_root_node(ObjectDataViewModelNode *parent_node, return false; } -wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) +wxDataViewItem ObjectDataViewModel::AddRoot(const wxDataViewItem &parent_item, ItemType root_type) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); // get InstanceRoot node - ObjectDataViewModelNode *inst_root_node { nullptr }; + ObjectDataViewModelNode *root_node { nullptr }; + const bool appended = append_root_node(parent_node, &root_node, root_type); + if (!root_node) return wxDataViewItem(0); - 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); + const wxDataViewItem root_item((void*)root_node); if (appended) - ItemAdded(parent_item, inst_root_item);// notify control + ItemAdded(parent_item, root_item);// notify control + return root_item; +} + +wxDataViewItem ObjectDataViewModel::AddInstanceRoot(const wxDataViewItem &parent_item) +{ + return AddRoot(parent_item, itInstanceRoot); +} + +wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) +{ + const std::vector print_indicator(num, true); + + return wxDataViewItem((void*)AddInstanceChild(parent_item, print_indicator)); +} + +wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& parent_item, + const std::vector& print_indicator) +{ + const wxDataViewItem inst_root_item = AddInstanceRoot(parent_item); + if (!inst_root_item) return wxDataViewItem(0); + + ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); // Add instance nodes ObjectDataViewModelNode *instance_node = nullptr; size_t counter = 0; - while (counter < num) { + while (counter < print_indicator.size()) { instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); + instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); inst_root_node->Append(instance_node); // notify control const wxDataViewItem instance_item((void*)instance_node); @@ -776,20 +808,7 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &paren 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 layer_root_item; + return AddRoot(parent_item, itLayerRoot); } wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, @@ -1356,13 +1375,16 @@ void ObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &ite ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); switch (col) { - case 0: + case colPrint: + variant << node->m_printable_icon; + break; + case colName: variant << DataViewBitmapText(node->m_name, node->m_bmp); break; - case 1: + case colExtruder: variant = node->m_extruder; break; - case 2: + case colEditing: variant << node->m_action_icon; break; default: @@ -1425,7 +1447,7 @@ bool ObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); // disable extruder selection for the non "itObject|itVolume" item - return !(col == 1 && node->m_extruder.IsEmpty()); + return !(col == colExtruder && node->m_extruder.IsEmpty()); } wxDataViewItem ObjectDataViewModel::GetParent(const wxDataViewItem &item) const @@ -1773,7 +1795,7 @@ bool BitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value // The icon can't be edited so get its old value and reuse it. wxVariant valueOld; - GetView()->GetModel()->GetValue(valueOld, m_item, 0); + GetView()->GetModel()->GetValue(valueOld, m_item, colName); DataViewBitmapText bmpText; bmpText << valueOld; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 785634b30..679d9346d 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -175,6 +175,21 @@ enum ItemType { itLayer = 64, }; +enum ColumnNumber +{ + colName = 0, // item name + colPrint , // printable property + colExtruder , // extruder selection + colEditing , // item editing +}; + +enum PrintIndicator +{ + piUndef = 0, // no print indicator + piPrintable , // printable + piUnprintable , // unprintable +}; + class ObjectDataViewModelNode; WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); @@ -194,6 +209,8 @@ class ObjectDataViewModelNode bool m_container = false; wxString m_extruder = "default"; wxBitmap m_action_icon; + PrintIndicator m_printable {piUndef}; + wxBitmap m_printable_icon; std::string m_action_icon_name = ""; Slic3r::ModelVolumeType m_volume_type; @@ -206,14 +223,8 @@ public: m_type(itObject), m_extruder(extruder) { -#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(); + init_container(); } ObjectDataViewModelNode(ObjectDataViewModelNode* parent, @@ -227,15 +238,9 @@ public: m_idx (idx), m_extruder (extruder) { - m_bmp = bmp; -#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__ - + m_bmp = bmp; set_action_icon(); + init_container(); } ObjectDataViewModelNode(ObjectDataViewModelNode* parent, @@ -256,6 +261,7 @@ public: } } + void init_container(); bool IsContainer() const { return m_container; @@ -344,6 +350,8 @@ public: // Set action icons for node void set_action_icon(); + // Set printable icon for node + void set_printable_icon(PrintIndicator printable); void update_settings_digest_bitmaps(); bool update_settings_digest(const std::vector& categories); @@ -383,6 +391,7 @@ public: const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); + wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, const std::vector& print_indicator); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, const t_layer_height_range& layer_range, @@ -472,6 +481,10 @@ public: const bool is_marked = false); void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false); t_layer_height_range GetLayerRangeByItem(const wxDataViewItem& item) const; + +private: + wxDataViewItem AddRoot(const wxDataViewItem& parent_item, const ItemType root_type); + wxDataViewItem AddInstanceRoot(const wxDataViewItem& parent_item); }; // ---------------------------------------------------------------------------- From f712e5fcf4cb44d61fd9f095058b2609e9f169be Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 5 Aug 2019 08:44:55 +0200 Subject: [PATCH 06/20] Implemented set printable state for ObjectList --- src/slic3r/GUI/GUI_ObjectList.cpp | 21 ++++++++++++++ src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/Selection.cpp | 2 ++ src/slic3r/GUI/wxExtensions.cpp | 46 ++++++++++++++++++++++++++++++- src/slic3r/GUI/wxExtensions.hpp | 5 ++++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 9602bf4f7..c0af7a41e 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2273,6 +2273,8 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) select_item(m_objects_model->AddInstanceChild(m_objects_model->GetItemById(obj_idx), print_idicator)); } + else + m_objects_model->SetPrintableState(obj_idx, model_object->instances[0]->is_printable() ? piPrintable : piUnprintable); // add settings to the object, if it has those add_settings_item(item, &model_object->config); @@ -3632,6 +3634,25 @@ void ObjectList::update_after_undo_redo() m_prevent_canvas_selection_update = false; } +void ObjectList::update_printable_state(int obj_idx, int instance_idx) +{ + ModelObject* object = (*m_objects)[obj_idx]; + PrintIndicator printable = piUndef; + + if (object->instances.size() == 1) + { + printable = object->instances[0]->printable ? piPrintable : piUnprintable; + instance_idx = -1; + } + else + { + m_objects_model->SetPrintableState(obj_idx, piUndef); + printable = object->instances[instance_idx]->printable ? piPrintable : piUnprintable; + } + + select_item(m_objects_model->SetPrintableState(obj_idx, printable, instance_idx)); +} + ModelObject* ObjectList::object(const int obj_idx) const { if (obj_idx < 0) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index cbffaaa0c..1cfca1a42 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -349,6 +349,7 @@ public: void msw_rescale(); void update_after_undo_redo(); + void update_printable_state(int obj_idx, int instance_idx); private: #ifdef __WXOSX__ diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 4e7b4e4ad..630ecd1d4 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1479,6 +1479,8 @@ void Selection::toggle_instance_printable_state() if ((volume->object_idx() == obj_idx) && (volume->instance_idx() == instance_idx)) volume->printable = instance->printable; } + + wxGetApp().obj_list()->update_printable_state(obj_idx, instance_idx); } } } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index f6dc9082e..7ddf1c273 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -799,12 +799,28 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); + const bool just_created = inst_root_node->GetChildren().Count() == 0; + // Add instance nodes ObjectDataViewModelNode *instance_node = nullptr; size_t counter = 0; while (counter < print_indicator.size()) { instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); - instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); + + // if InstanceRoot item is just created and start to adding Instances + if (just_created && counter == 0) + { + ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); + + // use object's printable state to first instance + instance_node->set_printable_icon(obj_node->IsPrintable()); + + // and set printable state for object_node to piUndef + obj_node->set_printable_icon(piUndef); + ItemChanged(parent_item); + } + else + instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); inst_root_node->Append(instance_node); // notify control const wxDataViewItem instance_item((void*)instance_node); @@ -915,11 +931,13 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) ItemDeleted(parent, item); ObjectDataViewModelNode *last_instance_node = node_parent->GetNthChild(0); + PrintIndicator last_instance_printable = last_instance_node->IsPrintable(); node_parent->GetChildren().Remove(last_instance_node); delete last_instance_node; ItemDeleted(parent, wxDataViewItem(last_instance_node)); ObjectDataViewModelNode *obj_node = node_parent->GetParent(); + obj_node->set_printable_icon(last_instance_printable); obj_node->GetChildren().Remove(node_parent); delete node_parent; ret_item = wxDataViewItem(obj_node); @@ -1041,9 +1059,12 @@ wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &par const int inst_cnt = inst_root_node->GetChildCount(); const bool delete_inst_root_item = inst_cnt - num < 2 ? true : false; + PrintIndicator last_inst_printable = piUndef; + int stop = delete_inst_root_item ? 0 : inst_cnt - num; for (int i = inst_cnt - 1; i >= stop;--i) { ObjectDataViewModelNode *last_instance_node = inst_root_node->GetNthChild(i); + if (i==0) last_inst_printable = last_instance_node->IsPrintable(); inst_root_node->GetChildren().Remove(last_instance_node); delete last_instance_node; ItemDeleted(inst_root_item, wxDataViewItem(last_instance_node)); @@ -1052,7 +1073,9 @@ wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &par if (delete_inst_root_item) { ret_item = parent_item; parent_node->GetChildren().Remove(inst_root_node); + parent_node->set_printable_icon(last_inst_printable); ItemDeleted(parent_item, inst_root_item); + ItemChanged(parent_item); #ifndef __WXGTK__ if (parent_node->GetChildCount() == 0) parent_node->m_container = false; @@ -1621,6 +1644,27 @@ void ObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const Slic3r ItemChanged(item); } +wxDataViewItem ObjectDataViewModel::SetPrintableState( + int obj_idx, + PrintIndicator printable/* = piUndef*/, + int subobj_idx /* = -1*/, + ItemType subobj_type/* = itInstance*/) +{ + wxDataViewItem item = wxDataViewItem(0); + if (subobj_idx < 0) + item = GetItemById(obj_idx); + else + item = subobj_type&itInstance ? GetItemByInstanceId(obj_idx, subobj_idx) : + GetItemByVolumeId(obj_idx, subobj_idx); + + ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); + if (!node) + return wxDataViewItem(0); + node->set_printable_icon(printable); + + return item; +} + void ObjectDataViewModel::Rescale() { wxDataViewItemArray all_items; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index c0df69c5c..b04c6c9c0 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -324,6 +324,7 @@ public: void SetIdx(const int& idx); int GetIdx() const { return m_idx; } t_layer_height_range GetLayerRange() const { return m_layer_range; } + PrintIndicator IsPrintable() const { return m_printable; } // use this function only for childrens void AssignAllVal(ObjectDataViewModelNode& from_node) @@ -482,6 +483,10 @@ public: void SetVolumeBitmaps(const std::vector& volume_bmps) { m_volume_bmps = volume_bmps; } void SetWarningBitmap(wxBitmap* bitmap) { m_warning_bmp = bitmap; } void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); + wxDataViewItem SetPrintableState( int obj_idx, + PrintIndicator printable = piUndef, + int subobj_idx = -1, + ItemType subobj_type = itInstance); void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } // Rescale bitmaps for existing Items From e8f27c6407c4339ea73d5561095cfc338bb3e207 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 5 Aug 2019 10:05:28 +0200 Subject: [PATCH 07/20] Added call a toggle printable property for instance from ObjectList --- src/slic3r/GUI/GUI_ObjectList.cpp | 22 +++++++++++++++++----- src/slic3r/GUI/GUI_ObjectList.hpp | 2 ++ src/slic3r/GUI/wxExtensions.cpp | 3 ++- src/slic3r/GUI/wxExtensions.hpp | 3 +-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c714b6797..6ab87bd66 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -752,8 +752,8 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) #endif // __WXOSX__ const wxString title = col->GetTitle(); - if (title == " "); - // show_context_menu(); + if (title == " ") + toggle_printable_state(item); else if (title == _("Editing")) show_context_menu(); else if (title == _("Name")) @@ -2276,7 +2276,7 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) select_item(m_objects_model->AddInstanceChild(m_objects_model->GetItemById(obj_idx), print_idicator)); } else - m_objects_model->SetPrintableState(obj_idx, model_object->instances[0]->is_printable() ? piPrintable : piUnprintable); + m_objects_model->SetPrintableState(model_object->instances[0]->is_printable() ? piPrintable : piUnprintable, obj_idx); // add settings to the object, if it has those add_settings_item(item, &model_object->config); @@ -3623,11 +3623,23 @@ void ObjectList::update_printable_state(int obj_idx, int instance_idx) } else { - m_objects_model->SetPrintableState(obj_idx, piUndef); + m_objects_model->SetPrintableState(piUndef, obj_idx); printable = object->instances[instance_idx]->printable ? piPrintable : piUnprintable; } - select_item(m_objects_model->SetPrintableState(obj_idx, printable, instance_idx)); + m_objects_model->SetPrintableState(printable, obj_idx, instance_idx); +} + +void ObjectList::toggle_printable_state(wxDataViewItem item) +{ + const ItemType type = m_objects_model->GetItemType(item); + if (!(type&(itObject|itInstance/*|itVolume*/))) + return; + + wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); + + // update scene + wxGetApp().plater()->update(); } ModelObject* ObjectList::object(const int obj_idx) const diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 1cfca1a42..bdec06081 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -349,7 +349,9 @@ public: void msw_rescale(); void update_after_undo_redo(); + //update printable state for item from objects model void update_printable_state(int obj_idx, int instance_idx); + void toggle_printable_state(wxDataViewItem item); private: #ifdef __WXOSX__ diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 3da6997a7..524861133 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1657,8 +1657,8 @@ void ObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const Slic3r } wxDataViewItem ObjectDataViewModel::SetPrintableState( + PrintIndicator printable, int obj_idx, - PrintIndicator printable/* = piUndef*/, int subobj_idx /* = -1*/, ItemType subobj_type/* = itInstance*/) { @@ -1673,6 +1673,7 @@ wxDataViewItem ObjectDataViewModel::SetPrintableState( if (!node) return wxDataViewItem(0); node->set_printable_icon(printable); + ItemChanged(item); return item; } diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 5b9bdee02..242a487d1 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -485,8 +485,7 @@ public: void SetVolumeBitmaps(const std::vector& volume_bmps) { m_volume_bmps = volume_bmps; } void SetWarningBitmap(wxBitmap* bitmap) { m_warning_bmp = bitmap; } void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); - wxDataViewItem SetPrintableState( int obj_idx, - PrintIndicator printable = piUndef, + wxDataViewItem SetPrintableState( PrintIndicator printable, int obj_idx, int subobj_idx = -1, ItemType subobj_type = itInstance); From 9b5a577c073e1d5ee48741b9441af0016695d2ed Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 5 Aug 2019 11:02:56 +0200 Subject: [PATCH 08/20] Fixed OnContextMenu() under OSX --- src/slic3r/GUI/GUI_ObjectList.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 6ab87bd66..9de9323f1 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -738,18 +738,16 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) wxDataViewColumn* col; const wxPoint pt = get_mouse_position_in_control(); HitTest(pt, item, col); - if (!item) #ifdef __WXOSX__ // temporary workaround for OSX - // after Yosemite OS X version, HitTest return undefined item - item = GetSelection(); - if (item) - show_context_menu(); - else - printf("undefined item\n"); - return; -#else - return; + // after Yosemite OS X version, HitTest return undefined item + if (!item) item = GetSelection(); #endif // __WXOSX__ + + if (!item) { + printf("undefined item\n"); + return; + } + const wxString title = col->GetTitle(); if (title == " ") From 4152a5df43298629ba2856f1813ab235191a88df Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 5 Aug 2019 14:57:30 +0200 Subject: [PATCH 09/20] Implemented update on canvas of a printable state for new volumes added from ObjectList --- src/slic3r/GUI/GLCanvas3D.cpp | 17 +++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GUI_ObjectList.cpp | 20 +++++++++++++++++--- src/slic3r/GUI/wxExtensions.cpp | 5 +++-- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c74207123..36d9fffec 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1320,6 +1320,23 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject _set_warning_texture(WarningTexture::SomethingNotShown, false); } +void GLCanvas3D::update_instance_printable_state_for_objects(std::vector& object_idxs) +{ + for (size_t obj_idx : object_idxs) + { + ModelObject* model_object = m_model->objects[obj_idx]; + for (int inst_idx = 0; inst_idx < model_object->instances.size(); inst_idx++) + { + ModelInstance* instance = model_object->instances[inst_idx]; + + for (GLVolume* volume : m_volumes.volumes) + { + if ((volume->object_idx() == obj_idx) && (volume->instance_idx() == inst_idx)) + volume->printable = instance->printable; + } + } + } +} void GLCanvas3D::set_config(const DynamicPrintConfig* config) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index bd33dbef7..1738d7742 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -482,6 +482,7 @@ public: void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); + void update_instance_printable_state_for_objects(std::vector& object_idxs); void set_config(const DynamicPrintConfig* config); void set_process(BackgroundSlicingProcess* process); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 9de9323f1..882ac873c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2271,7 +2271,9 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) for (int i = 0; i < model_object->instances.size(); ++i) print_idicator[i] = model_object->instances[i]->is_printable(); - select_item(m_objects_model->AddInstanceChild(m_objects_model->GetItemById(obj_idx), print_idicator)); + const wxDataViewItem object_item = m_objects_model->GetItemById(obj_idx); + m_objects_model->AddInstanceChild(object_item, print_idicator); + Expand(m_objects_model->GetInstanceRootItem(object_item)); } else m_objects_model->SetPrintableState(model_object->instances[0]->is_printable() ? piPrintable : piUnprintable, obj_idx); @@ -3317,7 +3319,8 @@ void ObjectList::instances_to_separated_object(const int obj_idx, const std::set } // Add new object to the object_list - add_object_to_list(m_objects->size() - 1); + const size_t new_obj_indx = static_cast(m_objects->size() - 1); + add_object_to_list(new_obj_indx); for (std::set::const_reverse_iterator it = inst_idxs.rbegin(); it != inst_idxs.rend(); ++it) { @@ -3325,12 +3328,18 @@ void ObjectList::instances_to_separated_object(const int obj_idx, const std::set del_subobject_from_object(obj_idx, *it, itInstance); delete_instance_from_list(obj_idx, *it); } + + std::vector object_idxs = { new_obj_indx }; + // update printable state for new volumes on canvas3D + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(object_idxs); } void ObjectList::instances_to_separated_objects(const int obj_idx) { const int inst_cnt = (*m_objects)[obj_idx]->instances.size(); + std::vector object_idxs; + for (int i = inst_cnt-1; i > 0 ; i--) { // create new object from initial @@ -3344,12 +3353,17 @@ void ObjectList::instances_to_separated_objects(const int obj_idx) } // Add new object to the object_list - add_object_to_list(m_objects->size() - 1); + const size_t new_obj_indx = static_cast(m_objects->size() - 1); + add_object_to_list(new_obj_indx); + object_idxs.push_back(new_obj_indx); // delete current instance from the initial object del_subobject_from_object(obj_idx, i, itInstance); delete_instance_from_list(obj_idx, i); } + + // update printable state for new volumes on canvas3D + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(object_idxs); } void ObjectList::split_instances() diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 524861133..5928a4c5d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -812,8 +812,9 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren { ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); - // use object's printable state to first instance - instance_node->set_printable_icon(obj_node->IsPrintable()); + // use object's printable state to first instance, if it was defined + instance_node->set_printable_icon(obj_node->IsPrintable() != piUndef ? obj_node->IsPrintable() : + print_indicator[counter] ? piPrintable : piUnprintable ); // and set printable state for object_node to piUndef obj_node->set_printable_icon(piUndef); From 8a2362587d8301897afe991800398be196ab8da8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 6 Aug 2019 14:54:38 +0200 Subject: [PATCH 10/20] Save/load printable flag to/from 3mf and amf --- src/libslic3r/Format/3mf.cpp | 25 ++++++++++++++++++------- src/libslic3r/Format/AMF.cpp | 21 ++++++++++++++++++--- src/slic3r/GUI/Plater.cpp | 3 +++ 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 0cc0a9d58..fd1d11c2f 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -71,6 +71,7 @@ const char* V2_ATTR = "v2"; const char* V3_ATTR = "v3"; const char* OBJECTID_ATTR = "objectid"; const char* TRANSFORM_ATTR = "transform"; +const char* PRINTABLE_ATTR = "printable"; const char* KEY_ATTR = "key"; const char* VALUE_ATTR = "value"; @@ -131,6 +132,12 @@ int get_attribute_value_int(const char** attributes, unsigned int attributes_siz return (text != nullptr) ? ::atoi(text) : 0; } +bool get_attribute_value_bool(const char** attributes, unsigned int attributes_size, const char* attribute_key) +{ + const char* text = get_attribute_value_charptr(attributes, attributes_size, attribute_key); + return (text != nullptr) ? (bool)::atoi(text) : true; +} + Slic3r::Transform3d get_transform_from_string(const std::string& mat_str) { if (mat_str.empty()) @@ -428,7 +435,7 @@ namespace Slic3r { bool _handle_start_metadata(const char** attributes, unsigned int num_attributes); bool _handle_end_metadata(); - bool _create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter); + bool _create_object_instance(int object_id, const Transform3d& transform, const bool printable, unsigned int recur_counter); void _apply_transform(ModelInstance& instance, const Transform3d& transform); @@ -1367,8 +1374,9 @@ namespace Slic3r { int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR); Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR)); + int printable = get_attribute_value_bool(attributes, num_attributes, PRINTABLE_ATTR); - return _create_object_instance(object_id, transform, 1); + return _create_object_instance(object_id, transform, printable, 1); } bool _3MF_Importer::_handle_end_item() @@ -1396,7 +1404,7 @@ namespace Slic3r { return true; } - bool _3MF_Importer::_create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter) + bool _3MF_Importer::_create_object_instance(int object_id, const Transform3d& transform, const bool printable, unsigned int recur_counter) { static const unsigned int MAX_RECURSIONS = 10; @@ -1432,6 +1440,7 @@ namespace Slic3r { add_error("Unable to add object instance"); return false; } + instance->printable = printable; m_instances.emplace_back(instance, transform); } @@ -1441,7 +1450,7 @@ namespace Slic3r { // recursively process nested components for (const Component& component : it->second) { - if (!_create_object_instance(component.object_id, transform * component.transform, recur_counter + 1)) + if (!_create_object_instance(component.object_id, transform * component.transform, printable, recur_counter + 1)) return false; } } @@ -1655,10 +1664,12 @@ namespace Slic3r { { unsigned int id; Transform3d transform; + bool printable; - BuildItem(unsigned int id, const Transform3d& transform) + BuildItem(unsigned int id, const Transform3d& transform, const bool printable) : id(id) , transform(transform) + , printable(printable) { } }; @@ -1951,7 +1962,7 @@ namespace Slic3r { Transform3d t = instance->get_matrix(); // instance_id is just a 1 indexed index in build_items. assert(instance_id == build_items.size() + 1); - build_items.emplace_back(instance_id, t); + build_items.emplace_back(instance_id, t, instance->printable); stream << " \n"; @@ -2059,7 +2070,7 @@ namespace Slic3r { stream << " "; } } - stream << "\" />\n"; + stream << "\" printable =\"" << item.printable << "\" />\n"; } stream << " \n"; diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index 4370a2e1c..08820f2ea 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -137,6 +137,7 @@ struct AMFParserContext NODE_TYPE_MIRRORX, // amf/constellation/instance/mirrorx NODE_TYPE_MIRRORY, // amf/constellation/instance/mirrory NODE_TYPE_MIRRORZ, // amf/constellation/instance/mirrorz + NODE_TYPE_PRINTABLE, // amf/constellation/instance/mirrorz NODE_TYPE_METADATA, // anywhere under amf/*/metadata }; @@ -145,7 +146,8 @@ struct AMFParserContext : deltax_set(false), deltay_set(false), deltaz_set(false) , rx_set(false), ry_set(false), rz_set(false) , scalex_set(false), scaley_set(false), scalez_set(false) - , mirrorx_set(false), mirrory_set(false), mirrorz_set(false) {} + , mirrorx_set(false), mirrory_set(false), mirrorz_set(false) + , printable(true) {} // Shift in the X axis. float deltax; bool deltax_set; @@ -178,6 +180,8 @@ struct AMFParserContext bool mirrory_set; float mirrorz; bool mirrorz_set; + // printable property + bool printable; bool anything_set() const { return deltax_set || deltay_set || deltaz_set || rx_set || ry_set || rz_set || @@ -321,6 +325,8 @@ void AMFParserContext::startElement(const char *name, const char **atts) node_type_new = NODE_TYPE_MIRRORY; else if (strcmp(name, "mirrorz") == 0) node_type_new = NODE_TYPE_MIRRORZ; + else if (strcmp(name, "printable") == 0) + node_type_new = NODE_TYPE_PRINTABLE; } else if (m_path[2] == NODE_TYPE_LAYER_CONFIG && strcmp(name, "range") == 0) { assert(m_object); @@ -397,7 +403,8 @@ void AMFParserContext::characters(const XML_Char *s, int len) m_path.back() == NODE_TYPE_SCALE || m_path.back() == NODE_TYPE_MIRRORX || m_path.back() == NODE_TYPE_MIRRORY || - m_path.back() == NODE_TYPE_MIRRORZ) + m_path.back() == NODE_TYPE_MIRRORZ || + m_path.back() == NODE_TYPE_PRINTABLE) m_value[0].append(s, len); break; case 6: @@ -507,6 +514,11 @@ void AMFParserContext::endElement(const char * /* name */) m_instance->mirrorz_set = true; m_value[0].clear(); break; + case NODE_TYPE_PRINTABLE: + assert(m_instance); + m_instance->printable = bool(atoi(m_value[0].c_str())); + m_value[0].clear(); + break; // Object vertices: case NODE_TYPE_VERTEX: @@ -685,6 +697,7 @@ void AMFParserContext::endDocument() mi->set_rotation(Vec3d(instance.rx_set ? (double)instance.rx : 0.0, instance.ry_set ? (double)instance.ry : 0.0, instance.rz_set ? (double)instance.rz : 0.0)); mi->set_scaling_factor(Vec3d(instance.scalex_set ? (double)instance.scalex : 1.0, instance.scaley_set ? (double)instance.scaley : 1.0, instance.scalez_set ? (double)instance.scalez : 1.0)); mi->set_mirror(Vec3d(instance.mirrorx_set ? (double)instance.mirrorx : 1.0, instance.mirrory_set ? (double)instance.mirrory : 1.0, instance.mirrorz_set ? (double)instance.mirrorz : 1.0)); + mi->printable = instance.printable; } } } @@ -1037,6 +1050,7 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) " %lf\n" " %lf\n" " %lf\n" + " %d\n" " \n", object_id, instance->get_offset(X), @@ -1050,7 +1064,8 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) instance->get_scaling_factor(Z), instance->get_mirror(X), instance->get_mirror(Y), - instance->get_mirror(Z)); + instance->get_mirror(Z), + instance->printable); //FIXME missing instance->scaling_factor instances.append(buf); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9e0b61a9b..506f2b36b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2326,6 +2326,9 @@ std::vector Plater::priv::load_files(const std::vector& input_ // automatic selection of added objects if (!obj_idxs.empty() && (view3D != nullptr)) { + // update printable state for new volumes on canvas3D + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs); + Selection& selection = view3D->get_canvas3d()->get_selection(); selection.clear(); for (size_t idx : obj_idxs) From 2f642ffffb3601b870c2e53194866f035e174bc7 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 10:18:16 +0200 Subject: [PATCH 11/20] ModelInstance::is_printable() takes into account printability of the parent ModelObject. --- src/libslic3r/Model.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 10d6a6d46..2678ddfcc 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -643,7 +643,7 @@ public: const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } - bool is_printable() const { return printable && (print_volume_state == PVS_Inside); } + bool is_printable() const { return object->printable && printable && (print_volume_state == PVS_Inside); } // Getting the input polygon for arrange arrangement::ArrangePolygon get_arrange_polygon() const; From a58b1844e032fc58e13a115a3fabedfd0690a04f Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 11:14:04 +0200 Subject: [PATCH 12/20] WIP: Picking fix - disable alpha blending and render with false colors including the alpha channels, which have their 3 lowest bits set to zero. In case some blending occurs, the lowest 3 bits will likely be used to interpolate between the false colors, therefore the 3 lowest bits may be used to detect alpha blending or multi-sampling. --- src/slic3r/GUI/GLCanvas3D.cpp | 73 +++++++++++++++-------------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ffc33a93e..9937d8de8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3764,6 +3764,7 @@ void GLCanvas3D::_picking_pass() const // Better to use software ray - casting on a bounding - box hierarchy. if (m_multisample_allowed) + // This flag is often ignored by NVIDIA drivers if rendering into a screen buffer. glsafe(::glDisable(GL_MULTISAMPLE)); glsafe(::glDisable(GL_BLEND)); @@ -3793,7 +3794,9 @@ void GLCanvas3D::_picking_pass() const if (inside) { glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color)); - volume_id = color[0] + (color[1] << 8) + (color[2] << 16); + if (((color[0] | color[1] | color[2] | color[3]) & 0x7) == 0) + // Only non-interpolated colors are valid, those have their lowest three bits zeroed. + volume_id = (color[0] >> 3) + (color[1] << (5 - 3)) + (color[2] << (10 - 3)) + (color[3] << (15 - 3)); } if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) { @@ -3816,6 +3819,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const if (m_picking_enabled) { if (m_multisample_allowed) + // This flag is often ignored by NVIDIA drivers if rendering into a screen buffer. glsafe(::glDisable(GL_MULTISAMPLE)); glsafe(::glDisable(GL_BLEND)); @@ -3841,7 +3845,9 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const struct Pixel { std::array data; - int id() const { return data[0] + (data[1] << 8) + (data[2] << 16); } + // Only non-interpolated colors are valid, those have their lowest three bits zeroed. + bool valid() const { return ((data[0] | data[1] | data[2] | data[3]) & 0x7) == 0; } + int id() const { return (data[0] >> 3) + (data[1] << (5 - 3)) + (data[2] << (10 - 3)) + (data[3] << (15 - 3)); } }; std::vector frame(px_count); @@ -3851,17 +3857,15 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const tbb::parallel_for(tbb::blocked_range(0, frame.size(), (size_t)width), [this, &frame, &idxs, &mutex](const tbb::blocked_range& range) { for (size_t i = range.begin(); i < range.end(); ++i) - { - int volume_id = frame[i].id(); - if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) - { - mutex.lock(); - idxs.insert(volume_id); - mutex.unlock(); - } - } - } - ); + if (frame[i].valid()) { + int volume_id = frame[i].id(); + if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) { + mutex.lock(); + idxs.insert(volume_id); + mutex.unlock(); + } + } + }); #else std::vector frame(4 * px_count); glsafe(::glReadPixels(left, top, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)frame.data())); @@ -4040,42 +4044,27 @@ void GLCanvas3D::_render_volumes_for_picking() const // do not cull backfaces to show broken geometry, if any glsafe(::glDisable(GL_CULL_FACE)); - glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); const Transform3d& view_matrix = m_camera.get_view_matrix(); - GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Opaque, view_matrix); - for (const GLVolumeWithIdAndZ& volume : to_render) - { - // Object picking mode. Render the object with a color encoding the object index. - unsigned int r = (volume.second.first & 0x000000FF) >> 0; - unsigned int g = (volume.second.first & 0x0000FF00) >> 8; - unsigned int b = (volume.second.first & 0x00FF0000) >> 16; - glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255)); - - if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) - volume.first->render(); - } - - to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Transparent, view_matrix); - for (const GLVolumeWithIdAndZ& volume : to_render) - { - // Object picking mode. Render the object with a color encoding the object index. - unsigned int r = (volume.second.first & 0x000000FF) >> 0; - unsigned int g = (volume.second.first & 0x0000FF00) >> 8; - unsigned int b = (volume.second.first & 0x00FF0000) >> 16; - glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255)); - - if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) - volume.first->render(); - } + for (size_t type = 0; type < 2; ++ type) { + GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::Opaque : GLVolumeCollection::Transparent, view_matrix); + for (const GLVolumeWithIdAndZ& volume : to_render) + if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) { + // Object picking mode. Render the object with a color encoding the object index. + unsigned int id = volume.second.first; + unsigned int r = (id & (0x0000001F << 0)) << 3; + unsigned int g = (id & (0x0000001F << 5)) >> (5 - 3); + unsigned int b = (id & (0x0000001F << 10)) >> (10 - 3); + unsigned int a = (id & (0x0000001F << 15)) >> (15 - 3); + glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); + volume.first->render(); + } + } glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisable(GL_BLEND)); glsafe(::glEnable(GL_CULL_FACE)); } From 2ad3c05a655cd801dc88adf3af7a4429a47ee6b3 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 11:37:38 +0200 Subject: [PATCH 13/20] WIP: Improvement in the picking robustness: store a checksum into the alpha channel. --- src/slic3r/GUI/GLCanvas3D.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9937d8de8..4de20c491 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3753,6 +3753,19 @@ void GLCanvas3D::_refresh_if_shown_on_screen() } } +static inline unsigned char picking_checksum(unsigned char red, unsigned char green, unsigned char blue) +{ + // 8 bit hash for the color + unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff; + // Increase enthropy by a bit reversal + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + // Flip every second bit to increase the enthropy even more. + b ^= 0x55; + return b; +} + void GLCanvas3D::_picking_pass() const { if (m_picking_enabled && !m_mouse.dragging && (m_mouse.position != Vec2d(DBL_MAX, DBL_MAX))) @@ -3794,9 +3807,9 @@ void GLCanvas3D::_picking_pass() const if (inside) { glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color)); - if (((color[0] | color[1] | color[2] | color[3]) & 0x7) == 0) + if (picking_checksum(color[0], color[1], color[2]) == color[3]) // Only non-interpolated colors are valid, those have their lowest three bits zeroed. - volume_id = (color[0] >> 3) + (color[1] << (5 - 3)) + (color[2] << (10 - 3)) + (color[3] << (15 - 3)); + volume_id = color[0] + (color[1] << 8) + (color[2] << 16); } if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) { @@ -3846,8 +3859,8 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const { std::array data; // Only non-interpolated colors are valid, those have their lowest three bits zeroed. - bool valid() const { return ((data[0] | data[1] | data[2] | data[3]) & 0x7) == 0; } - int id() const { return (data[0] >> 3) + (data[1] << (5 - 3)) + (data[2] << (10 - 3)) + (data[3] << (15 - 3)); } + bool valid() const { return picking_checksum(data[0], data[1], data[2]) == data[3]; } + int id() const { return data[0] + (data[1] << 8) + (data[2] << 16); } }; std::vector frame(px_count); @@ -4054,10 +4067,10 @@ void GLCanvas3D::_render_volumes_for_picking() const if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) { // Object picking mode. Render the object with a color encoding the object index. unsigned int id = volume.second.first; - unsigned int r = (id & (0x0000001F << 0)) << 3; - unsigned int g = (id & (0x0000001F << 5)) >> (5 - 3); - unsigned int b = (id & (0x0000001F << 10)) >> (10 - 3); - unsigned int a = (id & (0x0000001F << 15)) >> (15 - 3); + unsigned int r = (id & (0x000000FF << 0)) << 0; + unsigned int g = (id & (0x000000FF << 8)) >> 8; + unsigned int b = (id & (0x000000FF << 16)) >> 16; + unsigned int a = picking_checksum(r, g, b); glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); volume.first->render(); } From abe16fa22e59090669e1e6ca4a8329f4ac49e682 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 7 Aug 2019 14:11:41 +0200 Subject: [PATCH 14/20] Added printable property for object with instances --- src/slic3r/GUI/GUI_ObjectList.cpp | 31 ++++++---- src/slic3r/GUI/wxExtensions.cpp | 95 ++++++++++++++++++++++++++----- src/slic3r/GUI/wxExtensions.hpp | 5 ++ 3 files changed, 106 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index daed3fb72..66387b9f0 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3645,18 +3645,10 @@ void ObjectList::update_after_undo_redo() void ObjectList::update_printable_state(int obj_idx, int instance_idx) { ModelObject* object = (*m_objects)[obj_idx]; - PrintIndicator printable = piUndef; + const PrintIndicator printable = object->instances[instance_idx]->printable ? piPrintable : piUnprintable; if (object->instances.size() == 1) - { - printable = object->instances[0]->printable ? piPrintable : piUnprintable; instance_idx = -1; - } - else - { - m_objects_model->SetPrintableState(piUndef, obj_idx); - printable = object->instances[instance_idx]->printable ? piPrintable : piUnprintable; - } m_objects_model->SetPrintableState(printable, obj_idx, instance_idx); } @@ -3667,7 +3659,26 @@ void ObjectList::toggle_printable_state(wxDataViewItem item) if (!(type&(itObject|itInstance/*|itVolume*/))) return; - wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); + if (type & itObject) + { + const int obj_idx = m_objects_model->GetObjectIdByItem(item); + ModelObject* object = (*m_objects)[obj_idx]; + + // get object's printable and change it + bool printable = !m_objects_model->IsPrintable(item); + // set printable value for all instances in object + for (auto inst : object->instances) + inst->printable = printable; + + // update printable state on canvas + std::vector obj_idxs = {(size_t)obj_idx}; + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs); + + // update printable state in ObjectList + m_objects_model->SetObjectPrintableState(printable ? piPrintable : piUnprintable , item); + } + else + wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); // update scene wxGetApp().plater()->update(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 5928a4c5d..dcc47750e 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -806,22 +806,8 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren size_t counter = 0; while (counter < print_indicator.size()) { instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); + instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); - // if InstanceRoot item is just created and start to adding Instances - if (just_created && counter == 0) - { - ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); - - // use object's printable state to first instance, if it was defined - instance_node->set_printable_icon(obj_node->IsPrintable() != piUndef ? obj_node->IsPrintable() : - print_indicator[counter] ? piPrintable : piUnprintable ); - - // and set printable state for object_node to piUndef - obj_node->set_printable_icon(piUndef); - ItemChanged(parent_item); - } - else - instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); inst_root_node->Append(instance_node); // notify control const wxDataViewItem instance_item((void*)instance_node); @@ -829,9 +815,64 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren ++counter; } + // update object_node printable property + UpdateObjectPrintable(parent_item); + return wxDataViewItem((void*)instance_node); } +void ObjectDataViewModel::UpdateObjectPrintable(wxDataViewItem parent_item) +{ + const wxDataViewItem inst_root_item = GetInstanceRootItem(parent_item); + if (!inst_root_item) + return; + + ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); + + const size_t child_cnt = inst_root_node->GetChildren().Count(); + PrintIndicator obj_pi = piUnprintable; + for (size_t i=0; i < child_cnt; i++) + if (inst_root_node->GetNthChild(i)->IsPrintable() & piPrintable) { + obj_pi = piPrintable; + break; + } + // and set printable state for object_node to piUndef + ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); + obj_node->set_printable_icon(obj_pi); + ItemChanged(parent_item); +} + +// update printable property for all instances from object +void ObjectDataViewModel::UpdateInstancesPrintable(wxDataViewItem parent_item) +{ + const wxDataViewItem inst_root_item = GetInstanceRootItem(parent_item); + if (!inst_root_item) + return; + + ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); + const PrintIndicator obj_pi = obj_node->IsPrintable(); + + ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); + const size_t child_cnt = inst_root_node->GetChildren().Count(); + + for (size_t i=0; i < child_cnt; i++) + { + ObjectDataViewModelNode* inst_node = inst_root_node->GetNthChild(i); + // and set printable state for object_node to piUndef + inst_node->set_printable_icon(obj_pi); + ItemChanged(wxDataViewItem((void*)inst_node)); + } +} + +bool ObjectDataViewModel::IsPrintable(const wxDataViewItem& item) const +{ + ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); + if (!node) + return false; + + return node->IsPrintable() == piPrintable; +} + wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_item) { return AddRoot(parent_item, itLayerRoot); @@ -951,6 +992,9 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) return ret_item; } + if (node->m_type & itInstance) + UpdateObjectPrintable(wxDataViewItem(node_parent->GetParent())); + // if there was last layer item, delete this one and layers root item if (node_parent->GetChildCount() == 0 && node_parent->m_type == itLayerRoot) { @@ -1083,6 +1127,9 @@ wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &par #endif //__WXGTK__ } + // update object_node printable property + UpdateObjectPrintable(parent_item); + return ret_item; } @@ -1676,9 +1723,27 @@ wxDataViewItem ObjectDataViewModel::SetPrintableState( node->set_printable_icon(printable); ItemChanged(item); + if (subobj_idx >= 0) + UpdateObjectPrintable(GetItemById(obj_idx)); + return item; } +wxDataViewItem ObjectDataViewModel::SetObjectPrintableState( + PrintIndicator printable, + wxDataViewItem obj_item) +{ + ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)obj_item.GetID(); + if (!node) + return wxDataViewItem(0); + node->set_printable_icon(printable); + ItemChanged(obj_item); + + UpdateInstancesPrintable(obj_item); + + return obj_item; +} + void ObjectDataViewModel::Rescale() { wxDataViewItemArray all_items; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 242a487d1..24a28ecff 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -482,12 +482,17 @@ public: void UpdateSettingsDigest( const wxDataViewItem &item, const std::vector& categories); + bool IsPrintable(const wxDataViewItem &item) const; + void UpdateObjectPrintable(wxDataViewItem parent_item); + void UpdateInstancesPrintable(wxDataViewItem parent_item); + void SetVolumeBitmaps(const std::vector& volume_bmps) { m_volume_bmps = volume_bmps; } void SetWarningBitmap(wxBitmap* bitmap) { m_warning_bmp = bitmap; } void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); wxDataViewItem SetPrintableState( PrintIndicator printable, int obj_idx, int subobj_idx = -1, ItemType subobj_type = itInstance); + wxDataViewItem SetObjectPrintableState(PrintIndicator printable, wxDataViewItem obj_item); void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } // Rescale bitmaps for existing Items From 2d7f478dac6206284da6aed9c75a111a0a1db2b7 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 14:15:38 +0200 Subject: [PATCH 15/20] Finished picking by color with a checksum in the alpha channel to guard against unwanted alpha blending and / or multi sampling. --- src/slic3r/GUI/GLCanvas3D.cpp | 19 ++------- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 45 ++++++++++++++------ src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 24 ++++++----- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 17 ++++---- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 14 +++--- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 30 ++++++------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 8 ++-- 10 files changed, 89 insertions(+), 74 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4de20c491..b91b8c36a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3753,19 +3753,6 @@ void GLCanvas3D::_refresh_if_shown_on_screen() } } -static inline unsigned char picking_checksum(unsigned char red, unsigned char green, unsigned char blue) -{ - // 8 bit hash for the color - unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff; - // Increase enthropy by a bit reversal - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - // Flip every second bit to increase the enthropy even more. - b ^= 0x55; - return b; -} - void GLCanvas3D::_picking_pass() const { if (m_picking_enabled && !m_mouse.dragging && (m_mouse.position != Vec2d(DBL_MAX, DBL_MAX))) @@ -3807,7 +3794,7 @@ void GLCanvas3D::_picking_pass() const if (inside) { glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color)); - if (picking_checksum(color[0], color[1], color[2]) == color[3]) + if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3]) // Only non-interpolated colors are valid, those have their lowest three bits zeroed. volume_id = color[0] + (color[1] << 8) + (color[2] << 16); } @@ -3859,7 +3846,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const { std::array data; // Only non-interpolated colors are valid, those have their lowest three bits zeroed. - bool valid() const { return picking_checksum(data[0], data[1], data[2]) == data[3]; } + bool valid() const { return picking_checksum_alpha_channel(data[0], data[1], data[2]) == data[3]; } int id() const { return data[0] + (data[1] << 8) + (data[2] << 16); } }; @@ -4070,7 +4057,7 @@ void GLCanvas3D::_render_volumes_for_picking() const unsigned int r = (id & (0x000000FF << 0)) << 0; unsigned int g = (id & (0x000000FF << 8)) >> 8; unsigned int b = (id & (0x000000FF << 16)) >> 16; - unsigned int a = picking_checksum(r, g, b); + unsigned int a = picking_checksum_alpha_channel(r, g, b); glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); volume.first->render(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index a65074646..29e5e5686 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -29,19 +29,21 @@ GLGizmoBase::Grabber::Grabber() color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f; + color[3] = 1.0f; } void GLGizmoBase::Grabber::render(bool hover, float size) const { - float render_color[3]; + float render_color[4]; if (hover) { render_color[0] = 1.0f - color[0]; render_color[1] = 1.0f - color[1]; render_color[2] = 1.0f - color[2]; + render_color[3] = color[3]; } else - ::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float)); + ::memcpy((void*)render_color, (const void*)color, 4 * sizeof(float)); render(size, render_color, true); } @@ -63,7 +65,7 @@ void GLGizmoBase::Grabber::render(float size, const float* render_color, bool us if (use_lighting) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor3fv(render_color)); + glsafe(::glColor4fv(render_color)); glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); @@ -144,9 +146,9 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u , m_dragging(false) , m_imgui(wxGetApp().imgui()) { - ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 3 * sizeof(float)); - ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 3 * sizeof(float)); - ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 3 * sizeof(float)); + ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float)); + ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float)); + ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float)); } void GLGizmoBase::set_hover_id(int id) @@ -161,7 +163,7 @@ void GLGizmoBase::set_hover_id(int id) void GLGizmoBase::set_highlight_color(const float* color) { if (color != nullptr) - ::memcpy((void*)m_highlight_color, (const void*)color, 3 * sizeof(float)); + ::memcpy((void*)m_highlight_color, (const void*)color, 4 * sizeof(float)); } void GLGizmoBase::enable_grabber(unsigned int id) @@ -210,7 +212,7 @@ void GLGizmoBase::update(const UpdateData& data) on_update(data); } -std::array GLGizmoBase::picking_color_component(unsigned int id) const +std::array GLGizmoBase::picking_color_component(unsigned int id) const { static const float INV_255 = 1.0f / 255.0f; @@ -220,9 +222,12 @@ std::array GLGizmoBase::picking_color_component(unsigned int id) const id -= m_group_id; // color components are encoded to match the calculation of volume_id made into GLCanvas3D::_picking_pass() - return std::array { (float)((id >> 0) & 0xff) * INV_255, // red - (float)((id >> 8) & 0xff) * INV_255, // green - (float)((id >> 16) & 0xff) * INV_255 }; // blue + return std::array { + float((id >> 0) & 0xff) * INV_255, // red + float((id >> 8) & 0xff) * INV_255, // green + float((id >> 16) & 0xff) * INV_255, // blue + float(picking_checksum_alpha_channel(id & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff))* INV_255 // checksum for validating against unwanted alpha blending and multi sampling + }; } void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const @@ -247,10 +252,11 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const { if (m_grabbers[i].enabled) { - std::array color = picking_color_component(i); + std::array color = picking_color_component(i); m_grabbers[i].color[0] = color[0]; m_grabbers[i].color[1] = color[1]; m_grabbers[i].color[2] = color[2]; + m_grabbers[i].color[3] = color[3]; m_grabbers[i].render_for_picking(mean_size); } } @@ -267,5 +273,20 @@ std::string GLGizmoBase::format(float value, unsigned int decimals) const return Slic3r::string_printf("%.*f", decimals, value); } +// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components +// were not interpolated by alpha blending or multi sampling. +unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue) +{ + // 8 bit hash for the color + unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff; + // Increase enthropy by a bit reversal + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + // Flip every second bit to increase the enthropy even more. + b ^= 0x55; + return b; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index b84442b94..7b73c62c2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -21,11 +21,11 @@ class ModelObject; namespace GUI { -static const float DEFAULT_BASE_COLOR[3] = { 0.625f, 0.625f, 0.625f }; -static const float DEFAULT_DRAG_COLOR[3] = { 1.0f, 1.0f, 1.0f }; -static const float DEFAULT_HIGHLIGHT_COLOR[3] = { 1.0f, 0.38f, 0.0f }; -static const float AXES_COLOR[3][3] = { { 0.75f, 0.0f, 0.0f }, { 0.0f, 0.75f, 0.0f }, { 0.0f, 0.0f, 0.75f } }; -static const float CONSTRAINED_COLOR[3] = { 0.5f, 0.5f, 0.5f }; +static const float DEFAULT_BASE_COLOR[4] = { 0.625f, 0.625f, 0.625f, 1.0f }; +static const float DEFAULT_DRAG_COLOR[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; +static const float DEFAULT_HIGHLIGHT_COLOR[4] = { 1.0f, 0.38f, 0.0f, 1.0f }; +static const float AXES_COLOR[][4] = { { 0.75f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.75f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.75f, 1.0f } }; +static const float CONSTRAINED_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; @@ -48,7 +48,7 @@ protected: Vec3d center; Vec3d angles; - float color[3]; + float color[4]; bool enabled; bool dragging; @@ -94,9 +94,9 @@ protected: unsigned int m_sprite_id; int m_hover_id; bool m_dragging; - float m_base_color[3]; - float m_drag_color[3]; - float m_highlight_color[3]; + float m_base_color[4]; + float m_drag_color[4]; + float m_highlight_color[4]; mutable std::vector m_grabbers; ImGuiWrapper* m_imgui; @@ -166,7 +166,7 @@ protected: // 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) - std::array picking_color_component(unsigned int id) const; + std::array picking_color_component(unsigned int id) const; void render_grabbers(const BoundingBoxf3& box) const; void render_grabbers(float size) const; void render_grabbers_for_picking(const BoundingBoxf3& box) const; @@ -175,6 +175,10 @@ protected: std::string format(float value, unsigned int decimals) const; }; +// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components +// were not interpolated by alpha blending or multi sampling. +extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue); + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 39399fc0d..481bec956 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -17,7 +17,7 @@ namespace GUI { const double GLGizmoCut::Offset = 10.0; const double GLGizmoCut::Margin = 20.0; -const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 }; +const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0, 1.0 }; GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 5bfeda526..6e5738a42 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -11,7 +11,7 @@ class GLGizmoCut : public GLGizmoBase { static const double Offset; static const double Margin; - static const std::array GrabberColor; + static const std::array GrabberColor; mutable double m_cut_z; double m_start_z; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 5a42cbd31..9fae8893a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -115,7 +115,7 @@ void GLGizmoFlatten::on_render_for_picking() const const_cast(this)->update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { - glsafe(::glColor3fv(picking_color_component(i).data())); + glsafe(::glColor4fv(picking_color_component(i).data())); ::glBegin(GL_POLYGON); for (const Vec3d& vertex : m_planes[i].vertices) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 11bdcd4f8..862ffe41a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -104,15 +104,15 @@ void GLGizmoMove3D::on_render() const // x axis m_grabbers[0].center = Vec3d(box.max(0) + Offset, center(1), center(2)); - ::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 4 * sizeof(float)); // y axis m_grabbers[1].center = Vec3d(center(0), box.max(1) + Offset, center(2)); - ::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[1], 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[1], 4 * sizeof(float)); // z axis m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset); - ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 4 * sizeof(float)); glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); @@ -123,7 +123,7 @@ void GLGizmoMove3D::on_render() const { if (m_grabbers[i].enabled) { - glsafe(::glColor3fv(AXES_COLOR[i])); + glsafe(::glColor4fv(AXES_COLOR[i])); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[i].center.data()); @@ -142,7 +142,7 @@ void GLGizmoMove3D::on_render() const else { // draw axis - glsafe(::glColor3fv(AXES_COLOR[m_hover_id])); + glsafe(::glColor4fv(AXES_COLOR[m_hover_id])); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[m_hover_id].center.data()); @@ -220,19 +220,20 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); double size = m_dragging ? (double)m_grabbers[axis].get_dragging_half_size(mean_size) : (double)m_grabbers[axis].get_half_size(mean_size); - float color[3]; - ::memcpy((void*)color, (const void*)m_grabbers[axis].color, 3 * sizeof(float)); + float color[4]; + ::memcpy((void*)color, (const void*)m_grabbers[axis].color, 4 * sizeof(float)); if (!picking && (m_hover_id != -1)) { color[0] = 1.0f - color[0]; color[1] = 1.0f - color[1]; color[2] = 1.0f - color[2]; + color[3] = color[3]; } if (!picking) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor3fv(color)); + glsafe(::glColor4fv(color)); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2))); if (axis == X) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index f481bb5d7..9a2c72633 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -155,7 +155,7 @@ void GLGizmoRotate::on_render() const transform_to_local(selection); glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - glsafe(::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); + glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); render_circle(); @@ -166,7 +166,7 @@ void GLGizmoRotate::on_render() const render_reference_radius(); } - glsafe(::glColor3fv(m_highlight_color)); + glsafe(::glColor4fv(m_highlight_color)); if (m_hover_id != -1) render_angle(); @@ -287,14 +287,14 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); m_grabbers[0].angles(2) = m_angle; - glsafe(::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); + glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); ::glBegin(GL_LINES); ::glVertex3f(0.0f, 0.0f, 0.0f); ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); - ::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 4 * sizeof(float)); render_grabbers(box); } @@ -306,8 +306,8 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); double size = m_dragging ? (double)m_grabbers[0].get_dragging_half_size(mean_size) : (double)m_grabbers[0].get_half_size(mean_size); - float color[3]; - ::memcpy((void*)color, (const void*)m_grabbers[0].color, 3 * sizeof(float)); + float color[4]; + ::memcpy((void*)color, (const void*)m_grabbers[0].color, 4 * sizeof(float)); if (!picking && (m_hover_id != -1)) { color[0] = 1.0f - color[0]; @@ -318,7 +318,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick if (!picking) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor3fv(color)); + glsafe(::glColor4fv(color)); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 7dc38b801..bf540cb00 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -172,20 +172,20 @@ void GLGizmoScale3D::on_render() const // x axis m_grabbers[0].center = m_transform * Vec3d(m_box.min(0), center(1), center(2)) - offset_x; m_grabbers[1].center = m_transform * Vec3d(m_box.max(0), center(1), center(2)) + offset_x; - ::memcpy((void*)m_grabbers[0].color, (ctrl_down && (m_hover_id == 1)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 3 * sizeof(float)); - ::memcpy((void*)m_grabbers[1].color, (ctrl_down && (m_hover_id == 0)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[0].color, (ctrl_down && (m_hover_id == 1)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[1].color, (ctrl_down && (m_hover_id == 0)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); // y axis m_grabbers[2].center = m_transform * Vec3d(center(0), m_box.min(1), center(2)) - offset_y; m_grabbers[3].center = m_transform * Vec3d(center(0), m_box.max(1), center(2)) + offset_y; - ::memcpy((void*)m_grabbers[2].color, (ctrl_down && (m_hover_id == 3)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 3 * sizeof(float)); - ::memcpy((void*)m_grabbers[3].color, (ctrl_down && (m_hover_id == 2)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[2].color, (ctrl_down && (m_hover_id == 3)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[3].color, (ctrl_down && (m_hover_id == 2)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); // z axis m_grabbers[4].center = m_transform * Vec3d(center(0), center(1), m_box.min(2)) - offset_z; m_grabbers[5].center = m_transform * Vec3d(center(0), center(1), m_box.max(2)) + offset_z; - ::memcpy((void*)m_grabbers[4].color, (ctrl_down && (m_hover_id == 5)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 3 * sizeof(float)); - ::memcpy((void*)m_grabbers[5].color, (ctrl_down && (m_hover_id == 4)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[4].color, (ctrl_down && (m_hover_id == 5)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[5].color, (ctrl_down && (m_hover_id == 4)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); // uniform m_grabbers[6].center = m_transform * Vec3d(m_box.min(0), m_box.min(1), center(2)) - offset_x - offset_y; @@ -194,7 +194,7 @@ void GLGizmoScale3D::on_render() const m_grabbers[9].center = m_transform * Vec3d(m_box.min(0), m_box.max(1), center(2)) - offset_x + offset_y; for (int i = 6; i < 10; ++i) { - ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 3 * sizeof(float)); + ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 4 * sizeof(float)); } // sets grabbers orientation @@ -214,20 +214,20 @@ void GLGizmoScale3D::on_render() const // draw connections if (m_grabbers[0].enabled && m_grabbers[1].enabled) { - glsafe(::glColor3fv(m_grabbers[0].color)); + glsafe(::glColor4fv(m_grabbers[0].color)); render_grabbers_connection(0, 1); } if (m_grabbers[2].enabled && m_grabbers[3].enabled) { - glsafe(::glColor3fv(m_grabbers[2].color)); + glsafe(::glColor4fv(m_grabbers[2].color)); render_grabbers_connection(2, 3); } if (m_grabbers[4].enabled && m_grabbers[5].enabled) { - glsafe(::glColor3fv(m_grabbers[4].color)); + glsafe(::glColor4fv(m_grabbers[4].color)); render_grabbers_connection(4, 5); } - glsafe(::glColor3fv(m_base_color)); + glsafe(::glColor4fv(m_base_color)); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); @@ -238,7 +238,7 @@ void GLGizmoScale3D::on_render() const else if ((m_hover_id == 0) || (m_hover_id == 1)) { // draw connection - glsafe(::glColor3fv(m_grabbers[0].color)); + glsafe(::glColor4fv(m_grabbers[0].color)); render_grabbers_connection(0, 1); // draw grabbers m_grabbers[0].render(true, grabber_mean_size); @@ -247,7 +247,7 @@ void GLGizmoScale3D::on_render() const else if ((m_hover_id == 2) || (m_hover_id == 3)) { // draw connection - glsafe(::glColor3fv(m_grabbers[2].color)); + glsafe(::glColor4fv(m_grabbers[2].color)); render_grabbers_connection(2, 3); // draw grabbers m_grabbers[2].render(true, grabber_mean_size); @@ -256,7 +256,7 @@ void GLGizmoScale3D::on_render() const else if ((m_hover_id == 4) || (m_hover_id == 5)) { // draw connection - glsafe(::glColor3fv(m_grabbers[4].color)); + glsafe(::glColor4fv(m_grabbers[4].color)); render_grabbers_connection(4, 5); // draw grabbers m_grabbers[4].render(true, grabber_mean_size); @@ -265,7 +265,7 @@ void GLGizmoScale3D::on_render() const else if (m_hover_id >= 6) { // draw connection - glsafe(::glColor3fv(m_drag_color)); + glsafe(::glColor4fv(m_drag_color)); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 19b0c791c..7db944406 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -286,7 +286,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glTranslated(0.0, 0.0, m_z_shift)); glsafe(::glMultMatrixd(instance_matrix.data())); - float render_color[3]; + float render_color[4]; size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); for (size_t i = 0; i < cache_size; ++i) { @@ -298,12 +298,14 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) // First decide about the color of the point. if (picking) { - std::array color = picking_color_component(i); + std::array color = picking_color_component(i); render_color[0] = color[0]; render_color[1] = color[1]; render_color[2] = color[2]; + render_color[3] = picking_checksum_alpha_channel(render_color[0], render_color[1], render_color[2]); } else { + render_color[3] = 1.f; if ((m_hover_id == i && m_editing_mode)) { // ignore hover state unless editing mode is active render_color[0] = 0.f; render_color[1] = 1.0f; @@ -320,7 +322,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f; } } - glsafe(::glColor3fv(render_color)); + glsafe(::glColor4fv(render_color)); float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f}; glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); From d25c5e04730cf6795fa634164faf79ae4bf613ba Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 7 Aug 2019 14:28:46 +0200 Subject: [PATCH 16/20] Added printable state update on canvas from Undo/redo --- src/slic3r/GUI/GUI_ObjectList.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 66387b9f0..441e91707 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3628,18 +3628,22 @@ void ObjectList::update_after_undo_redo() m_objects_model->DeleteAll(); size_t obj_idx = 0; + std::vector obj_idxs; + obj_idxs.reserve(m_objects->size()); while (obj_idx < m_objects->size()) { add_object_to_list(obj_idx, false); + obj_idxs.push_back(obj_idx); ++obj_idx; } -#ifndef __WXOSX__ -// selection_changed(); -#endif /* __WXOSX__ */ - update_selections(); m_prevent_canvas_selection_update = false; + + // update printable states on canvas + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs); + // update scene + wxGetApp().plater()->update(); } void ObjectList::update_printable_state(int obj_idx, int instance_idx) From a19a506ad8d925f9c9a6df93311f8b87b7205012 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 14:55:34 +0200 Subject: [PATCH 17/20] GLCanvas requires 8bit alpha channel for picking checksums. --- src/slic3r/GUI/GLCanvas3DManager.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index b2a3161e8..781fc7948 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -290,7 +290,21 @@ GLCanvas3D* GLCanvas3DManager::get_canvas(wxGLCanvas* canvas) wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent) { - int attribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 24, WX_GL_SAMPLE_BUFFERS, GL_TRUE, WX_GL_SAMPLES, 4, 0 }; + int attribList[] = { + WX_GL_RGBA, + WX_GL_DOUBLEBUFFER, + // RGB channels each should be allocated with 8 bit depth. One should almost certainly get these bit depths by default. + WX_GL_MIN_RED, 8, + WX_GL_MIN_GREEN, 8, + WX_GL_MIN_BLUE, 8, + // Requesting an 8 bit alpha channel. Interestingly, the NVIDIA drivers would most likely work with some alpha plane, but glReadPixels would not return + // the alpha channel on NVIDIA if not requested when the GL context is created. + WX_GL_MIN_ALPHA, 0, + WX_GL_DEPTH_SIZE, 24, + WX_GL_SAMPLE_BUFFERS, GL_TRUE, + WX_GL_SAMPLES, 4, + 0 + }; if (s_multisample == MS_Unknown) { From 7cef1292b20306eb19cede4fefce492c590dfedf Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 15:03:43 +0200 Subject: [PATCH 18/20] Yet another fix of the preceding commit. --- src/slic3r/GUI/GLCanvas3DManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 781fc7948..c096c0e9f 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -299,7 +299,7 @@ wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent) WX_GL_MIN_BLUE, 8, // Requesting an 8 bit alpha channel. Interestingly, the NVIDIA drivers would most likely work with some alpha plane, but glReadPixels would not return // the alpha channel on NVIDIA if not requested when the GL context is created. - WX_GL_MIN_ALPHA, 0, + WX_GL_MIN_ALPHA, 8, WX_GL_DEPTH_SIZE, 24, WX_GL_SAMPLE_BUFFERS, GL_TRUE, WX_GL_SAMPLES, 4, @@ -314,7 +314,7 @@ wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent) } if (! can_multisample()) - attribList[4] = 0; + attribList[12] = 0; return new wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); } From 841d0796b79b923f98cd477b39c2abf9ab6e7ac4 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 7 Aug 2019 15:36:09 +0200 Subject: [PATCH 19/20] Fix of the SLA gizmo picking. --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 7db944406..d120cb95f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -302,7 +302,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color[0] = color[0]; render_color[1] = color[1]; render_color[2] = color[2]; - render_color[3] = picking_checksum_alpha_channel(render_color[0], render_color[1], render_color[2]); + render_color[3] = color[3]; } else { render_color[3] = 1.f; From 850fbdbe56f18c1b18f1e09d6060198f02a1ef2d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 7 Aug 2019 15:39:46 +0200 Subject: [PATCH 20/20] Added snapshot taking for Set Printable/Unprintable for full object --- src/slic3r/GUI/GUI_ObjectList.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 441e91707..d860e8724 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3669,7 +3669,13 @@ void ObjectList::toggle_printable_state(wxDataViewItem item) ModelObject* object = (*m_objects)[obj_idx]; // get object's printable and change it - bool printable = !m_objects_model->IsPrintable(item); + const bool printable = !m_objects_model->IsPrintable(item); + + const wxString snapshot_text = wxString::Format("%s %s", + printable ? _(L("Set Printable")) : _(L("Set Unprintable")), + object->name); + take_snapshot(snapshot_text); + // set printable value for all instances in object for (auto inst : object->instances) inst->printable = printable;