From 9e09c52ab008f6e8346972f0591a60e248d78ddb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 20 Sep 2019 09:53:35 +0200 Subject: [PATCH 1/6] #2948 - Max zoom takes in account custom bed model size --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index edb9c7830..08e47f30b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3372,7 +3372,7 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type) void GLCanvas3D::set_camera_zoom(double zoom) { const Size& cnv_size = get_canvas_size(); - m_camera.set_zoom(zoom, _max_bounding_box(false, false), cnv_size.get_width(), cnv_size.get_height()); + m_camera.set_zoom(zoom, _max_bounding_box(false, true), cnv_size.get_width(), cnv_size.get_height()); m_dirty = true; } From 8aaff083557a79a041ee17f1d6879a5574e62599 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 20 Sep 2019 09:57:27 +0200 Subject: [PATCH 2/6] Added Possibility to create "shape" as an independent object from 3dScene, using right click on empty place --- src/slic3r/GUI/GLCanvas3D.cpp | 12 ++++- src/slic3r/GUI/GLCanvas3D.hpp | 5 +- src/slic3r/GUI/Plater.cpp | 91 ++++++++++++++++++++--------------- 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index edb9c7830..6d069df29 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1094,7 +1094,7 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const wxDEFINE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent); -wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent); @@ -3012,15 +3012,23 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) wxGetApp().obj_manipul()->set_dirty(); // forces a frame render to update the view before the context menu is shown render(); - +/* #et_FIXME Vec2d logical_pos = pos.cast(); #if ENABLE_RETINA_GL const float factor = m_retina_helper->get_scale_factor(); logical_pos = logical_pos.cwiseQuotient(Vec2d(factor, factor)); #endif // ENABLE_RETINA_GL post_event(Vec2dEvent(EVT_GLCANVAS_RIGHT_CLICK, logical_pos)); +*/ } } + // #et_FIXME + Vec2d logical_pos = pos.cast(); +#if ENABLE_RETINA_GL + const float factor = m_retina_helper->get_scale_factor(); + logical_pos = logical_pos.cwiseQuotient(Vec2d(factor, factor)); +#endif // ENABLE_RETINA_GL + post_event(RBtnEvent(EVT_GLCANVAS_RIGHT_CLICK, {logical_pos, m_hover_volume_idxs.empty()})); } mouse_up_cleanup(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index b15402a52..e6b10e9ca 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -71,6 +71,9 @@ public: wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent); using Vec2dEvent = Event; +// #et_FIXME : RBtnEvent is used instead of Vec2dEvent on EVT_GLCANVAS_RIGHT_CLICK +// _bool_ value is used as a indicator of selection in the 3DScene +using RBtnEvent = Event>; template using Vec2dsEvent = ArrayEvent; using Vec3dEvent = Event; @@ -78,7 +81,7 @@ template using Vec3dsEvent = ArrayEvent; wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); -wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent); wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 524034ea9..18bc08d27 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1340,6 +1340,8 @@ struct Plater::priv MenuWithSeparators part_menu; // SLA-Object popup menu MenuWithSeparators sla_object_menu; + // Default popup menu (when nothing is selected on 3DScene) + MenuWithSeparators default_menu; // Removed/Prepended Items according to the view mode std::vector items_increase; @@ -1879,7 +1881,7 @@ struct Plater::priv void on_action_layersediting(SimpleEvent&); void on_object_select(SimpleEvent&); - void on_right_click(Vec2dEvent&); + void on_right_click(RBtnEvent&); void on_wipetower_moved(Vec3dEvent&); void on_wipetower_rotated(Vec3dEvent&); void on_update_geometry(Vec3dsEvent<2>&); @@ -3446,57 +3448,66 @@ void Plater::priv::on_object_select(SimpleEvent& evt) selection_changed(); } -void Plater::priv::on_right_click(Vec2dEvent& evt) +void Plater::priv::on_right_click(RBtnEvent& evt) { int obj_idx = get_selected_object_idx(); + + wxMenu* menu = nullptr; + if (obj_idx == -1) - return; - - wxMenu* menu = printer_technology == ptSLA ? &sla_object_menu : - get_selection().is_single_full_instance() ? // show "Object menu" for each FullInstance instead of FullObject - &object_menu : &part_menu; - - sidebar->obj_list()->append_menu_item_settings(menu); - - if (printer_technology != ptSLA) - sidebar->obj_list()->append_menu_item_change_extruder(menu); - - if (menu != &part_menu) + menu = &default_menu; + else { - /* Remove/Prepend "increase/decrease instances" menu items according to the view mode. - * Suppress to show those items for a Simple mode - */ - const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF; - if (wxGetApp().get_mode() == comSimple) { - if (menu->FindItem(_(L("Add instance"))) != wxNOT_FOUND) - { - /* Detach an items from the menu, but don't delete them - * so that they can be added back later - * (after switching to the Advanced/Expert mode) - */ - menu->Remove(items_increase[id]); - menu->Remove(items_decrease[id]); - menu->Remove(items_set_number_of_copies[id]); + // If in 3DScene is(are) selected volume(s), but right button was clicked on empty space + if (evt.data.second) + return; + + menu = printer_technology == ptSLA ? &sla_object_menu : + get_selection().is_single_full_instance() ? // show "Object menu" for each FullInstance instead of FullObject + &object_menu : &part_menu; + + sidebar->obj_list()->append_menu_item_settings(menu); + + if (printer_technology != ptSLA) + sidebar->obj_list()->append_menu_item_change_extruder(menu); + + if (menu != &part_menu) + { + /* Remove/Prepend "increase/decrease instances" menu items according to the view mode. + * Suppress to show those items for a Simple mode + */ + const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF; + if (wxGetApp().get_mode() == comSimple) { + if (menu->FindItem(_(L("Add instance"))) != wxNOT_FOUND) + { + /* Detach an items from the menu, but don't delete them + * so that they can be added back later + * (after switching to the Advanced/Expert mode) + */ + menu->Remove(items_increase[id]); + menu->Remove(items_decrease[id]); + menu->Remove(items_set_number_of_copies[id]); + } } - } - else { - if (menu->FindItem(_(L("Add instance"))) == wxNOT_FOUND) - { - // Prepend items to the menu, if those aren't not there - menu->Prepend(items_set_number_of_copies[id]); - menu->Prepend(items_decrease[id]); - menu->Prepend(items_increase[id]); + else { + if (menu->FindItem(_(L("Add instance"))) == wxNOT_FOUND) + { + // Prepend items to the menu, if those aren't not there + menu->Prepend(items_set_number_of_copies[id]); + menu->Prepend(items_decrease[id]); + menu->Prepend(items_increase[id]); + } } } } - if (q != nullptr) { + if (q != nullptr && menu) { #ifdef __linux__ // For some reason on Linux the menu isn't displayed if position is specified // (even though the position is sane). q->PopupMenu(menu); #else - q->PopupMenu(menu, (int)evt.data.x(), (int)evt.data.y()); + q->PopupMenu(menu, (int)evt.data.first.x(), (int)evt.data.first.y()); #endif } } @@ -3548,12 +3559,14 @@ bool Plater::priv::init_object_menu() init_common_menu(&part_menu, true); complit_init_part_menu(); + sidebar->obj_list()->create_default_popupmenu(&default_menu); + return true; } void Plater::priv::msw_rescale_object_menu() { - for (MenuWithSeparators* menu : { &object_menu, &sla_object_menu, &part_menu }) + for (MenuWithSeparators* menu : { &object_menu, &sla_object_menu, &part_menu, &default_menu }) msw_rescale_menu(dynamic_cast(menu)); } From b241ba16ed403492dad83068e655fec1723305e3 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 20 Sep 2019 10:53:50 +0200 Subject: [PATCH 3/6] Fixed layer profile equality check for wipe tower validation (fixup of b43003d) --- src/libslic3r/Print.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index cbbbf1f1a..4d8482743 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1236,7 +1236,8 @@ std::string Print::validate() const // The comparison of the profiles is not just about element-wise equality, some layers may not be // explicitely included. Always remember z and height of last reference layer that in the vector - // and compare to that. + // and compare to that. In case some layers are in the vectors multiple times, only the last entry is + // taken into account and compared. size_t i = 0; // index into tested profile size_t j = 0; // index into reference profile coordf_t ref_z = -1.; @@ -1244,8 +1245,12 @@ std::string Print::validate() const coordf_t ref_height = -1.; while (i < layer_height_profile.size()) { coordf_t this_z = layer_height_profile[i]; + // find the last entry with this z + while (i+2 < layer_height_profile.size() && layer_height_profile[i+2] == this_z) + i += 2; + coordf_t this_height = layer_height_profile[i+1]; - if (next_ref_z < this_z + EPSILON) { + if (ref_height < -1. || next_ref_z < this_z + EPSILON) { ref_z = next_ref_z; do { // one layer can be in the vector several times ref_height = layer_height_profile_tallest[j+1]; From d66bf7e1e198b66feb78af9d7787490428995015 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 20 Sep 2019 11:19:06 +0200 Subject: [PATCH 4/6] Follow-up of 8aaff083557a79a041ee17f1d6879a5574e62599 -> Do not show the new context menu when the user pans the scene + cleanup --- src/slic3r/GUI/GLCanvas3D.cpp | 13 +++---------- src/slic3r/GUI/GLCanvas3D.hpp | 1 - 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 21cd72a22..715d9f806 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3012,23 +3012,16 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) wxGetApp().obj_manipul()->set_dirty(); // forces a frame render to update the view before the context menu is shown render(); -/* #et_FIXME - Vec2d logical_pos = pos.cast(); -#if ENABLE_RETINA_GL - const float factor = m_retina_helper->get_scale_factor(); - logical_pos = logical_pos.cwiseQuotient(Vec2d(factor, factor)); -#endif // ENABLE_RETINA_GL - post_event(Vec2dEvent(EVT_GLCANVAS_RIGHT_CLICK, logical_pos)); -*/ } } - // #et_FIXME Vec2d logical_pos = pos.cast(); #if ENABLE_RETINA_GL const float factor = m_retina_helper->get_scale_factor(); logical_pos = logical_pos.cwiseQuotient(Vec2d(factor, factor)); #endif // ENABLE_RETINA_GL - post_event(RBtnEvent(EVT_GLCANVAS_RIGHT_CLICK, {logical_pos, m_hover_volume_idxs.empty()})); + if (!m_mouse.dragging) + // do not post the event if the user is panning the scene + post_event(RBtnEvent(EVT_GLCANVAS_RIGHT_CLICK, { logical_pos, m_hover_volume_idxs.empty() })); } mouse_up_cleanup(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e6b10e9ca..fb767360c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -71,7 +71,6 @@ public: wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent); using Vec2dEvent = Event; -// #et_FIXME : RBtnEvent is used instead of Vec2dEvent on EVT_GLCANVAS_RIGHT_CLICK // _bool_ value is used as a indicator of selection in the 3DScene using RBtnEvent = Event>; template using Vec2dsEvent = ArrayEvent; From 7e060f84bd534fb027bdc3a1f4b48cce912090bd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 20 Sep 2019 11:30:29 +0200 Subject: [PATCH 5/6] Forcing of explicit SetWidth for the columns under OSX, as an attempt to fix a narrow column width on 4(5)K monitors under OSX --- src/slic3r/GUI/GUI_ObjectList.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 47be4b5eb..1d5d8f1a5 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -255,21 +255,30 @@ void ObjectList::create_objects_ctrl() EnableDropTarget(wxDF_UNICODETEXT); #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + const int em = wxGetApp().em_unit(); + // column ItemName(Icon+Text) of the view control: // And Icon can be consisting of several bitmaps AppendColumn(new wxDataViewColumn(_(L("Name")), new BitmapTextRenderer(), - colName, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); + colName, 20*em, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); // column PrintableProperty (Icon) of the view control: - AppendBitmapColumn(" ", colPrint, wxDATAVIEW_CELL_INERT, int(2 * wxGetApp().em_unit()), + AppendBitmapColumn(" ", colPrint, wxDATAVIEW_CELL_INERT, 3*em, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); // column Extruder of the view control: AppendColumn(create_objects_list_extruder_column(4)); // column ItemEditing of the view control: - AppendBitmapColumn(_(L("Editing")), colEditing, wxDATAVIEW_CELL_INERT, int(2.5 * wxGetApp().em_unit())/*25*/, + AppendBitmapColumn(_(L("Editing")), colEditing, wxDATAVIEW_CELL_INERT, 3*em, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + + if (wxOSX) + { + GetColumn(colName)->SetWidth(20*em); + GetColumn(colPrint)->SetWidth(3*em); + GetColumn(colExtruder)->SetWidth(8*em); + } } void ObjectList::create_popup_menus() @@ -822,12 +831,18 @@ void ObjectList::list_manipulation(bool evt_context_menu/* = false*/) show_context_menu(evt_context_menu); else if (title == _("Name")) { - int obj_idx, vol_idx; - get_selected_item_indexes(obj_idx, vol_idx, item); + if (wxOSX) + show_context_menu(evt_context_menu); // return context menu under OSX (related to #2909) - if (is_windows10() && get_mesh_errors_count(obj_idx, vol_idx) > 0 && - pt.x > 2*wxGetApp().em_unit() && pt.x < 4*wxGetApp().em_unit() ) - fix_through_netfabb(); + if (is_windows10()) + { + int obj_idx, vol_idx; + get_selected_item_indexes(obj_idx, vol_idx, item); + + if (get_mesh_errors_count(obj_idx, vol_idx) > 0 && + pt.x > 2*wxGetApp().em_unit() && pt.x < 4*wxGetApp().em_unit() ) + fix_through_netfabb(); + } } #ifndef __WXMSW__ From 656569b0e9e836c628f85cabc16e6805382ac729 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 20 Sep 2019 16:45:43 +0200 Subject: [PATCH 6/6] Fix of https://github.com/prusa3d/PrusaSlicer/issues/2953 printf-like function argument mismatch: num was long, which was obfuscated by the auto keyword --- src/slic3r/GUI/Plater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 18bc08d27..28474cac9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4336,14 +4336,14 @@ void Plater::set_number_of_copies(/*size_t num*/) ModelObject* model_object = p->model.objects[obj_idx]; - const auto num = wxGetNumberFromUser( " ", _("Enter the number of copies:"), + const int num = wxGetNumberFromUser( " ", _("Enter the number of copies:"), _("Copies of the selected object"), model_object->instances.size(), 0, 1000, this ); if (num < 0) return; Plater::TakeSnapshot snapshot(this, wxString::Format(_(L("Set numbers of copies to %d")), num)); - int diff = (int)num - (int)model_object->instances.size(); + int diff = num - (int)model_object->instances.size(); if (diff > 0) increase_instances(diff); else if (diff < 0)