From 30a3b2179be6bb9cfe43e66ba94b535431331338 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 30 May 2018 15:18:45 +0200 Subject: [PATCH] 3DScene timer and _variable_layer_thickness_action method moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 131 +++++++-------- xs/src/libslic3r/Print.hpp | 4 + xs/src/libslic3r/PrintObject.cpp | 13 ++ xs/src/slic3r/GUI/3DScene.cpp | 25 +++ xs/src/slic3r/GUI/3DScene.hpp | 7 + xs/src/slic3r/GUI/GLCanvas3D.cpp | 213 ++++++++++++++++++------ xs/src/slic3r/GUI/GLCanvas3D.hpp | 35 +++- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 36 ++++ xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 7 + xs/xsp/GUI_3DScene.xsp | 36 ++++ xs/xsp/Print.xsp | 18 +- 11 files changed, 389 insertions(+), 136 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index a6ec2e692..319a15535 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -49,9 +49,6 @@ __PACKAGE__->mk_accessors( qw(_quat init _drag_volume_center_offset _drag_start_xy _dragged - - _layer_height_edited - ) ); #__PACKAGE__->mk_accessors( qw(_quat _dirty init # enable_picking @@ -260,19 +257,16 @@ sub new { # } # } # }); +# +# $self->{layer_height_edit_timer_id} = &Wx::NewId(); +# $self->{layer_height_edit_timer} = Wx::Timer->new($self, $self->{layer_height_edit_timer_id}); +# EVT_TIMER($self, $self->{layer_height_edit_timer_id}, sub { +# my ($self, $event) = @_; +# return if $self->_layer_height_edited != 1; +# $self->_variable_layer_thickness_action(undef); +# }); #============================================================================================================================== - $self->{layer_height_edit_timer_id} = &Wx::NewId(); - $self->{layer_height_edit_timer} = Wx::Timer->new($self, $self->{layer_height_edit_timer_id}); - EVT_TIMER($self, $self->{layer_height_edit_timer_id}, sub { - my ($self, $event) = @_; - return if $self->_layer_height_edited != 1; -#============================================================================================================================== - return if Slic3r::GUI::_3DScene::get_layers_editing_last_object_id($self) == -1; -#============================================================================================================================== - $self->_variable_layer_thickness_action(undef); - }); - return $self; } @@ -290,7 +284,10 @@ sub new { sub Destroy { my ($self) = @_; - $self->{layer_height_edit_timer}->Stop; +#============================================================================================================================== + Slic3r::GUI::_3DScene::stop_timer($self); +# $self->{layer_height_edit_timer}->Stop; +#============================================================================================================================== $self->DestroyGL; #============================================================================================================================== Slic3r::GUI::_3DScene::remove_canvas($self); @@ -426,66 +423,33 @@ sub _variable_layer_thickness_reset_rect_viewport { # # Outside the bar. # -1000.; #} -#============================================================================================================================== - -sub _variable_layer_thickness_action { - my ($self, $mouse_event, $do_modification) = @_; -#============================================================================================================================== - my $object_idx_selected = Slic3r::GUI::_3DScene::get_layers_editing_last_object_id($self); - # A volume is selected. Test, whether hovering over a layer thickness bar. - return if ($object_idx_selected == -1); +# +#sub _variable_layer_thickness_action { +# my ($self, $mouse_event, $do_modification) = @_; +# # A volume is selected. Test, whether hovering over a layer thickness bar. # return if $self->{layer_height_edit_last_object_id} == -1; -#============================================================================================================================== - if (defined($mouse_event)) { - my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen; -#============================================================================================================================== - Slic3r::GUI::_3DScene::set_layers_editing_last_z($self, unscale($self->{print}->get_object($object_idx_selected)->size->z) - * ($bar_bottom - $mouse_event->GetY - 1.) / ($bar_bottom - $bar_top)); - Slic3r::GUI::_3DScene::set_layers_editing_last_action($self, $mouse_event->ShiftDown ? ($mouse_event->RightIsDown ? 3 : 2) : ($mouse_event->RightIsDown ? 0 : 1)); +# if (defined($mouse_event)) { +# my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen; # $self->{layer_height_edit_last_z} = unscale($self->{print}->get_object($self->{layer_height_edit_last_object_id})->size->z) # * ($bar_bottom - $mouse_event->GetY - 1.) / ($bar_bottom - $bar_top); # $self->{layer_height_edit_last_action} = $mouse_event->ShiftDown ? ($mouse_event->RightIsDown ? 3 : 2) : ($mouse_event->RightIsDown ? 0 : 1); -#============================================================================================================================== - } - # Mark the volume as modified, so Print will pick its layer height profile? Where to mark it? - # Start a timer to refresh the print? schedule_background_process() ? - # The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself. -#============================================================================================================================== - $self->{print}->get_object($object_idx_selected)->adjust_layer_height_profile( - Slic3r::GUI::_3DScene::get_layers_editing_last_z($self), - Slic3r::GUI::_3DScene::get_layers_editing_strength($self), - Slic3r::GUI::_3DScene::get_layers_editing_band_width($self), - Slic3r::GUI::_3DScene::get_layers_editing_last_action($self)); +# } +# # Mark the volume as modified, so Print will pick its layer height profile? Where to mark it? +# # Start a timer to refresh the print? schedule_background_process() ? +# # The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself. # $self->{print}->get_object($self->{layer_height_edit_last_object_id})->adjust_layer_height_profile( # $self->{layer_height_edit_last_z}, # $self->{layer_height_edit_strength}, # $self->{layer_height_edit_band_width}, # $self->{layer_height_edit_last_action}); -#============================================================================================================================== - - #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MERGE FROM SCENE_MANIPULATORS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - # searches the id of the first volume of the selected object - my $volume_idx = 0; - for my $i (0..$object_idx_selected - 1) { - my $obj = $self->{print}->get_object($i); - for my $j (0..$obj->region_volumes_count - 1) { - $volume_idx += scalar @{$obj->get_region_volumes($j)}; - } - } - #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MERGE FROM SCENE_MANIPULATORS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -#============================================================================================================================== - #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MERGE FROM SCENE_MANIPULATORS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - $self->volumes->[$volume_idx]->generate_layer_height_texture($self->{print}->get_object($object_idx_selected), 1); -# $self->volumes->[$object_idx_selected]->generate_layer_height_texture($self->{print}->get_object($object_idx_selected), 1); - #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MERGE FROM SCENE_MANIPULATORS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# # $self->volumes->[$self->{layer_height_edit_last_object_id}]->generate_layer_height_texture( # $self->{print}->get_object($self->{layer_height_edit_last_object_id}), 1); +# $self->Refresh; +# # Automatic action on mouse down with the same coordinate. +# $self->{layer_height_edit_timer}->Start(100, wxTIMER_CONTINUOUS); +#} #============================================================================================================================== - $self->Refresh; - # Automatic action on mouse down with the same coordinate. - $self->{layer_height_edit_timer}->Start(100, wxTIMER_CONTINUOUS); -} sub mouse_event { my ($self, $e) = @_; @@ -519,24 +483,32 @@ sub mouse_event { # on a volume or not. #============================================================================================================================== my $volume_idx = Slic3r::GUI::_3DScene::get_hover_volume_id($self); + Slic3r::GUI::_3DScene::set_layers_editing_state($self, 0); # my $volume_idx = $self->_hover_volume_idx // -1; +# $self->_layer_height_edited(0); #============================================================================================================================== - $self->_layer_height_edited(0); #============================================================================================================================== if ($object_idx_selected != -1 && Slic3r::GUI::_3DScene::bar_rect_contains($self, $e->GetX, $e->GetY)) { # if ($object_idx_selected != -1 && $self->_variable_layer_thickness_bar_rect_mouse_inside($e)) { #============================================================================================================================== # A volume is selected and the mouse is hovering over a layer thickness bar. # Start editing the layer height. - $self->_layer_height_edited(1); - $self->_variable_layer_thickness_action($e); +#============================================================================================================================== + Slic3r::GUI::_3DScene::set_layers_editing_state($self, 1); + Slic3r::GUI::_3DScene::perform_layer_editing_action($self, $e->GetY, $e->ShiftDown, $e->RightIsDown); +# $self->_layer_height_edited(1); +# $self->_variable_layer_thickness_action($e); +#============================================================================================================================== #============================================================================================================================== } elsif ($object_idx_selected != -1 && Slic3r::GUI::_3DScene::reset_rect_contains($self, $e->GetX, $e->GetY)) { # } elsif ($object_idx_selected != -1 && $self->_variable_layer_thickness_reset_rect_mouse_inside($e)) { #============================================================================================================================== $self->{print}->get_object($object_idx_selected)->reset_layer_height_profile; # Index 2 means no editing, just wait for mouse up event. - $self->_layer_height_edited(2); +#============================================================================================================================== + Slic3r::GUI::_3DScene::set_layers_editing_state($self, 2); +# $self->_layer_height_edited(2); +#============================================================================================================================== $self->Refresh; $self->Update; } else { @@ -599,7 +571,10 @@ sub mouse_event { } } } - } elsif ($e->Dragging && $e->LeftIsDown && ! $self->_layer_height_edited && defined($self->_drag_volume_idx)) { +#============================================================================================================================== + } elsif ($e->Dragging && $e->LeftIsDown && (Slic3r::GUI::_3DScene::get_layers_editing_state($self) == 0) && defined($self->_drag_volume_idx)) { +# } elsif ($e->Dragging && $e->LeftIsDown && ! $self->_layer_height_edited && defined($self->_drag_volume_idx)) { +#============================================================================================================================== # Get new position at the same Z of the initial click point. my $cur_pos = Slic3r::Linef3->new( $self->mouse_to_3d($e->GetX, $e->GetY, 0), @@ -635,8 +610,13 @@ sub mouse_event { $self->Refresh; $self->Update; } elsif ($e->Dragging) { - if ($self->_layer_height_edited && $object_idx_selected != -1) { - $self->_variable_layer_thickness_action($e) if ($self->_layer_height_edited == 1); +#============================================================================================================================== + if ((Slic3r::GUI::_3DScene::get_layers_editing_state($self) > 0) && ($object_idx_selected != -1)) { + Slic3r::GUI::_3DScene::perform_layer_editing_action($self, $e->GetY, $e->ShiftDown, $e->RightIsDown) if (Slic3r::GUI::_3DScene::get_layers_editing_state($self) == 1); + +# if ($self->_layer_height_edited && $object_idx_selected != -1) { +# $self->_variable_layer_thickness_action($e) if ($self->_layer_height_edited == 1); +#============================================================================================================================== } elsif ($e->LeftIsDown) { # if dragging over blank area with left button, rotate if (defined $self->_drag_start_pos) { @@ -686,9 +666,14 @@ sub mouse_event { $self->_drag_start_xy($pos); } } elsif ($e->LeftUp || $e->MiddleUp || $e->RightUp) { - if ($self->_layer_height_edited) { - $self->_layer_height_edited(undef); - $self->{layer_height_edit_timer}->Stop; +#============================================================================================================================== + if (Slic3r::GUI::_3DScene::get_layers_editing_state($self) > 0) { + Slic3r::GUI::_3DScene::set_layers_editing_state($self, 0); + Slic3r::GUI::_3DScene::stop_timer($self); +# if ($self->_layer_height_edited) { +# $self->_layer_height_edited(undef); +# $self->{layer_height_edit_timer}->Stop; +#============================================================================================================================== $self->on_model_update->() if ($object_idx_selected != -1 && $self->on_model_update); } elsif ($self->on_move && defined($self->_drag_volume_idx) && $self->_dragged) { diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index c56e64c6c..8b6b3773f 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -184,6 +184,10 @@ public: void reset_layer_height_profile(); +//############################################################################################################################################ + void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action); +//############################################################################################################################################ + // Collect the slicing parameters, to be used by variable layer thickness algorithm, // by the interactive layer height editor and by the printing process itself. // The slicing parameters are dependent on various configuration values diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index b0341db16..9d0fe03fb 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -4,6 +4,9 @@ #include "Geometry.hpp" #include "SupportMaterial.hpp" #include "Surface.hpp" +//############################################################################################################################################ +#include "Slicing.hpp" +//############################################################################################################################################ #include #include @@ -1961,4 +1964,14 @@ void PrintObject::reset_layer_height_profile() this->model_object()->layer_height_profile_valid = false; } +//############################################################################################################################################ +void PrintObject::adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action) +{ + update_layer_height_profile(_model_object->layer_height_profile); + Slic3r::adjust_layer_height_profile(slicing_parameters(), _model_object->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action)); + _model_object->layer_height_profile_valid = true; + layer_height_profile_valid = false; +} +//############################################################################################################################################ + } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 80102cc50..cb87a43d2 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -2015,6 +2015,16 @@ unsigned int _3DScene::get_layers_editing_z_texture_id(wxGLCanvas* canvas) return s_canvas_mgr.get_layers_editing_z_texture_id(canvas); } +unsigned int _3DScene::get_layers_editing_state(wxGLCanvas* canvas) +{ + return s_canvas_mgr.get_layers_editing_state(canvas); +} + +void _3DScene::set_layers_editing_state(wxGLCanvas* canvas, unsigned int state) +{ + s_canvas_mgr.set_layers_editing_state(canvas, state); +} + float _3DScene::get_layers_editing_band_width(wxGLCanvas* canvas) { return s_canvas_mgr.get_layers_editing_band_width(canvas); @@ -2140,6 +2150,21 @@ void _3DScene::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float lef s_canvas_mgr.render_texture(canvas, tex_id, left, right, bottom, top); } +void _3DScene::start_timer(wxGLCanvas* canvas) +{ + s_canvas_mgr.start_timer(canvas); +} + +void _3DScene::stop_timer(wxGLCanvas* canvas) +{ + s_canvas_mgr.stop_timer(canvas); +} + +void _3DScene::perform_layer_editing_action(wxGLCanvas* canvas, int y, bool shift_down, bool right_down) +{ + s_canvas_mgr.perform_layer_editing_action(canvas, y, shift_down, right_down); +} + void _3DScene::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback) { s_canvas_mgr.register_on_viewport_changed_callback(canvas, callback); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 45fdbbb41..22a5e8d61 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -619,6 +619,9 @@ public: static unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas); + static unsigned int get_layers_editing_state(wxGLCanvas* canvas); + static void set_layers_editing_state(wxGLCanvas* canvas, unsigned int state); + static float get_layers_editing_band_width(wxGLCanvas* canvas); static void set_layers_editing_band_width(wxGLCanvas* canvas, float band_width); @@ -655,6 +658,10 @@ public: static void render_volumes(wxGLCanvas* canvas, bool fake_colors); static void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top); + static void start_timer(wxGLCanvas* canvas); + static void stop_timer(wxGLCanvas* canvas); + static void perform_layer_editing_action(wxGLCanvas* canvas, int y, bool shift_down, bool right_down); + static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); // static void _glew_init(); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 4946ae807..c9b31a94c 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -589,7 +590,8 @@ GLCanvas3D::LayersEditing::GLTextureData::GLTextureData(unsigned int id, int wid } GLCanvas3D::LayersEditing::LayersEditing() - : m_use_legacy_opengl(false) + : m_state(Unknown) + , m_use_legacy_opengl(false) , m_enabled(false) , m_z_texture_id(0) , m_band_width(2.0f) @@ -638,6 +640,16 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, return true; } +GLCanvas3D::LayersEditing::EState GLCanvas3D::LayersEditing::get_state() const +{ + return m_state; +} + +void GLCanvas3D::LayersEditing::set_state(GLCanvas3D::LayersEditing::EState state) +{ + m_state = state; +} + bool GLCanvas3D::LayersEditing::is_allowed() const { return m_use_legacy_opengl && m_shader.is_initialized(); @@ -718,8 +730,8 @@ void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObje if (!m_enabled) return; - const Rect& bar_rect = _get_bar_rect_viewport(canvas); - const Rect& reset_rect = _get_reset_rect_viewport(canvas); + const Rect& bar_rect = get_bar_rect_viewport(canvas); + const Rect& reset_rect = get_reset_rect_viewport(canvas); ::glDisable(GL_DEPTH_TEST); @@ -747,13 +759,13 @@ const GLShader* GLCanvas3D::LayersEditing::get_shader() const float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas) { const Point& mouse_pos = canvas.get_local_mouse_position(); - const Rect& bar_rect = _get_bar_rect_screen(canvas); + const Rect& rect = get_bar_rect_screen(canvas); float x = (float)mouse_pos.x; float y = (float)mouse_pos.y; - float t = bar_rect.get_top(); - float b = bar_rect.get_bottom(); + float t = rect.get_top(); + float b = rect.get_bottom(); - return ((bar_rect.get_left() <= x) && (x <= bar_rect.get_right()) && (t <= y) && (y <= b)) ? + return ((rect.get_left() <= x) && (x <= rect.get_right()) && (t <= y) && (y <= b)) ? // Inside the bar. (b - y - 1.0f) / (b - t - 1.0f) : // Outside the bar. @@ -777,16 +789,59 @@ int GLCanvas3D::LayersEditing::get_first_selected_object_id(const GLVolumeCollec bool GLCanvas3D::LayersEditing::bar_rect_contains(const GLCanvas3D& canvas, float x, float y) { - const Rect& rect = _get_bar_rect_screen(canvas); + const Rect& rect = get_bar_rect_screen(canvas); return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom()); } bool GLCanvas3D::LayersEditing::reset_rect_contains(const GLCanvas3D& canvas, float x, float y) { - const Rect& rect = _get_reset_rect_screen(canvas); + const Rect& rect = get_reset_rect_screen(canvas); return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom()); } +Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) +{ + const Size& cnv_size = canvas.get_canvas_size(); + float w = (float)cnv_size.get_width(); + float h = (float)cnv_size.get_height(); + + return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0.0f, w, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT); +} + +Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas) +{ + const Size& cnv_size = canvas.get_canvas_size(); + float w = (float)cnv_size.get_width(); + float h = (float)cnv_size.get_height(); + + return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, w, h); +} + +Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) +{ + const Size& cnv_size = canvas.get_canvas_size(); + float half_w = 0.5f * (float)cnv_size.get_width(); + float half_h = 0.5f * (float)cnv_size.get_height(); + + float zoom = canvas.get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom); +} + +Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas) +{ + const Size& cnv_size = canvas.get_canvas_size(); + float half_w = 0.5f * (float)cnv_size.get_width(); + float half_h = 0.5f * (float)cnv_size.get_height(); + + float zoom = canvas.get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); +} + + bool GLCanvas3D::LayersEditing::_is_initialized() const { return m_shader.is_initialized(); @@ -969,48 +1024,6 @@ GLCanvas3D::LayersEditing::GLTextureData GLCanvas3D::LayersEditing::_load_textur return GLTextureData((unsigned int)tex_id, width, height); } -Rect GLCanvas3D::LayersEditing::_get_bar_rect_screen(const GLCanvas3D& canvas) -{ - const Size& cnv_size = canvas.get_canvas_size(); - float w = (float)cnv_size.get_width(); - float h = (float)cnv_size.get_height(); - - return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0.0f, w, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT); -} - -Rect GLCanvas3D::LayersEditing::_get_reset_rect_screen(const GLCanvas3D& canvas) -{ - const Size& cnv_size = canvas.get_canvas_size(); - float w = (float)cnv_size.get_width(); - float h = (float)cnv_size.get_height(); - - return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, w, h); -} - -Rect GLCanvas3D::LayersEditing::_get_bar_rect_viewport(const GLCanvas3D& canvas) -{ - const Size& cnv_size = canvas.get_canvas_size(); - float half_w = 0.5f * (float)cnv_size.get_width(); - float half_h = 0.5f * (float)cnv_size.get_height(); - - float zoom = canvas.get_camera_zoom(); - float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - - return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom); -} - -Rect GLCanvas3D::LayersEditing::_get_reset_rect_viewport(const GLCanvas3D& canvas) -{ - const Size& cnv_size = canvas.get_canvas_size(); - float half_w = 0.5f * (float)cnv_size.get_width(); - float half_h = 0.5f * (float)cnv_size.get_height(); - - float zoom = canvas.get_camera_zoom(); - float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - - return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); -} - GLCanvas3D::Mouse::Mouse() : m_dragging(false) { @@ -1039,6 +1052,7 @@ void GLCanvas3D::Mouse::set_position(const Pointf& position) GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) : m_canvas(canvas) , m_context(context) + , m_timer(nullptr) , m_volumes(nullptr) , m_config(nullptr) , m_print(nullptr) @@ -1051,10 +1065,18 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) , m_shader_enabled(false) , m_multisample_allowed(false) { + if (m_canvas != nullptr) + m_timer = new wxTimer(m_canvas); } GLCanvas3D::~GLCanvas3D() { + if (m_timer != nullptr) + { + delete m_timer; + m_timer = nullptr; + } + _deregister_callbacks(); } @@ -1585,6 +1607,17 @@ unsigned int GLCanvas3D::get_layers_editing_z_texture_id() const return m_layers_editing.get_z_texture_id(); } +unsigned int GLCanvas3D::get_layers_editing_state() const +{ + return (unsigned int)m_layers_editing.get_state(); +} + +void GLCanvas3D::set_layers_editing_state(unsigned int state) +{ + if (state < (unsigned int)LayersEditing::Num_States) + m_layers_editing.set_state((LayersEditing::EState)state); +} + float GLCanvas3D::get_layers_editing_band_width() const { return m_layers_editing.get_band_width(); @@ -1833,6 +1866,14 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) _refresh_if_shown_on_screen(); } +void GLCanvas3D::on_timer(wxTimerEvent& evt) +{ + if (get_layers_editing_state() != 1) + return; + + _perform_layer_editing_action(); +} + Size GLCanvas3D::get_canvas_size() const { int w = 0; @@ -1853,6 +1894,28 @@ Point GLCanvas3D::get_local_mouse_position() const return Point(mouse_pos.x, mouse_pos.y); } +void GLCanvas3D::start_timer() +{ + if (m_timer != nullptr) + m_timer->Start(100, wxTIMER_CONTINUOUS); +} + +void GLCanvas3D::stop_timer() +{ + if (m_timer != nullptr) + m_timer->Stop(); +} + +void GLCanvas3D::perform_layer_editing_action(int y, bool shift_down, bool right_down) +{ + wxMouseEvent evt; + evt.m_y = (wxCoord)y; + evt.SetShiftDown(shift_down); + evt.SetRightDown(right_down); + + _perform_layer_editing_action(&evt); +} + void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox) { // Calculate the zoom factor needed to adjust viewport to bounding box. @@ -2238,5 +2301,53 @@ void GLCanvas3D::_render_layer_editing_overlay() const m_layers_editing.render(*this, *print_object, *volume); } +void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt) +{ + int object_idx_selected = get_layers_editing_last_object_id(); + if (object_idx_selected == -1) + return; + + if ((m_volumes == nullptr) || (m_print == nullptr)) + return; + + PrintObject* selected_obj = m_print->get_object(object_idx_selected); + if (selected_obj == nullptr) + return; + + // A volume is selected. Test, whether hovering over a layer thickness bar. + if (evt != nullptr) + { + const Rect& rect = LayersEditing::get_bar_rect_screen(*this); + float b = rect.get_bottom(); + set_layers_editing_last_z(unscale(selected_obj->size.z) * (b - evt->GetY() - 1.0f) / (b - rect.get_top())); + set_layers_editing_last_action(evt->ShiftDown() ? (evt->RightIsDown() ? 3 : 2) : (evt->RightIsDown() ? 0 : 1)); + } + + // Mark the volume as modified, so Print will pick its layer height profile ? Where to mark it ? + // Start a timer to refresh the print ? schedule_background_process() ? + // The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself. + selected_obj->adjust_layer_height_profile(get_layers_editing_last_z(), get_layers_editing_strength(), get_layers_editing_band_width(), get_layers_editing_last_action()); + + // searches the id of the first volume of the selected object + int volume_idx = 0; + for (int i = 0; i < object_idx_selected; ++i) + { + PrintObject* obj = m_print->get_object(i); + if (obj != nullptr) + { + for (int j = 0; j < (int)obj->region_volumes.size(); ++j) + { + volume_idx += (int)obj->region_volumes[j].size(); + } + } + } + + m_volumes->volumes[volume_idx]->generate_layer_height_texture(selected_obj, 1); + _refresh_if_shown_on_screen(); + + // Automatic action on mouse down with the same coordinate. + start_timer(); +} + } // namespace GUI } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 30d219cff..bbb5880f1 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -7,10 +7,12 @@ class wxGLCanvas; class wxGLContext; +class wxTimer; class wxSizeEvent; class wxIdleEvent; class wxKeyEvent; class wxMouseEvent; +class wxTimerEvent; namespace Slic3r { @@ -202,6 +204,16 @@ public: class LayersEditing { + public: + enum EState : unsigned char + { + Unknown, + Editing, + Completed, + Num_States + }; + + private: struct GLTextureData { unsigned int id; @@ -212,6 +224,7 @@ public: GLTextureData(unsigned int id, int width, int height); }; + EState m_state; bool m_use_legacy_opengl; bool m_enabled; Shader m_shader; @@ -230,6 +243,9 @@ public: bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); + EState get_state() const; + void set_state(EState state); + bool is_allowed() const; void set_use_legacy_opengl(bool use_legacy_opengl); @@ -261,6 +277,10 @@ public: static int get_first_selected_object_id(const GLVolumeCollection& volumes, unsigned int objects_count); static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y); static bool reset_rect_contains(const GLCanvas3D& canvas, float x, float y); + static Rect get_bar_rect_screen(const GLCanvas3D& canvas); + static Rect get_reset_rect_screen(const GLCanvas3D& canvas); + static Rect get_bar_rect_viewport(const GLCanvas3D& canvas); + static Rect get_reset_rect_viewport(const GLCanvas3D& canvas); private: bool _is_initialized() const; @@ -269,10 +289,6 @@ public: void _render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const; void _render_profile(const PrintObject& print_object, const Rect& bar_rect) const; static GLTextureData _load_texture_from_file(const std::string& filename); - static Rect _get_bar_rect_screen(const GLCanvas3D& canvas); - static Rect _get_reset_rect_screen(const GLCanvas3D& canvas); - static Rect _get_bar_rect_viewport(const GLCanvas3D& canvas); - static Rect _get_reset_rect_viewport(const GLCanvas3D& canvas); }; class Mouse @@ -293,6 +309,7 @@ public: private: wxGLCanvas* m_canvas; wxGLContext* m_context; + wxTimer* m_timer; Camera m_camera; Bed m_bed; Axes m_axes; @@ -402,6 +419,9 @@ public: unsigned int get_layers_editing_z_texture_id() const; + unsigned int get_layers_editing_state() const; + void set_layers_editing_state(unsigned int state); + float get_layers_editing_band_width() const; void set_layers_editing_band_width(float band_width); @@ -444,10 +464,15 @@ public: void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); void on_mouse_wheel(wxMouseEvent& evt); + void on_timer(wxTimerEvent& evt); Size get_canvas_size() const; Point get_local_mouse_position() const; + void start_timer(); + void stop_timer(); + void perform_layer_editing_action(int y, bool shift_down, bool right_down); + private: void _zoom_to_bounding_box(const BoundingBoxf3& bbox); float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const; @@ -466,6 +491,8 @@ private: void _render_warning_texture() const; void _render_legend_texture() const; void _render_layer_editing_overlay() const; + + void _perform_layer_editing_action(wxMouseEvent* evt = nullptr); }; } // namespace GUI diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 16398b6d6..2d692cc27 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -76,6 +77,7 @@ bool GLCanvas3DManager::add(wxGLCanvas* canvas, wxGLContext* context) 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); }); m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D)); @@ -481,6 +483,19 @@ unsigned int GLCanvas3DManager::get_layers_editing_z_texture_id(wxGLCanvas* canv return (it != m_canvases.end()) ? it->second->get_layers_editing_z_texture_id() : 0; } +unsigned int GLCanvas3DManager::get_layers_editing_state(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->get_layers_editing_state() : 0; +} + +void GLCanvas3DManager::set_layers_editing_state(wxGLCanvas* canvas, unsigned int state) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->set_layers_editing_state(state); +} + float GLCanvas3DManager::get_layers_editing_band_width(wxGLCanvas* canvas) const { CanvasesMap::const_iterator it = _get_canvas(canvas); @@ -649,6 +664,27 @@ void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, it->second->render_texture(tex_id, left, right, bottom, top); } +void GLCanvas3DManager::start_timer(wxGLCanvas* canvas) +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->start_timer(); +} + +void GLCanvas3DManager::stop_timer(wxGLCanvas* canvas) +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->stop_timer(); +} + +void GLCanvas3DManager::perform_layer_editing_action(wxGLCanvas* canvas, int y, bool shift_down, bool right_down) +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->perform_layer_editing_action(y, shift_down, right_down); +} + void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 301650990..1cb4c316e 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -119,6 +119,9 @@ public: unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas) const; + unsigned int get_layers_editing_state(wxGLCanvas* canvas) const; + void set_layers_editing_state(wxGLCanvas* canvas, unsigned int state); + float get_layers_editing_band_width(wxGLCanvas* canvas) const; void set_layers_editing_band_width(wxGLCanvas* canvas, float band_width); @@ -155,6 +158,10 @@ public: void render_volumes(wxGLCanvas* canvas, bool fake_colors) const; void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const; + void start_timer(wxGLCanvas* canvas); + void stop_timer(wxGLCanvas* canvas); + void perform_layer_editing_action(wxGLCanvas* canvas, int y, bool shift_down, bool right_down); + void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); private: diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index b155c0cb0..0ffe3677b 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -578,6 +578,21 @@ get_layers_editing_z_texture_id(canvas) OUTPUT: RETVAL +unsigned int +get_layers_editing_state(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::get_layers_editing_state((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + +void +set_layers_editing_state(canvas, state) + SV *canvas; + unsigned int state; + CODE: + _3DScene::set_layers_editing_state((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), state); + float get_layers_editing_band_width(canvas) SV *canvas; @@ -768,6 +783,27 @@ render_texture(canvas, tex_id, left, right, bottom, top) CODE: _3DScene::render_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), tex_id, left, right, bottom, top); +void +start_timer(canvas) + SV *canvas; + CODE: + _3DScene::start_timer((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + +void +stop_timer(canvas) + SV *canvas; + CODE: + _3DScene::stop_timer((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + +void +perform_layer_editing_action(canvas, y, shift_down, right_down) + SV *canvas; + int y; + bool shift_down; + bool right_down; + CODE: + _3DScene::perform_layer_editing_action((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), y, shift_down, right_down); + void register_on_viewport_changed_callback(canvas, callback) SV *canvas; diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index f21923b41..60b589336 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -122,14 +122,16 @@ _constant() RETVAL.push_back(slicing_params.layer_height); %}; - void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action) - %code%{ - THIS->update_layer_height_profile(THIS->model_object()->layer_height_profile); - adjust_layer_height_profile( - THIS->slicing_parameters(), THIS->model_object()->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action)); - THIS->model_object()->layer_height_profile_valid = true; - THIS->layer_height_profile_valid = false; - %}; +//################################################################################################################################################################### +// void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action) +// %code%{ +// THIS->update_layer_height_profile(THIS->model_object()->layer_height_profile); +// adjust_layer_height_profile( +// THIS->slicing_parameters(), THIS->model_object()->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action)); +// THIS->model_object()->layer_height_profile_valid = true; +// THIS->layer_height_profile_valid = false; +// %}; +//################################################################################################################################################################### void reset_layer_height_profile();