From db260a669cf642826e3af4956e638c7eea6b71f3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 28 May 2018 15:23:01 +0200 Subject: [PATCH] 3DScene mouse wheel event moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 129 ++++++++++-------------- lib/Slic3r/GUI/Plater/3D.pm | 1 + xs/src/slic3r/GUI/3DScene.cpp | 10 +- xs/src/slic3r/GUI/3DScene.hpp | 2 +- xs/src/slic3r/GUI/GLCanvas3D.cpp | 84 +++++++++++---- xs/src/slic3r/GUI/GLCanvas3D.hpp | 7 +- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 14 +-- xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 2 +- xs/xsp/GUI_3DScene.xsp | 15 ++- 9 files changed, 148 insertions(+), 116 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index 8a80eeac7..435a4892b 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -226,8 +226,8 @@ sub new { # $self->Resize( $self->GetSizeWH ); # $self->Refresh; # }); +# EVT_MOUSEWHEEL($self, \&mouse_wheel_event); #============================================================================================================================== - EVT_MOUSEWHEEL($self, \&mouse_wheel_event); EVT_MOUSE_EVENTS($self, \&mouse_event); #============================================================================================================================== ## EVT_KEY_DOWN($self, sub { @@ -392,12 +392,14 @@ sub _variable_layer_thickness_bar_rect_viewport { #============================================================================================================================== } -# Returns an array with (left, top, right, bottom) of the variable layer thickness bar on the screen. -sub _variable_layer_thickness_reset_rect_screen { - my ($self) = @_; - my ($cw, $ch) = $self->GetSizeWH; - return ($cw - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, $ch - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, $cw, $ch); -} +#============================================================================================================================== +## Returns an array with (left, top, right, bottom) of the variable layer thickness bar on the screen. +#sub _variable_layer_thickness_reset_rect_screen { +# my ($self) = @_; +# my ($cw, $ch) = $self->GetSizeWH; +# return ($cw - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, $ch - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, $cw, $ch); +#} +#============================================================================================================================== sub _variable_layer_thickness_reset_rect_viewport { my ($self) = @_; @@ -732,83 +734,60 @@ sub mouse_event { } } -sub mouse_wheel_event { - my ($self, $e) = @_; - - if ($e->MiddleIsDown) { - # Ignore the wheel events if the middle button is pressed. - return; - } #============================================================================================================================== - if (Slic3r::GUI::_3DScene::is_layers_editing_enabled($self) && $self->{print}) { - my $object_idx_selected = Slic3r::GUI::_3DScene::get_layers_editing_first_selected_object_id($self, $self->{print}->object_count); +#sub mouse_wheel_event { +# my ($self, $e) = @_; +# +# if ($e->MiddleIsDown) { +# # Ignore the wheel events if the middle button is pressed. +# return; +# } # if ($self->layer_editing_enabled && $self->{print}) { # my $object_idx_selected = $self->_first_selected_object_id_for_variable_layer_height_editing; -#============================================================================================================================== - if ($object_idx_selected != -1) { - # A volume is selected. Test, whether hovering over a layer thickness bar. -#============================================================================================================================== - if (Slic3r::GUI::_3DScene::bar_rect_contains($self, $e->GetX, $e->GetY)) { +# if ($object_idx_selected != -1) { +# # A volume is selected. Test, whether hovering over a layer thickness bar. # if ($self->_variable_layer_thickness_bar_rect_mouse_inside($e)) { -#============================================================================================================================== - # Adjust the width of the selection. -#============================================================================================================================== - Slic3r::GUI::_3DScene::set_layers_editing_band_width($self, max(min(Slic3r::GUI::_3DScene::get_layers_editing_band_width($self) * (1 + 0.1 * $e->GetWheelRotation() / $e->GetWheelDelta()), 10.), 1.5)); +# # Adjust the width of the selection. # $self->{layer_height_edit_band_width} = max(min($self->{layer_height_edit_band_width} * (1 + 0.1 * $e->GetWheelRotation() / $e->GetWheelDelta()), 10.), 1.5); -#============================================================================================================================== - $self->Refresh; - return; - } - } - } - - # Calculate the zoom delta and apply it to the current zoom factor - my $zoom = $e->GetWheelRotation() / $e->GetWheelDelta(); - $zoom = max(min($zoom, 4), -4); - $zoom /= 10; -#============================================================================================================================== - $zoom = Slic3r::GUI::_3DScene::get_camera_zoom($self) / (1-$zoom); +# $self->Refresh; +# return; +# } +# } +# } +# +# # Calculate the zoom delta and apply it to the current zoom factor +# my $zoom = $e->GetWheelRotation() / $e->GetWheelDelta(); +# $zoom = max(min($zoom, 4), -4); +# $zoom /= 10; # $zoom = $self->_zoom / (1-$zoom); -#============================================================================================================================== - # Don't allow to zoom too far outside the scene. -#============================================================================================================================== - my $zoom_min = $self->get_zoom_to_bounding_box_factor(Slic3r::GUI::_3DScene::get_max_bounding_box($self)); +# # Don't allow to zoom too far outside the scene. # my $zoom_min = $self->get_zoom_to_bounding_box_factor($self->max_bounding_box); -#============================================================================================================================== - $zoom_min *= 0.4 if defined $zoom_min; - $zoom = $zoom_min if defined $zoom_min && $zoom < $zoom_min; -#============================================================================================================================== - $zoom = Slic3r::GUI::_3DScene::set_camera_zoom($self, $zoom); +# $zoom_min *= 0.4 if defined $zoom_min; +# $zoom = $zoom_min if defined $zoom_min && $zoom < $zoom_min; # $self->_zoom($zoom); -#============================================================================================================================== - -# # In order to zoom around the mouse point we need to translate -# # the camera target -# my $size = Slic3r::Pointf->new($self->GetSizeWH); -# my $pos = Slic3r::Pointf->new($e->GetX, $size->y - $e->GetY); #- -# $self->_camera_target->translate( -# # ($pos - $size/2) represents the vector from the viewport center -# # to the mouse point. By multiplying it by $zoom we get the new, -# # transformed, length of such vector. -# # Since we want that point to stay fixed, we move our camera target -# # in the opposite direction by the delta of the length of such vector -# # ($zoom - 1). We then scale everything by 1/$self->_zoom since -# # $self->_camera_target is expressed in terms of model units. -# -($pos->x - $size->x/2) * ($zoom) / $self->_zoom, -# -($pos->y - $size->y/2) * ($zoom) / $self->_zoom, -# 0, -# ) if 0; - - $self->on_viewport_changed->() if $self->on_viewport_changed; -#============================================================================================================================== -#============================================================================================================================== - Slic3r::GUI::_3DScene::resize($self, $self->GetSizeWH) if Slic3r::GUI::_3DScene::is_shown_on_screen($self); +# +## # In order to zoom around the mouse point we need to translate +## # the camera target +## my $size = Slic3r::Pointf->new($self->GetSizeWH); +## my $pos = Slic3r::Pointf->new($e->GetX, $size->y - $e->GetY); #- +## $self->_camera_target->translate( +## # ($pos - $size/2) represents the vector from the viewport center +## # to the mouse point. By multiplying it by $zoom we get the new, +## # transformed, length of such vector. +## # Since we want that point to stay fixed, we move our camera target +## # in the opposite direction by the delta of the length of such vector +## # ($zoom - 1). We then scale everything by 1/$self->_zoom since +## # $self->_camera_target is expressed in terms of model units. +## -($pos->x - $size->x/2) * ($zoom) / $self->_zoom, +## -($pos->y - $size->y/2) * ($zoom) / $self->_zoom, +## 0, +## ) if 0; +# +# $self->on_viewport_changed->() if $self->on_viewport_changed; # $self->Resize($self->GetSizeWH) if $self->IsShownOnScreen; -#============================================================================================================================== - $self->Refresh; -} - -#============================================================================================================================== +# $self->Refresh; +#} +# ## Reset selection. #sub reset_objects { # my ($self) = @_; diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm index 5d905c896..8e6f2b81f 100644 --- a/lib/Slic3r/GUI/Plater/3D.pm +++ b/lib/Slic3r/GUI/Plater/3D.pm @@ -32,6 +32,7 @@ sub new { $self->{print} = $print; $self->{config} = $config; #============================================================================================================================== + Slic3r::GUI::_3DScene::set_print($self, $print); Slic3r::GUI::_3DScene::set_config($self, $config); #============================================================================================================================== $self->{on_select_object} = sub {}; diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 89532677b..23f0f0194 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1802,16 +1802,16 @@ void _3DScene::select_volume(wxGLCanvas* canvas, unsigned int id) s_canvas_mgr.select_volume(canvas, id); } -DynamicPrintConfig* _3DScene::get_config(wxGLCanvas* canvas) -{ - return s_canvas_mgr.get_config(canvas); -} - void _3DScene::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config) { s_canvas_mgr.set_config(canvas, config); } +void _3DScene::set_print(wxGLCanvas* canvas, Print* print) +{ + s_canvas_mgr.set_print(canvas, print); +} + void _3DScene::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape) { return s_canvas_mgr.set_bed_shape(canvas, shape); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 0f39aa537..973b5eeb2 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -559,8 +559,8 @@ public: static void deselect_volumes(wxGLCanvas* canvas); static void select_volume(wxGLCanvas* canvas, unsigned int id); - static DynamicPrintConfig* get_config(wxGLCanvas* canvas); static void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config); + static void set_print(wxGLCanvas* canvas, Print* print); static void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape); static void set_auto_bed_shape(wxGLCanvas* canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 3c264f25d..cc968755b 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1041,6 +1041,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) , m_context(context) , m_volumes(nullptr) , m_config(nullptr) + , m_print(nullptr) , m_dirty(true) , m_apply_zoom_to_volumes_filter(false) , m_hover_volume_id(-1) @@ -1242,16 +1243,16 @@ void GLCanvas3D::select_volume(unsigned int id) } } -DynamicPrintConfig* GLCanvas3D::get_config() -{ - return m_config; -} - void GLCanvas3D::set_config(DynamicPrintConfig* config) { m_config = config; } +void GLCanvas3D::set_print(Print* print) +{ + m_print = print; +} + void GLCanvas3D::set_bed_shape(const Pointfs& shape) { m_bed.set_shape(shape); @@ -1946,15 +1947,10 @@ void GLCanvas3D::on_size(wxSizeEvent& evt) void GLCanvas3D::on_idle(wxIdleEvent& evt) { - if (!is_dirty() || !is_shown_on_screen()) + if (!is_dirty()) return; - if (m_canvas != nullptr) - { - const Size& cnv_size = get_canvas_size(); - resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); - m_canvas->Refresh(); - } + _refresh_if_shown_on_screen(); } void GLCanvas3D::on_char(wxKeyEvent& evt) @@ -1992,6 +1988,51 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } } +void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) +{ + // Ignore the wheel events if the middle button is pressed. + if (evt.MiddleIsDown()) + return; + + // Performs layers editing updates, if enabled + if (is_layers_editing_enabled() && (m_print != nullptr)) + { + int object_idx_selected = get_layers_editing_first_selected_object_id((unsigned int)m_print->objects.size()); + if (object_idx_selected != -1) + { + // A volume is selected. Test, whether hovering over a layer thickness bar. + if (bar_rect_contains((float)evt.GetX(), (float)evt.GetY())) + { + // Adjust the width of the selection. + set_layers_editing_band_width(std::max(std::min(get_layers_editing_band_width() * (1.0f + 0.1f * (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta()), 10.0f), 1.5f)); + if (m_canvas != nullptr) + m_canvas->Refresh(); + + return; + } + } + } + + // Calculate the zoom delta and apply it to the current zoom factor + float zoom = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta(); + zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f; + zoom = get_camera_zoom() / (1.0f - zoom); + + // Don't allow to zoom too far outside the scene. + float zoom_min = _get_zoom_to_bounding_box_factor(max_bounding_box()); + if (zoom_min > 0.0f) + { + zoom_min *= 0.4f; + if (zoom < zoom_min) + zoom = zoom_min; + } + + set_camera_zoom(zoom); + m_on_viewport_changed_callback.call(); + + _refresh_if_shown_on_screen(); +} + Size GLCanvas3D::get_canvas_size() const { int w = 0; @@ -2024,13 +2065,7 @@ void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox) m_on_viewport_changed_callback.call(); - if (is_shown_on_screen()) - { - const Size& cnv_size = get_canvas_size(); - resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); - if (m_canvas != nullptr) - m_canvas->Refresh(); - } + _refresh_if_shown_on_screen(); } } @@ -2126,5 +2161,16 @@ void GLCanvas3D::_deregister_callbacks() m_on_mark_volumes_for_layer_height_callback.deregister_callback(); } +void GLCanvas3D::_refresh_if_shown_on_screen() +{ + if (is_shown_on_screen()) + { + const Size& cnv_size = get_canvas_size(); + resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); + if (m_canvas != nullptr) + m_canvas->Refresh(); + } +} + } // namespace GUI } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 9a7c342c4..c5aa5a1cd 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -10,6 +10,7 @@ class wxGLContext; class wxSizeEvent; class wxIdleEvent; class wxKeyEvent; +class wxMouseEvent; namespace Slic3r { @@ -302,6 +303,7 @@ private: GLVolumeCollection* m_volumes; DynamicPrintConfig* m_config; + Print* m_print; bool m_dirty; bool m_apply_zoom_to_volumes_filter; @@ -336,8 +338,8 @@ public: void deselect_volumes(); void select_volume(unsigned int id); - DynamicPrintConfig* get_config(); void set_config(DynamicPrintConfig* config); + void set_print(Print* print); // Set the bed shape to a single closed 2D polygon(array of two element arrays), // triangulate the bed and store the triangles into m_bed.m_triangles, @@ -450,6 +452,7 @@ public: void on_size(wxSizeEvent& evt); void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); + void on_mouse_wheel(wxMouseEvent& evt); Size get_canvas_size() const; Point get_local_mouse_position() const; @@ -459,6 +462,8 @@ private: float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const; void _deregister_callbacks(); + + void _refresh_if_shown_on_screen(); }; } // namespace GUI diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 27390a14e..fea8dab8a 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -75,6 +75,7 @@ bool GLCanvas3DManager::add(wxGLCanvas* canvas, wxGLContext* context) canvas->Bind(wxEVT_SIZE, [canvas3D](wxSizeEvent& evt) { canvas3D->on_size(evt); }); canvas->Bind(wxEVT_IDLE, [canvas3D](wxIdleEvent& evt) { canvas3D->on_idle(evt); }); canvas->Bind(wxEVT_CHAR, [canvas3D](wxKeyEvent& evt) { canvas3D->on_char(evt); }); + canvas->Bind(wxEVT_MOUSEWHEEL, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse_wheel(evt); }); m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D)); @@ -203,12 +204,6 @@ void GLCanvas3DManager::select_volume(wxGLCanvas* canvas, unsigned int id) it->second->select_volume(id); } -DynamicPrintConfig* GLCanvas3DManager::get_config(wxGLCanvas* canvas) -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - return (it != m_canvases.end()) ? it->second->get_config() : nullptr; -} - void GLCanvas3DManager::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -216,6 +211,13 @@ void GLCanvas3DManager::set_config(wxGLCanvas* canvas, DynamicPrintConfig* confi it->second->set_config(config); } +void GLCanvas3DManager::set_print(wxGLCanvas* canvas, Print* print) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->set_print(print); +} + void GLCanvas3DManager::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 27807bd84..786c095e8 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -59,8 +59,8 @@ public: void deselect_volumes(wxGLCanvas* canvas); void select_volume(wxGLCanvas* canvas, unsigned int id); - DynamicPrintConfig* get_config(wxGLCanvas* canvas); void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config); + void set_print(wxGLCanvas* canvas, Print* print); void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape); void set_auto_bed_shape(wxGLCanvas* canvas); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index fb0a549fd..8aff20ae3 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -264,14 +264,6 @@ select_volume(canvas, id) CODE: _3DScene::select_volume((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id); -DynamicPrintConfig* -get_config(canvas) - SV *canvas; - CODE: - RETVAL = _3DScene::get_config((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - OUTPUT: - RETVAL - void set_config(canvas, config) SV *canvas; @@ -279,6 +271,13 @@ set_config(canvas, config) CODE: _3DScene::set_config((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), config); +void +set_print(canvas, print) + SV *canvas; + Print *print; + CODE: + _3DScene::set_print((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print); + void set_bed_shape(canvas, shape) SV *canvas;