From efb1fd20666bf69aeed210588d7a3c252b024638 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 30 May 2017 17:24:50 +0200 Subject: [PATCH] Fixed order of loading the configs into Print / PrintObjects and loading the 3d print path preview. --- lib/Slic3r/GUI/3DScene.pm | 8 ++--- lib/Slic3r/GUI/Plater.pm | 17 ++++++----- lib/Slic3r/GUI/Plater/3DPreview.pm | 33 +++++++++++++++++--- xs/src/libslic3r/Print.hpp | 24 +++++++-------- xs/src/slic3r/GUI/3DScene.cpp | 49 ++++++++++++++---------------- xs/xsp/Print.xsp | 1 + 6 files changed, 77 insertions(+), 55 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index b0ebaa9e5..9e35e32f7 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -910,14 +910,12 @@ sub UseVBOs { if (! defined ($self->{use_VBOs})) { # This is a special path for wxWidgets on GTK, where an OpenGL context is initialized # first when an OpenGL widget is shown for the first time. How ugly. - # It seems like the wipe tower configuration fills in the VBOs before the window is created. - # Therefore it is safer to wait for the first screen refresh on Windows and OSX as well. -# return 0 if (! $self->init && $^O eq 'linux'); - return 0 if (! $self->init); + return 0 if (! $self->init && $^O eq 'linux'); # Don't use VBOs if anything fails. $self->{use_VBOs} = 0; if ($self->GetContext) { $self->SetCurrent($self->GetContext); + Slic3r::GUI::_3DScene::_glew_init; my @gl_version = split(/\./, glGetString(GL_VERSION)); $self->{use_VBOs} = int($gl_version[0]) >= 2; # print "UseVBOs $self OpenGL major: $gl_version[0], minor: $gl_version[1]. Use VBOs: ", $self->{use_VBOs}, "\n"; @@ -1023,8 +1021,6 @@ sub InitGL { glEnable(GL_COLOR_MATERIAL); glEnable(GL_MULTISAMPLE); - Slic3r::GUI::_3DScene::_glew_init; - if ($self->UseVBOs) { my $shader = new Slic3r::GUI::_3DScene::GLShader; if (! $shader->load($self->_fragment_shader_Gouraud, $self->_vertex_shader_Gouraud)) { diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 6cf912f0c..7743077ad 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1202,11 +1202,7 @@ sub schedule_background_process { # The timer is started by schedule_background_process(), sub async_apply_config { my ($self) = @_; - - # reset preview canvases - $self->{toolpaths2D}->reload_print if $self->{toolpaths2D}; - $self->{preview3D}->reload_print if $self->{preview3D}; - + # pause process thread before applying new config # since we don't want to touch data that is being used by the threads $self->pause_background_process; @@ -1231,6 +1227,11 @@ sub async_apply_config { # schedule a new process thread in case it wasn't running $self->start_background_process; + + # Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. + # Otherwise they will be just refreshed. + $self->{toolpaths2D}->reload_print if $self->{toolpaths2D}; + $self->{preview3D}->reload_print if $self->{preview3D}; } sub start_background_process { @@ -1817,8 +1818,10 @@ sub on_config_change { $self->{"btn_layer_editing"}->Enable; } } - } elsif ($opt_key eq 'extruder_color') { - + } elsif ($opt_key eq 'extruder_colour') { + $update_scheduled = 1; + my $extruder_colors = $config->get('extruder_colour'); + $self->{preview3D}->set_number_extruders(scalar(@{$extruder_colors})); } } diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm index b065e4fbe..4d77d5ee0 100644 --- a/lib/Slic3r/GUI/Plater/3DPreview.pm +++ b/lib/Slic3r/GUI/Plater/3DPreview.pm @@ -8,7 +8,7 @@ use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE); use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX); use base qw(Wx::Panel Class::Accessor); -__PACKAGE__->mk_accessors(qw(print enabled _loaded canvas slider_low slider_high single_layer color_by_extruder)); +__PACKAGE__->mk_accessors(qw(print enabled _loaded canvas slider_low slider_high single_layer)); sub new { my $class = shift; @@ -16,6 +16,8 @@ sub new { my $self = $class->SUPER::new($parent, -1, wxDefaultPosition); $self->{config} = $config; + $self->{number_extruders} = 1; + $self->{preferred_color_mode} = 'feature'; # init GUI elements my $canvas = Slic3r::GUI::3DScene->new($self); @@ -54,7 +56,7 @@ sub new { $z_label_high->SetFont($Slic3r::GUI::small_font); $self->single_layer(0); - $self->color_by_extruder(0); + $self->{color_by_extruder} = 0; my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, "1 Layer"); my $checkbox_color_by_extruder = $self->{checkbox_color_by_extruder} = Wx::CheckBox->new($self, -1, "Tool"); @@ -112,7 +114,8 @@ sub new { } }); EVT_CHECKBOX($self, $checkbox_color_by_extruder, sub { - $self->color_by_extruder($checkbox_color_by_extruder->GetValue()); + $self->{color_by_extruder} = $checkbox_color_by_extruder->GetValue(); + $self->{preferred_color_mode} = $self->{color_by_extruder} ? 'tool' : 'feature'; $self->reload_print; }); @@ -189,10 +192,21 @@ sub load_print { $self->slider_high->Show; $self->Layout; + my $by_tool = $self->{color_by_extruder}; + if ($self->{preferred_color_mode} eq 'tool_or_feature') { + # It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature. + # Color by feature if it is a single extruder print. + my $extruders = $self->{print}->extruders; + $by_tool = scalar(@{$extruders}) > 1; + $self->{color_by_extruder} = $by_tool; + $self->{checkbox_color_by_extruder}->SetValue($by_tool); + $self->{preferred_color_mode} = 'tool_or_feature'; + } + # Collect colors per extruder. # Leave it empty, if the print should be colored by a feature. my @colors = (); - if ($self->color_by_extruder) { + if ($by_tool) { my @extruder_colors = @{$self->{config}->extruder_colour}; my @filament_colors = @{$self->{config}->filament_colour}; for (my $i = 0; $i <= $#extruder_colors; $i += 1) { @@ -264,4 +278,15 @@ sub set_bed_shape { $self->canvas->set_bed_shape($bed_shape); } +sub set_number_extruders { + my ($self, $number_extruders) = @_; + if ($self->{number_extruders} != $number_extruders) { + $self->{number_extruders} = $number_extruders; + my $by_tool = $number_extruders > 1; + $self->{color_by_extruder} = $by_tool; + $self->{checkbox_color_by_extruder}->SetValue($by_tool); + $self->{preferred_color_mode} = $by_tool ? 'tool_or_feature' : 'feature'; + } +} + 1; diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 1ac9b15f8..580de19a6 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -139,19 +139,19 @@ public: const Points& copies() const { return this->_copies; } bool add_copy(const Pointf &point); bool delete_last_copy(); - bool delete_all_copies(); + bool delete_all_copies() { return this->set_copies(Points()); } bool set_copies(const Points &points); bool reload_model_instances(); - BoundingBox bounding_box() const { - // since the object is aligned to origin, bounding box coincides with size - return BoundingBox(Point(0,0), this->size); - } - - // adds region_id, too, if necessary - void add_region_volume(int region_id, int volume_id); + // since the object is aligned to origin, bounding box coincides with size + BoundingBox bounding_box() const { return BoundingBox(Point(0,0), this->size); } - size_t total_layer_count() const; - size_t layer_count() const; + // adds region_id, too, if necessary + void add_region_volume(int region_id, int volume_id) { region_volumes[region_id].push_back(volume_id); } + // This is the *total* layer count (including support layers) + // this value is not supposed to be compared with Layer::id + // since they have different semantics. + size_t total_layer_count() const { return this->layer_count() + this->support_layer_count(); } + size_t layer_count() const { return this->layers.size(); } void clear_layers(); Layer* get_layer(int idx) { return this->layers.at(idx); } const Layer* get_layer(int idx) const { return this->layers.at(idx); } @@ -160,9 +160,9 @@ public: Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); void delete_layer(int idx); - size_t support_layer_count() const; + size_t support_layer_count() const { return this->support_layers.size(); } void clear_support_layers(); - SupportLayer* get_support_layer(int idx); + SupportLayer* get_support_layer(int idx) { return this->support_layers.at(idx); } SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z); void delete_support_layer(int idx); diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 03fba8ecc..0b183b9e8 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -825,6 +825,8 @@ void _3DScene::_load_print_object_toolpaths( bool color_by_tool() const { return tool_colors != nullptr; } size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; } const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; } + int volume_idx(int extruder, int feature) const + { return this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(extruder - 1, 0)) : feature; } } ctxt; ctxt.shifted_copies = &print_object->_shifted_copies; @@ -890,41 +892,33 @@ void _3DScene::_load_print_object_toolpaths( } for (const Point ©: *ctxt.shifted_copies) { for (const LayerRegion *layerm : layer->regions) { - if (ctxt.has_perimeters) { - int volume_idx = ctxt.color_by_tool() ? - std::max(layerm->region()->config.perimeter_extruder.value - 1, 0) : - 0; - extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, *vols[volume_idx]); - } + if (ctxt.has_perimeters) + extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, + *vols[ctxt.volume_idx(layerm->region()->config.perimeter_extruder.value, 0)]); if (ctxt.has_infill) { for (const ExtrusionEntity *ee : layerm->fills.entities) { // fill represents infill extrusions of a single island. const auto *fill = dynamic_cast(ee); - if (fill->entities.empty()) - // This shouldn't happen but first_point() would fail. - continue; - int volume_idx = ctxt.color_by_tool() ? - std::max(0, - (is_solid_infill(fill->entities.front()->role()) ? - layerm->region()->config.solid_infill_extruder : - layerm->region()->config.infill_extruder) - 1) : - 1; - extrusionentity_to_verts(*fill, float(layer->print_z), copy, *vols[volume_idx]); + if (! fill->entities.empty()) + extrusionentity_to_verts(*fill, float(layer->print_z), copy, + *vols[ctxt.volume_idx( + is_solid_infill(fill->entities.front()->role()) ? + layerm->region()->config.solid_infill_extruder : + layerm->region()->config.infill_extruder, + 1)]); } } } if (ctxt.has_support) { const SupportLayer *support_layer = dynamic_cast(layer); if (support_layer) { - for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) { - int volume_idx = ctxt.color_by_tool() ? - std::max(0, - ((extrusion_entity->role() == erSupportMaterial) ? - support_layer->object()->config.support_material_extruder : - support_layer->object()->config.support_material_interface_extruder) - 1) : - 2; - extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy, *vols[volume_idx]); - } + for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) + extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy, + *vols[ctxt.volume_idx( + (extrusion_entity->role() == erSupportMaterial) ? + support_layer->object()->config.support_material_extruder : + support_layer->object()->config.support_material_interface_extruder, + 2)]); } } } @@ -985,6 +979,8 @@ void _3DScene::_load_wipe_tower_toolpaths( bool color_by_tool() const { return tool_colors != nullptr; } size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; } const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; } + int volume_idx(int tool, int feature) const + { return this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(tool, 0)) : feature; } } ctxt; ctxt.print = print; @@ -1069,7 +1065,8 @@ void _3DScene::_load_wipe_tower_toolpaths( lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y)); widths.emplace_back(e.width); } - thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z, *vols[ctxt.color_by_tool() ? e.tool : 0]); + thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z, + *vols[ctxt.volume_idx(e.tool, 0)]); } } } diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 2aa4cd59a..23c09dbdf 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -230,6 +230,7 @@ _constant() %code%{ RETVAL = THIS->apply_config(*config); %}; bool has_infinite_skirt(); bool has_skirt(); + std::vector extruders() const; std::string _validate() %code%{ RETVAL = THIS->validate(); %}; Clone bounding_box();