From bf2fd5457822d6774fc4ddb1c8954474c67fb775 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 8 Jun 2018 09:40:00 +0200 Subject: [PATCH] reload_scene method of 3D class moved to c++ --- lib/Slic3r/GUI/Plater.pm | 92 ++++++++---- lib/Slic3r/GUI/Plater/3D.pm | 187 ++++++++++-------------- xs/src/libslic3r/Utils.hpp | 1 + xs/src/libslic3r/utils.cpp | 5 + xs/src/slic3r/GUI/3DScene.cpp | 20 +++ xs/src/slic3r/GUI/3DScene.hpp | 7 + xs/src/slic3r/GUI/GLCanvas3D.cpp | 105 +++++++++++++ xs/src/slic3r/GUI/GLCanvas3D.hpp | 12 ++ xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 27 ++++ xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 7 + xs/xsp/GUI_3DScene.xsp | 29 ++++ 11 files changed, 355 insertions(+), 137 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 82249bfd4..9dad79807 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -128,23 +128,10 @@ sub new { Slic3r::GUI::_3DScene::register_on_decrease_objects_callback($self->{canvas3D}, sub { $self->decrease() }); Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { $self->remove() }); Slic3r::GUI::_3DScene::register_on_instance_moved_callback($self->{canvas3D}, $on_instances_moved); -# $self->{canvas3D}->set_on_double_click($on_double_click); -# $self->{canvas3D}->set_on_right_click(sub { $on_right_click->($self->{canvas3D}, @_); }); -# $self->{canvas3D}->set_on_arrange(sub { $self->arrange }); -# $self->{canvas3D}->set_on_rotate_object_left(sub { $self->rotate(-45, Z, 'relative') }); -# $self->{canvas3D}->set_on_rotate_object_right(sub { $self->rotate( 45, Z, 'relative') }); -# $self->{canvas3D}->set_on_scale_object_uniformly(sub { $self->changescale(undef) }); -# $self->{canvas3D}->set_on_increase_objects(sub { $self->increase() }); -# $self->{canvas3D}->set_on_decrease_objects(sub { $self->decrease() }); -# $self->{canvas3D}->set_on_remove_object(sub { $self->remove() }); -# $self->{canvas3D}->set_on_instances_moved($on_instances_moved); -#============================================================================================================================== - $self->{canvas3D}->set_on_enable_action_buttons($enable_action_buttons); -#=================================================================================================================================== + Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons); Slic3r::GUI::_3DScene::enable_shader($self->{canvas3D}, 1); Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($self->{canvas3D}, 1); -# $self->{canvas3D}->use_plain_shader(1); -#=================================================================================================================================== + Slic3r::GUI::_3DScene::register_on_wipe_tower_moved_callback($self->{canvas3D}, sub { my ($x, $y) = @_; my $cfg = Slic3r::Config->new; @@ -153,14 +140,6 @@ sub new { $self->GetFrame->{options_tabs}{print}->load_config($cfg); }); -# $self->{canvas3D}->set_on_wipe_tower_moved(sub { -# my ($new_pos_3f) = @_; -# my $cfg = Slic3r::Config->new; -# $cfg->set('wipe_tower_x', $new_pos_3f->x); -# $cfg->set('wipe_tower_y', $new_pos_3f->y); -# $self->GetFrame->{options_tabs}{print}->load_config($cfg); -# }); -#============================================================================================================================== Slic3r::GUI::_3DScene::register_on_model_update_callback($self->{canvas3D}, sub { if (wxTheApp->{app_config}->get("background_processing")) { $self->schedule_background_process; @@ -172,6 +151,27 @@ sub new { Slic3r::GUI::_3DScene::register_on_viewport_changed_callback($self->{canvas3D}, sub { Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{preview3D}->canvas, $self->{canvas3D}); }); +# $self->{canvas3D}->set_on_double_click($on_double_click); +# $self->{canvas3D}->set_on_right_click(sub { $on_right_click->($self->{canvas3D}, @_); }); +# $self->{canvas3D}->set_on_arrange(sub { $self->arrange }); +# $self->{canvas3D}->set_on_rotate_object_left(sub { $self->rotate(-45, Z, 'relative') }); +# $self->{canvas3D}->set_on_rotate_object_right(sub { $self->rotate( 45, Z, 'relative') }); +# $self->{canvas3D}->set_on_scale_object_uniformly(sub { $self->changescale(undef) }); +# $self->{canvas3D}->set_on_increase_objects(sub { $self->increase() }); +# $self->{canvas3D}->set_on_decrease_objects(sub { $self->decrease() }); +# $self->{canvas3D}->set_on_remove_object(sub { $self->remove() }); +# $self->{canvas3D}->set_on_instances_moved($on_instances_moved); +# $self->{canvas3D}->set_on_enable_action_buttons($enable_action_buttons); +# $self->{canvas3D}->use_plain_shader(1); +# +# $self->{canvas3D}->set_on_wipe_tower_moved(sub { +# my ($new_pos_3f) = @_; +# my $cfg = Slic3r::Config->new; +# $cfg->set('wipe_tower_x', $new_pos_3f->x); +# $cfg->set('wipe_tower_y', $new_pos_3f->y); +# $self->GetFrame->{options_tabs}{print}->load_config($cfg); +# }); +# # $self->{canvas3D}->set_on_model_update(sub { # if (wxTheApp->{app_config}->get("background_processing")) { # $self->schedule_background_process; @@ -229,7 +229,20 @@ sub new { #============================================================================================================================== } +#============================================================================================================================== + if ($preview == $self->{canvas3D}) { + if (Slic3r::GUI::_3DScene::is_reload_delayed($self->{canvas3D})) { + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1); + } + } + else { +#============================================================================================================================== $preview->OnActivate if $preview->can('OnActivate'); +#============================================================================================================================== + } +#============================================================================================================================== }); # toolbar for object manipulation @@ -1795,7 +1808,12 @@ sub update { } $self->{canvas}->reload_scene if $self->{canvas}; - $self->{canvas3D}->reload_scene if $self->{canvas3D}; +#============================================================================================================================== + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0); +# $self->{canvas3D}->reload_scene if $self->{canvas3D}; +#============================================================================================================================== $self->{preview3D}->reset_gcode_preview_data if $self->{preview3D}; $self->{preview3D}->reload_print if $self->{preview3D}; } @@ -1933,14 +1951,29 @@ sub list_item_selected { my $obj_idx = $event->GetIndex; $self->select_object($obj_idx); $self->{canvas}->Refresh; - $self->{canvas3D}->update_volumes_selection if $self->{canvas3D}; #============================================================================================================================== - Slic3r::GUI::_3DScene::render($self->{canvas3D}) if $self->{canvas3D}; + if ($self->{canvas3D}) { + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::render($self->{canvas3D}); + } +# $self->{canvas3D}->update_volumes_selection if $self->{canvas3D}; # $self->{canvas3D}->Render if $self->{canvas3D}; #============================================================================================================================== undef $self->{_lecursor}; } +#============================================================================================================================== +sub collect_selections { + my ($self) = @_; + my $selections = []; + foreach my $o (@{$self->{objects}}) { + push(@$selections, $o->selected); + } + return $selections; +} +#============================================================================================================================== + sub list_item_activated { my ($self, $event, $obj_idx) = @_; @@ -2036,7 +2069,12 @@ sub object_settings_dialog { $self->{print}->reload_object($obj_idx); $self->schedule_background_process; $self->{canvas}->reload_scene if $self->{canvas}; - $self->{canvas3D}->reload_scene if $self->{canvas3D}; +#============================================================================================================================== + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0); +# $self->{canvas3D}->reload_scene if $self->{canvas3D}; +#============================================================================================================================== } else { $self->resume_background_process; } diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm index 28bc6490c..fdd55cdd8 100644 --- a/lib/Slic3r/GUI/Plater/3D.pm +++ b/lib/Slic3r/GUI/Plater/3D.pm @@ -13,7 +13,6 @@ use base qw(Slic3r::GUI::3DScene Class::Accessor); use Wx::Locale gettext => 'L'; #============================================================================================================================== -__PACKAGE__->mk_accessors(qw(on_enable_action_buttons)); #__PACKAGE__->mk_accessors(qw( # on_arrange on_rotate_object_left on_rotate_object_right on_scale_object_uniformly # on_remove_object on_increase_objects on_decrease_objects on_enable_action_buttons)); @@ -33,9 +32,9 @@ sub new { # $self->enable_moving(1); # $self->select_by('object'); # $self->drag_by('instance'); +# +# $self->{objects} = $objects; #============================================================================================================================== - - $self->{objects} = $objects; $self->{model} = $model; #============================================================================================================================== # $self->{print} = $print; @@ -50,9 +49,9 @@ sub new { #============================================================================================================================== # $self->{on_instances_moved} = sub {}; # $self->{on_wipe_tower_moved} = sub {}; +# +# $self->{objects_volumes_idxs} = []; #============================================================================================================================== - - $self->{objects_volumes_idxs} = []; #============================================================================================================================== Slic3r::GUI::_3DScene::register_on_select_callback($self, sub { @@ -205,125 +204,93 @@ sub set_on_select_object { # my ($self, $cb) = @_; # $self->on_model_update($cb); #} -#============================================================================================================================== - -sub set_on_enable_action_buttons { - my ($self, $cb) = @_; - $self->on_enable_action_buttons($cb); -#============================================================================================================================== - Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self, $cb); -#============================================================================================================================== -} - -sub update_volumes_selection { - my ($self) = @_; - - foreach my $obj_idx (0..$#{$self->{model}->objects}) { - if ($self->{objects}[$obj_idx]->selected) { - my $volume_idxs = $self->{objects_volumes_idxs}->[$obj_idx]; -#============================================================================================================================== - Slic3r::GUI::_3DScene::select_volume($self, $_) for @{$volume_idxs}; +# +#sub set_on_enable_action_buttons { +# my ($self, $cb) = @_; +# $self->on_enable_action_buttons($cb); +#} +# +#sub update_volumes_selection { +# my ($self) = @_; +# +# foreach my $obj_idx (0..$#{$self->{model}->objects}) { +# if ($self->{objects}[$obj_idx]->selected) { +# my $volume_idxs = $self->{objects_volumes_idxs}->[$obj_idx]; # $self->select_volume($_) for @{$volume_idxs}; -#============================================================================================================================== - } - } -} - -sub reload_scene { - my ($self, $force) = @_; - -#============================================================================================================================== - Slic3r::GUI::_3DScene::reset_volumes($self); - Slic3r::GUI::_3DScene::set_bed_shape($self, $self->{config}->bed_shape); +# } +# } +#} +# +#sub reload_scene { +# my ($self, $force) = @_; +# # $self->reset_objects; # $self->update_bed_size; -#============================================================================================================================== - - if (! $self->IsShown && ! $force) { - $self->{reload_delayed} = 1; - return; - } - - $self->{reload_delayed} = 0; - - $self->{objects_volumes_idxs} = []; - foreach my $obj_idx (0..$#{$self->{model}->objects}) { -#============================================================================================================================== - my $volume_idxs = Slic3r::GUI::_3DScene::load_model($self, $self->{model}, $obj_idx); - push(@{$self->{objects_volumes_idxs}}, \@{$volume_idxs}); - +# +# if (! $self->IsShown && ! $force) { +# $self->{reload_delayed} = 1; +# return; +# } +# +# $self->{reload_delayed} = 0; +# +# $self->{objects_volumes_idxs} = []; +# foreach my $obj_idx (0..$#{$self->{model}->objects}) { # my @volume_idxs = $self->load_object($self->{model}, $self->{print}, $obj_idx); # push(@{$self->{objects_volumes_idxs}}, \@volume_idxs); -#============================================================================================================================== - } - - $self->update_volumes_selection; - - if (defined $self->{config}->nozzle_diameter) { - # Should the wipe tower be visualized? - my $extruders_count = scalar @{ $self->{config}->nozzle_diameter }; - # Height of a print. - my $height = $self->{model}->bounding_box->z_max; - # Show at least a slab. - $height = 10 if $height < 10; - if ($extruders_count > 1 && $self->{config}->single_extruder_multi_material && $self->{config}->wipe_tower && - ! $self->{config}->complete_objects) { - $self->volumes->load_wipe_tower_preview(1000, - $self->{config}->wipe_tower_x, $self->{config}->wipe_tower_y, $self->{config}->wipe_tower_width, - #$self->{config}->wipe_tower_per_color_wipe# 15 * ($extruders_count - 1), # this is just a hack when the config parameter became obsolete - 15 * ($extruders_count - 1), -#============================================================================================================================== - $self->{model}->bounding_box->z_max, $self->{config}->wipe_tower_rotation_angle, Slic3r::GUI::_3DScene::use_VBOs()); +# } +# +# $self->update_volumes_selection; +# +# if (defined $self->{config}->nozzle_diameter) { +# # Should the wipe tower be visualized? +# my $extruders_count = scalar @{ $self->{config}->nozzle_diameter }; +# # Height of a print. +# my $height = $self->{model}->bounding_box->z_max; +# # Show at least a slab. +# $height = 10 if $height < 10; +# if ($extruders_count > 1 && $self->{config}->single_extruder_multi_material && $self->{config}->wipe_tower && +# ! $self->{config}->complete_objects) { +# $self->volumes->load_wipe_tower_preview(1000, +# $self->{config}->wipe_tower_x, $self->{config}->wipe_tower_y, $self->{config}->wipe_tower_width, +# #$self->{config}->wipe_tower_per_color_wipe# 15 * ($extruders_count - 1), # this is just a hack when the config parameter became obsolete +# 15 * ($extruders_count - 1), # $self->{model}->bounding_box->z_max, $self->{config}->wipe_tower_rotation_angle, $self->UseVBOs); -#============================================================================================================================== - } - } - -#============================================================================================================================== - Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self); +# } +# } +# # $self->update_volumes_colors_by_extruder($self->{config}); -#============================================================================================================================== - - # checks for geometry outside the print volume to render it accordingly - if (scalar @{$self->volumes} > 0) - { - my $contained = $self->volumes->check_outside_state($self->{config}); - if (!$contained) { -#============================================================================================================================== - Slic3r::GUI::_3DScene::enable_warning_texture($self, 1); +# +# # checks for geometry outside the print volume to render it accordingly +# if (scalar @{$self->volumes} > 0) +# { +# my $contained = $self->volumes->check_outside_state($self->{config}); +# if (!$contained) { # $self->set_warning_enabled(1); -#============================================================================================================================== - Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume")); - $self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons); - } else { -#============================================================================================================================== - Slic3r::GUI::_3DScene::enable_warning_texture($self, 0); +# Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume")); +# $self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons); +# } else { # $self->set_warning_enabled(0); -#============================================================================================================================== - $self->volumes->reset_outside_state(); - Slic3r::GUI::_3DScene::reset_warning_texture(); - $self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons); - } - } else { -#============================================================================================================================== - Slic3r::GUI::_3DScene::enable_warning_texture($self, 0); +# $self->volumes->reset_outside_state(); +# Slic3r::GUI::_3DScene::reset_warning_texture(); +# $self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons); +# } +# } else { # $self->set_warning_enabled(0); -#============================================================================================================================== - Slic3r::GUI::_3DScene::reset_warning_texture(); - } -} - -#============================================================================================================================== +# Slic3r::GUI::_3DScene::reset_warning_texture(); +# } +#} +# #sub update_bed_size { # my ($self) = @_; # $self->set_bed_shape($self->{config}->bed_shape); #} +# +## Called by the Platter wxNotebook when this page is activated. +#sub OnActivate { +# my ($self) = @_; +# $self->reload_scene(1) if ($self->{reload_delayed}); +#} #============================================================================================================================== -# Called by the Platter wxNotebook when this page is activated. -sub OnActivate { - my ($self) = @_; - $self->reload_scene(1) if ($self->{reload_delayed}); -} - 1; diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp index 913f91ccf..472b0478f 100644 --- a/xs/src/libslic3r/Utils.hpp +++ b/xs/src/libslic3r/Utils.hpp @@ -97,6 +97,7 @@ public: void call(int i, int j) const; void call(const std::vector& ints) const; void call(double x, double y) const; + void call(bool b) const; // void call(); // void call(int i); // void call(int i, int j); diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp index 017e2f1b3..7209d86f6 100644 --- a/xs/src/libslic3r/utils.cpp +++ b/xs/src/libslic3r/utils.cpp @@ -282,6 +282,11 @@ void PerlCallback::call(double x, double y) const FREETMPS; LEAVE; } + +void PerlCallback::call(bool b) const +{ + call(b ? 1 : 0); +} //############################################################################################################## #ifdef WIN32 diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 2d341996e..e773ec6eb 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1822,6 +1822,16 @@ void _3DScene::select_volume(wxGLCanvas* canvas, unsigned int id) s_canvas_mgr.select_volume(canvas, id); } +void _3DScene::update_volumes_selection(wxGLCanvas* canvas, const std::vector& selections) +{ + s_canvas_mgr.update_volumes_selection(canvas, selections); +} + +void _3DScene::set_objects_selections(wxGLCanvas* canvas, const std::vector& selections) +{ + s_canvas_mgr.set_objects_selections(canvas, selections); +} + void _3DScene::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config) { s_canvas_mgr.set_config(canvas, config); @@ -1892,6 +1902,11 @@ bool _3DScene::is_shader_enabled(wxGLCanvas* canvas) return s_canvas_mgr.is_shader_enabled(canvas); } +bool _3DScene::is_reload_delayed(wxGLCanvas* canvas) +{ + return s_canvas_mgr.is_reload_delayed(canvas); +} + void _3DScene::enable_layers_editing(wxGLCanvas* canvas, bool enable) { s_canvas_mgr.enable_layers_editing(canvas, enable); @@ -2091,6 +2106,11 @@ std::vector _3DScene::load_object(wxGLCanvas* canvas, const Model* model, i return s_canvas_mgr.load_object(canvas, model, obj_idx); } +void _3DScene::reload_scene(wxGLCanvas* canvas, bool force) +{ + s_canvas_mgr.reload_scene(canvas, force); +} + void _3DScene::load_print_toolpaths(wxGLCanvas* canvas) { s_canvas_mgr.load_print_toolpaths(canvas); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 7c4d8b3e9..a66130a3b 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -562,6 +562,9 @@ public: static void reset_volumes(wxGLCanvas* canvas); static void deselect_volumes(wxGLCanvas* canvas); static void select_volume(wxGLCanvas* canvas, unsigned int id); + static void update_volumes_selection(wxGLCanvas* canvas, const std::vector& selections); + + static void set_objects_selections(wxGLCanvas* canvas, const std::vector& selections); static void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config); static void set_print(wxGLCanvas* canvas, Print* print); @@ -584,6 +587,8 @@ public: static bool is_layers_editing_allowed(wxGLCanvas* canvas); static bool is_shader_enabled(wxGLCanvas* canvas); + static bool is_reload_delayed(wxGLCanvas* canvas); + static void enable_layers_editing(wxGLCanvas* canvas, bool enable); static void enable_warning_texture(wxGLCanvas* canvas, bool enable); static void enable_legend_texture(wxGLCanvas* canvas, bool enable); @@ -628,6 +633,8 @@ public: static std::vector load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector instance_idxs); static std::vector load_object(wxGLCanvas* canvas, const Model* model, int obj_idx); + static void reload_scene(wxGLCanvas* canvas, bool force); + static void load_print_toolpaths(wxGLCanvas* canvas); static void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector& str_tool_colors); static void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector& str_tool_colors); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index f969e1d46..745268627 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -2,6 +2,7 @@ #include "../../slic3r/GUI/3DScene.hpp" #include "../../slic3r/GUI/GLShader.hpp" +#include "../../slic3r/GUI/GUI.hpp" #include "../../libslic3r/ClipperUtils.hpp" #include "../../libslic3r/PrintConfig.hpp" #include "../../libslic3r/Print.hpp" @@ -963,6 +964,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) , m_color_by("volume") , m_select_by("object") , m_drag_by("instance") + , m_reload_delayed(false) { if (m_canvas != nullptr) m_timer = new wxTimer(m_canvas); @@ -1107,6 +1109,29 @@ void GLCanvas3D::select_volume(unsigned int id) } } +void GLCanvas3D::update_volumes_selection(const std::vector& selections) +{ + if (m_model == nullptr) + return; + + for (unsigned int obj_idx = 0; obj_idx < (unsigned int)m_model->objects.size(); ++obj_idx) + { + if (selections[obj_idx] == 1) + { + const std::vector& volume_idxs = m_objects_volumes_idxs[obj_idx]; + for (int v : volume_idxs) + { + select_volume(v); + } + } + } +} + +void GLCanvas3D::set_objects_selections(const std::vector& selections) +{ + m_objects_selections = selections; +} + void GLCanvas3D::set_config(DynamicPrintConfig* config) { m_config = config; @@ -1210,6 +1235,11 @@ bool GLCanvas3D::is_shader_enabled() const return m_shader_enabled; } +bool GLCanvas3D::is_reload_delayed() const +{ + return m_reload_delayed; +} + void GLCanvas3D::enable_layers_editing(bool enable) { m_layers_editing.set_enabled(enable); @@ -1409,6 +1439,81 @@ std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) return std::vector(); } +void GLCanvas3D::reload_scene(bool force) +{ + if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr) || (m_volumes == nullptr)) + return; + + reset_volumes(); + set_bed_shape(dynamic_cast(m_config->option("bed_shape"))->values); + + if (!m_canvas->IsShown() && !force) + { + m_reload_delayed = true; + return; + } + + m_reload_delayed = false; + + m_objects_volumes_idxs.clear(); + + for (unsigned int obj_idx = 0; obj_idx < (unsigned int)m_model->objects.size(); ++obj_idx) + { + m_objects_volumes_idxs.push_back(load_object(*m_model, obj_idx)); + } + + update_volumes_selection(m_objects_selections); + + if (m_config->has("nozzle_diameter")) + { + // Should the wipe tower be visualized ? + unsigned int extruders_count = (unsigned int)dynamic_cast(m_config->option("nozzle_diameter"))->values.size(); + + bool semm = dynamic_cast(m_config->option("single_extruder_multi_material"))->value; + bool wt = dynamic_cast(m_config->option("wipe_tower"))->value; + bool co = dynamic_cast(m_config->option("complete_objects"))->value; + + if ((extruders_count > 1) && semm && wt && !co) + { + // Height of a print (Show at least a slab) + coordf_t height = std::max(m_model->bounding_box().max.z, 10.0); + + float x = dynamic_cast(m_config->option("wipe_tower_x"))->value; + float y = dynamic_cast(m_config->option("wipe_tower_y"))->value; + float w = dynamic_cast(m_config->option("wipe_tower_width"))->value; + float a = dynamic_cast(m_config->option("wipe_tower_rotation_angle"))->value; + + m_volumes->load_wipe_tower_preview(1000, x, y, w, 15.0f * (float)(extruders_count - 1), (float)height, a, m_use_VBOs && m_initialized); + } + } + + update_volumes_colors_by_extruder(); + + // checks for geometry outside the print volume to render it accordingly + if (!m_volumes->empty()) + { + bool contained = m_volumes->check_outside_state(m_config); + if (!contained) + { + enable_warning_texture(true); + _3DScene::generate_warning_texture(L("Detected object outside print volume")); + m_on_enable_action_buttons_callback.call(false); + } + else + { + enable_warning_texture(false); + m_volumes->reset_outside_state(); + _3DScene::reset_warning_texture(); + m_on_enable_action_buttons_callback.call(!m_model->objects.empty()); + } + } + else + { + enable_warning_texture(false); + _3DScene::reset_warning_texture(); + } +} + void GLCanvas3D::load_print_toolpaths() { if ((m_print == nullptr) || (m_volumes == nullptr)) diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index e18b80345..49d06c135 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -14,6 +14,7 @@ class wxKeyEvent; class wxMouseEvent; class wxTimerEvent; class wxPaintEvent; +class wxActivateEvent; namespace Slic3r { @@ -349,6 +350,10 @@ private: std::string m_select_by; std::string m_drag_by; + bool m_reload_delayed; + std::vector> m_objects_volumes_idxs; + std::vector m_objects_selections; + GCodePreviewVolumeIndex m_gcode_preview_volume_index; PerlCallback m_on_viewport_changed_callback; @@ -381,6 +386,9 @@ public: void reset_volumes(); void deselect_volumes(); void select_volume(unsigned int id); + void update_volumes_selection(const std::vector& selections); + + void set_objects_selections(const std::vector& selections); void set_config(DynamicPrintConfig* config); void set_print(Print* print); @@ -410,6 +418,8 @@ public: bool is_layers_editing_allowed() const; bool is_shader_enabled() const; + bool is_reload_delayed() const; + void enable_layers_editing(bool enable); void enable_warning_texture(bool enable); void enable_legend_texture(bool enable); @@ -435,6 +445,8 @@ public: std::vector load_object(const ModelObject& model_object, int obj_idx, std::vector instance_idxs); std::vector load_object(const Model& model, int obj_idx); + void reload_scene(bool force); + // Create 3D thick extrusion lines for a skirt and brim. // Adds a new Slic3r::GUI::3DScene::Volume to volumes. void load_print_toolpaths(); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 34d62927a..cd4549bd8 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -254,6 +254,20 @@ void GLCanvas3DManager::select_volume(wxGLCanvas* canvas, unsigned int id) it->second->select_volume(id); } +void GLCanvas3DManager::update_volumes_selection(wxGLCanvas* canvas, const std::vector& selections) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->update_volumes_selection(selections); +} + +void GLCanvas3DManager::set_objects_selections(wxGLCanvas* canvas, const std::vector& selections) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->set_objects_selections(selections); +} + void GLCanvas3DManager::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -348,6 +362,12 @@ bool GLCanvas3DManager::is_shader_enabled(wxGLCanvas* canvas) const return (it != m_canvases.end()) ? it->second->is_shader_enabled() : false; } +bool GLCanvas3DManager::is_reload_delayed(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->is_reload_delayed() : false; +} + void GLCanvas3DManager::enable_layers_editing(wxGLCanvas* canvas, bool enable) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -481,6 +501,13 @@ std::vector GLCanvas3DManager::load_object(wxGLCanvas* canvas, const Model* return (it != m_canvases.end()) ? it->second->load_object(*model, obj_idx) : std::vector(); } +void GLCanvas3DManager::reload_scene(wxGLCanvas* canvas, bool force) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->reload_scene(force); +} + void GLCanvas3DManager::load_print_toolpaths(wxGLCanvas* canvas) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index f012b7703..d0765932a 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -57,6 +57,9 @@ public: void reset_volumes(wxGLCanvas* canvas); void deselect_volumes(wxGLCanvas* canvas); void select_volume(wxGLCanvas* canvas, unsigned int id); + void update_volumes_selection(wxGLCanvas* canvas, const std::vector& selections); + + void set_objects_selections(wxGLCanvas* canvas, const std::vector& selections); void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config); void set_print(wxGLCanvas* canvas, Print* print); @@ -79,6 +82,8 @@ public: bool is_layers_editing_allowed(wxGLCanvas* canvas) const; bool is_shader_enabled(wxGLCanvas* canvas) const; + bool is_reload_delayed(wxGLCanvas* canvas) const; + void enable_layers_editing(wxGLCanvas* canvas, bool enable); void enable_warning_texture(wxGLCanvas* canvas, bool enable); void enable_legend_texture(wxGLCanvas* canvas, bool enable); @@ -103,6 +108,8 @@ public: std::vector load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector instance_idxs); std::vector load_object(wxGLCanvas* canvas, const Model* model, int obj_idx); + void reload_scene(wxGLCanvas* canvas, bool force); + void load_print_toolpaths(wxGLCanvas* canvas); void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector& tool_colors); void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector& str_tool_colors); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 0635cea31..46c4381fd 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -225,6 +225,20 @@ select_volume(canvas, id) CODE: _3DScene::select_volume((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id); +void +update_volumes_selection(canvas, selections) + SV *canvas; + std::vector selections; + CODE: + _3DScene::update_volumes_selection((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections); + +void +set_objects_selections(canvas, selections) + SV *canvas; + std::vector selections; + CODE: + _3DScene::set_objects_selections((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections); + void set_config(canvas, config) SV *canvas; @@ -327,6 +341,14 @@ is_shader_enabled(canvas) OUTPUT: RETVAL +bool +is_reload_delayed(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::is_reload_delayed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + void enable_layers_editing(canvas, enable) SV *canvas; @@ -621,6 +643,13 @@ load_model(canvas, model, obj_idx) OUTPUT: RETVAL +void +reload_scene(canvas, force) + SV *canvas; + bool force; + CODE: + _3DScene::reload_scene((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), force); + void load_print_toolpaths(canvas) SV *canvas;