diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index 1995805f87..5f33b17abc 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -18,19 +18,19 @@ use warnings; use Wx qw(wxTheApp :timer :bitmap :icon :dialog); #============================================================================================================================== #use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS EVT_CHAR EVT_TIMER); -#============================================================================================================================== # must load OpenGL *before* Wx::GLCanvas use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants); use base qw(Wx::GLCanvas Class::Accessor); -use Math::Trig qw(asin tan); -use List::Util qw(reduce min max first); #============================================================================================================================== -use Slic3r::Geometry qw(X Y); +#use Math::Trig qw(asin tan); +#use List::Util qw(reduce min max first); #use Slic3r::Geometry qw(X Y normalize scale unscale scaled_epsilon); #use Slic3r::Geometry::Clipper qw(offset_ex intersection_pl JT_ROUND); #============================================================================================================================== use Wx::GLCanvas qw(:all); -use Slic3r::Geometry qw(PI); +#============================================================================================================================== +#use Slic3r::Geometry qw(PI); +#============================================================================================================================== # volumes: reference to vector of Slic3r::GUI::3DScene::Volume. #============================================================================================================================== @@ -259,12 +259,10 @@ sub new { sub Destroy { my ($self) = @_; -#============================================================================================================================== -# $self->{layer_height_edit_timer}->Stop; -#============================================================================================================================== - $self->DestroyGL; #============================================================================================================================== Slic3r::GUI::_3DScene::remove_canvas($self); +# $self->{layer_height_edit_timer}->Stop; +# $self->DestroyGL; #============================================================================================================================== return $self->SUPER::Destroy; } @@ -1247,13 +1245,11 @@ sub SetCurrent { # } # } #} -#=================================================================================================================================== - -sub DestroyGL { - my $self = shift; - if ($self->GetContext) { - $self->SetCurrent($self->GetContext); -#=================================================================================================================================== +# +#sub DestroyGL { +# my $self = shift; +# if ($self->GetContext) { +# $self->SetCurrent($self->GetContext); # if ($self->{plain_shader}) { # $self->{plain_shader}->release; # delete $self->{plain_shader}; @@ -1262,12 +1258,10 @@ sub DestroyGL { # $self->{layer_height_edit_shader}->release; # delete $self->{layer_height_edit_shader}; # } -#=================================================================================================================================== - $self->volumes->release_geometry; - } -} - -#============================================================================================================================== +# $self->volumes->release_geometry; +# } +#} +# #sub Render { # my ($self, $dc) = @_; # @@ -2145,10 +2139,12 @@ sub DestroyGL { package Slic3r::GUI::3DScene; use base qw(Slic3r::GUI::3DScene::Base); -use OpenGL qw(:glconstants :gluconstants :glufunctions); -use List::Util qw(first min max); -use Slic3r::Geometry qw(scale unscale epsilon); -use Slic3r::Print::State ':steps'; +#=================================================================================================================================== +#use OpenGL qw(:glconstants :gluconstants :glufunctions); +#use List::Util qw(first min max); +#use Slic3r::Geometry qw(scale unscale epsilon); +#use Slic3r::Print::State ':steps'; +#=================================================================================================================================== #=================================================================================================================================== #__PACKAGE__->mk_accessors(qw( diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index ebbbcf43eb..6a2246fa16 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -91,6 +91,7 @@ sub new { # but in rare cases it may not have been called yet. wxTheApp->{app_config}->save; #============================================================================================================================== + $self->{plater}->{print} = undef if($self->{plater}); Slic3r::GUI::_3DScene::remove_all_canvases(); #============================================================================================================================== # propagate event diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm index 2a710b6f9f..6641d45e5f 100644 --- a/lib/Slic3r/GUI/Plater/3D.pm +++ b/lib/Slic3r/GUI/Plater/3D.pm @@ -32,7 +32,9 @@ sub new { $self->{objects} = $objects; $self->{model} = $model; - $self->{print} = $print; +#============================================================================================================================== +# $self->{print} = $print; +#============================================================================================================================== $self->{config} = $config; #============================================================================================================================== Slic3r::GUI::_3DScene::set_print($self, $print); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 783ae52f8c..41741eef82 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -969,6 +969,12 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) GLCanvas3D::~GLCanvas3D() { + if (m_volumes != nullptr) + { + set_current(); + m_volumes->release_geometry(); + } + if (m_timer != nullptr) { delete m_timer; @@ -1836,6 +1842,57 @@ void GLCanvas3D::register_on_move_callback(void* callback) m_on_move_callback.register_callback(callback); } +void GLCanvas3D::bind_event_handlers() +{ + if (m_canvas != nullptr) + { + m_canvas->Bind(wxEVT_SIZE, &GLCanvas3D::on_size, this); + m_canvas->Bind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); + m_canvas->Bind(wxEVT_CHAR, &GLCanvas3D::on_char, this); + m_canvas->Bind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); + m_canvas->Bind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); + m_canvas->Bind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_MIDDLE_DOWN, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_MIDDLE_UP, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_RIGHT_DOWN, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_RIGHT_UP, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_MOTION, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_ENTER_WINDOW, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_LEAVE_WINDOW, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_LEFT_DCLICK, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); + m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); + } +} + +void GLCanvas3D::unbind_event_handlers() +{ + if (m_canvas != nullptr) + { + m_canvas->GetEventHandler()->ProcessPendingEvents(); + m_canvas->Unbind(wxEVT_SIZE, &GLCanvas3D::on_size, this); + m_canvas->Unbind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); + m_canvas->Unbind(wxEVT_CHAR, &GLCanvas3D::on_char, this); + m_canvas->Unbind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); + m_canvas->Unbind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); + m_canvas->Unbind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_MIDDLE_DOWN, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_MIDDLE_UP, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_RIGHT_DOWN, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_RIGHT_UP, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_MOTION, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_ENTER_WINDOW, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_LEAVE_WINDOW, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_LEFT_DCLICK, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); + m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); + } +} + void GLCanvas3D::on_size(wxSizeEvent& evt) { m_dirty = true; diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index c8533f5147..7bd93a32eb 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -442,6 +442,9 @@ public: void register_on_model_update_callback(void* callback); void register_on_move_callback(void* callback); + void bind_event_handlers(); + void unbind_event_handlers(); + void on_size(wxSizeEvent& evt); void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index bfb11d9724..26c19e9fd3 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -138,25 +138,7 @@ bool GLCanvas3DManager::add(wxGLCanvas* canvas, wxGLContext* context) if (canvas3D == nullptr) return false; - 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); }); - canvas->Bind(wxEVT_TIMER, [canvas3D](wxTimerEvent& evt) { canvas3D->on_timer(evt); }); - canvas->Bind(wxEVT_LEFT_DOWN, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_LEFT_UP, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_MIDDLE_DOWN, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_MIDDLE_UP, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_RIGHT_DOWN, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_RIGHT_UP, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_MOTION, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_ENTER_WINDOW, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_LEAVE_WINDOW, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_LEFT_DCLICK, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_MIDDLE_DCLICK, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_RIGHT_DCLICK, [canvas3D](wxMouseEvent& evt) { canvas3D->on_mouse(evt); }); - canvas->Bind(wxEVT_PAINT, [canvas3D](wxPaintEvent& evt) { canvas3D->on_paint(evt); }); - + canvas3D->bind_event_handlers(); m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D)); std::cout << "canvas added: " << (void*)canvas << " (" << (void*)canvas3D << ")" << std::endl; @@ -170,6 +152,7 @@ bool GLCanvas3DManager::remove(wxGLCanvas* canvas) if (it == m_canvases.end()) return false; + it->second->unbind_event_handlers(); delete it->second; m_canvases.erase(it); @@ -183,6 +166,8 @@ void GLCanvas3DManager::remove_all() for (CanvasesMap::value_type& item : m_canvases) { std::cout << "canvas removed: " << (void*)item.second << std::endl; + + item.second->unbind_event_handlers(); delete item.second; } m_canvases.clear();