From f64e7bc331fa8f3075fc7b99f0492c3b8498f08a Mon Sep 17 00:00:00 2001 From: NateTG Date: Thu, 6 Apr 2017 13:41:48 -0700 Subject: [PATCH 01/22] Update FillRectilinear.cpp Changes cubic infill so that it forms closed parallelepiped cells and infill walls are flat. --- xs/src/libslic3r/Fill/FillRectilinear.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/libslic3r/Fill/FillRectilinear.cpp b/xs/src/libslic3r/Fill/FillRectilinear.cpp index f2e5ba7a3..8e0578c48 100644 --- a/xs/src/libslic3r/Fill/FillRectilinear.cpp +++ b/xs/src/libslic3r/Fill/FillRectilinear.cpp @@ -525,7 +525,7 @@ void FillCubic::_fill_surface_single( direction_t direction2 = direction; const coord_t range = scale_(this->min_spacing / this->density); - const coord_t x_shift = abs(( (coord_t)(scale_(this->z) + range) % (coord_t)(range * 2)) - range); + const coord_t x_shift = (coord_t)(scale_(this->z) + range) % (coord_t)(range*3); fill2._fill_single_direction(expolygon, direction2, -x_shift, out); From 3164217e3dd5b0e25eb5c996184941d5d2404fbb Mon Sep 17 00:00:00 2001 From: Jaggz H Date: Tue, 11 Apr 2017 12:19:05 -0700 Subject: [PATCH 02/22] Addressed logic of enforced supports. There are inconsistent rare crashes which I cannot find as related to my changes. --- lib/Slic3r/Print/Object.pm | 6 +++- lib/Slic3r/Print/SupportMaterial.pm | 51 +++++++++++++++++++---------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 368a23406..6816c9228 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -211,7 +211,11 @@ sub generate_support_material { $self->clear_support_layers; - if ((!$self->config->support_material && $self->config->raft_layers == 0) || scalar(@{$self->layers}) < 2) { + if ((!$self->config->support_material + && $self->config->raft_layers == 0 + && $self->config->support_material_enforce_layers == 0) + || scalar(@{$self->layers}) < 2 + ) { $self->set_step_done(STEP_SUPPORTMATERIAL); return; } diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index c533aa433..0fa27441c 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -93,18 +93,21 @@ sub generate { sub contact_area { # $object is Slic3r::Print::Object my ($self, $object) = @_; + my $conf = $self->object_config; # if user specified a custom angle threshold, convert it to radians my $threshold_rad; - if (!($self->object_config->support_material_threshold =~ /%$/)) { - $threshold_rad = deg2rad($self->object_config->support_material_threshold + 1); # +1 makes the threshold inclusive + if (!($conf->support_material_threshold =~ /%$/)) { + $threshold_rad = deg2rad($conf->support_material_threshold + 1); # +1 makes the threshold inclusive Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad); } # Build support on a build plate only? If so, then collect top surfaces into $buildplate_only_top_surfaces # and subtract $buildplate_only_top_surfaces from the contact surfaces, so # there is no contact surface supported by a top surface. - my $buildplate_only = $self->object_config->support_material && $self->object_config->support_material_buildplate_only; + my $buildplate_only = + ( $conf->support_material || $conf->support_material_enforce_layers) + && $conf->support_material_buildplate_only; my $buildplate_only_top_surfaces = []; # determine contact areas @@ -115,12 +118,19 @@ sub contact_area { # so $layer_id == 0 means first object layer # and $layer->id == 0 means first print layer (including raft) - if ($self->object_config->raft_layers == 0) { - next if $layer_id == 0; - } elsif (!$self->object_config->support_material) { + # if no raft, and we're at layer 0, skip to layer 1 + if ( $conf->raft_layers == 0 && $layer_id == 0 ) { + next; + } + # with or without raft, if we're above layer 1, we need to quit + # support generation if supports are disabled, or if we're at a high + # enough layer that enforce-supports no longer applies + if ( $layer_id > 0 + && !$conf->support_material + && ($layer_id >= $conf->support_material_enforce_layers) ) { # if we are only going to generate raft just check # the 'overhangs' of the first object layer - last if $layer_id > 0; + last; } my $layer = $object->get_layer($layer_id); @@ -154,12 +164,19 @@ sub contact_area { my $diff; # If a threshold angle was specified, use a different logic for detecting overhangs. - if (defined $threshold_rad - || $layer_id < $self->object_config->support_material_enforce_layers - || ($self->object_config->raft_layers > 0 && $layer_id == 0)) { - my $d = defined $threshold_rad - ? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad)) - : 0; + if (($conf->support_material && defined $threshold_rad) + || $layer_id <= $conf->support_material_enforce_layers + || ($conf->raft_layers > 0 && $layer_id == 0)) { + my $d = 0; + my $layer_threshold_rad = $threshold_rad; + if ($layer_id <= $conf->support_material_enforce_layers) { + # Use ~45 deg number for enforced supports if we are in auto + $layer_threshold_rad = deg2rad(75); + } + if (defined $layer_threshold_rad) { + $d = scale $lower_layer->height + * ((cos $layer_threshold_rad) / (sin $layer_threshold_rad)); + } $diff = diff( offset([ map $_->p, @{$layerm->slices} ], -$d), @@ -177,7 +194,7 @@ sub contact_area { } else { $diff = diff( [ map $_->p, @{$layerm->slices} ], - offset([ map @$_, @{$lower_layer->slices} ], +$self->object_config->get_abs_value_over('support_material_threshold', $fw)), + offset([ map @$_, @{$lower_layer->slices} ], +$conf->get_abs_value_over('support_material_threshold', $fw)), ); # collapse very tiny spots @@ -189,7 +206,7 @@ sub contact_area { # outside the lower slice boundary, thus no overhang } - if ($self->object_config->dont_support_bridges) { + if ($conf->dont_support_bridges) { # compute the area of bridging perimeters # Note: this is duplicate code from GCode.pm, we need to refactor @@ -264,7 +281,7 @@ sub contact_area { 1, ); } - } # if ($self->object_config->dont_support_bridges) + } # if ($conf->dont_support_bridges) if ($buildplate_only) { # Don't support overhangs above the top surfaces. @@ -309,7 +326,7 @@ sub contact_area { my $contact_z = $layer->print_z - $self->contact_distance($layer->height, $nozzle_diameter); # ignore this contact area if it's too low - next if $contact_z < $self->object_config->get_value('first_layer_height') - epsilon; + next if $contact_z < $conf->get_value('first_layer_height') - epsilon; $contact{$contact_z} = [ @contact ]; $overhang{$contact_z} = [ @overhang ]; From b78ccc6d4f3e7766da6dc3e9bc05c36da8b09193 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Thu, 13 Apr 2017 16:04:07 -0500 Subject: [PATCH 03/22] Ignore vim swap files. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f24586461..c8c13aed4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ xs/assertlib* local-lib package/osx/Slic3r*.app *.dmg +*.swp +*.swo From 075adca8bb94d527275b8812693c314dc31cb090 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Sat, 15 Apr 2017 10:39:11 -0500 Subject: [PATCH 04/22] Resize & Rotate modifier mesh (#3879) * Prototype scaling-to-size for modifier meshes. Currently the rescale doesn't seem to operate as expected. * Added scaling to size for modifier meshes. * Added rotation for modifier meshes. * Used correct UTF8 encoded ellipse. --- lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm | 120 +++++++++++++++++- lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm | 15 ++- xs/xsp/Model.xsp | 9 ++ 3 files changed, 140 insertions(+), 4 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index 1898ac6a0..17090438d 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -9,7 +9,9 @@ use utf8; use File::Basename qw(basename); use Wx qw(:misc :sizer :treectrl :button wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxTheApp); -use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED); +use List::Util qw(max); +use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_ITEM_RIGHT_CLICK); +use Slic3r::Geometry qw(X Y Z MIN MAX scale unscale deg2rad rad2deg); use base 'Wx::Panel'; use constant ICON_OBJECT => 0; @@ -156,11 +158,47 @@ sub new { return if $self->{disable_tree_sel_changed_event}; $self->selection_changed; }); + EVT_TREE_ITEM_RIGHT_CLICK($self, $tree, sub { + my ($self, $event) = @_; + my $item = $event->GetItem; + my $frame = $self->GetFrame; + my $menu = Wx::Menu->new; + + my $scaleToSizeMenu = Wx::Menu->new; + my $scaleToSizeMenuItem = $menu->AppendSubMenu($scaleToSizeMenu, "Scale to size", 'Scale the selected object along a single axis'); + wxTheApp->set_menu_item_icon($scaleToSizeMenuItem, 'arrow_out.png'); + $frame->_append_menu_item($scaleToSizeMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes', sub { + $self->changescale(undef, 1); + }); + $frame->_append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', sub { + $self->changescale(X, 1); + }, undef, 'bullet_red.png'); + $frame->_append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub { + $self->changescale(Y, 1); + }, undef, 'bullet_green.png'); + $frame->_append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { + $self->changescale(Z, 1); + }, undef, 'bullet_blue.png'); + my $rotateMenu = Wx::Menu->new; + my $rotateMenuItem = $menu->AppendSubMenu($rotateMenu, "Rotate", 'Rotate the selected object by an arbitrary angle'); + wxTheApp->set_menu_item_icon($rotateMenuItem, 'textfield.png'); + $frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub { + $self->rotate(undef, X); + }, undef, 'bullet_red.png'); + $frame->_append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub { + $self->rotate(undef, Y); + }, undef, 'bullet_green.png'); + $frame->_append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub { + $self->rotate(undef, Z); + }, undef, 'bullet_blue.png'); + + $frame->PopupMenu($menu, $event->GetPoint); + }); EVT_BUTTON($self, $self->{btn_load_part}, sub { $self->on_btn_load(0) }); EVT_BUTTON($self, $self->{btn_load_modifier}, sub { $self->on_btn_load(1) }); EVT_BUTTON($self, $self->{btn_load_lambda_modifier}, sub { $self->on_btn_lambda(1) }); EVT_BUTTON($self, $self->{btn_delete}, \&on_btn_delete); - + $self->reload_tree; return $self; @@ -450,4 +488,82 @@ sub _update { $self->{canvas}->Render; } +sub changescale { + my ($self, $axis, $tosize) = @_; + my $itemData = $self->get_selection; + if ($itemData && $itemData->{type} eq 'volume') { + my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}]; + my $object_size = $volume->bounding_box->size; + if (defined $axis) { + my $axis_name = $axis == X ? 'X' : $axis == Y ? 'Y' : 'Z'; + my $scale; + if (defined $tosize) { + my $cursize = $object_size->[$axis]; + # Wx::GetNumberFromUser() does not support decimal numbers + my $newsize = Wx::GetTextFromUser( + sprintf("Enter the new size for the selected mesh:"), + "Scale along $axis_name", + $cursize, $self); + return if !$newsize || $newsize !~ /^\d*(?:\.\d*)?$/ || $newsize < 0; + $scale = $newsize / $cursize * 100; + } else { + # Wx::GetNumberFromUser() does not support decimal numbers + $scale = Wx::GetTextFromUser("Enter the scale % for the selected object:", + "Scale along $axis_name", 100, $self); + $scale =~ s/%$//; + return if !$scale || $scale !~ /^\d*(?:\.\d*)?$/ || $scale < 0; + } + my $versor = [1,1,1]; + $versor->[$axis] = $scale/100; + $volume->mesh->scale_xyz(Slic3r::Pointf3->new(@$versor)); + } else { + my $scale; + if ($tosize) { + my $cursize = max(@$object_size); + # Wx::GetNumberFromUser() does not support decimal numbers + my $newsize = Wx::GetTextFromUser("Enter the new max size for the selected object:", + "Scale", $cursize, $self); + return if !$newsize || $newsize !~ /^\d*(?:\.\d*)?$/ || $newsize < 0; + $scale = $newsize / $cursize; + } else { + # max scale factor should be above 2540 to allow importing files exported in inches + # Wx::GetNumberFromUser() does not support decimal numbers + $scale = Wx::GetTextFromUser("Enter the scale % for the selected object:", 'Scale', + 100, $self); + return if !$scale || $scale !~ /^\d*(?:\.\d*)?$/ || $scale < 0; + } + return if !$scale || $scale < 0; + $volume->mesh->scale($scale); + } + $self->_parts_changed; + } +} + +sub rotate { + my $self = shift; + my ($angle, $axis) = @_; + # angle is in degrees + my $itemData = $self->get_selection; + if ($itemData && $itemData->{type} eq 'volume') { + my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}]; + if (!defined $angle) { + my $axis_name = $axis == X ? 'X' : $axis == Y ? 'Y' : 'Z'; + my $default = $axis == Z ? 0 : 0; + # Wx::GetNumberFromUser() does not support decimal numbers + $angle = Wx::GetTextFromUser("Enter the rotation angle:", "Rotate around $axis_name axis", + $default, $self); + return if !$angle || $angle !~ /^-?\d*(?:\.\d*)?$/ || $angle == -1; + } + if ($axis == X) { $volume->mesh->rotate_x(deg2rad($angle)); } + + if ($axis == Y) { $volume->mesh->rotate_y(deg2rad($angle)); } + if ($axis == Z) { $volume->mesh->rotate_z(deg2rad($angle)); } + + $self->_parts_changed; + } +} +sub GetFrame { + my ($self) = @_; + return &Wx::GetTopLevelParent($self); +} 1; diff --git a/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm b/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm index c0979cd13..2cca0d901 100644 --- a/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm @@ -7,8 +7,8 @@ use strict; use warnings; use utf8; -use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL); -use Wx::Event qw(EVT_BUTTON); +use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL wxTheApp); +use Wx::Event qw(EVT_BUTTON EVT_MENU); use base 'Wx::Dialog'; sub new { @@ -53,6 +53,17 @@ sub PartSettingsChanged { my ($self) = @_; return $self->{parts}->PartSettingsChanged || $self->{layers}->LayersChanged; } +sub _append_menu_item { + my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_; + + $id //= &Wx::NewId(); + my $item = $menu->Append($id, $string, $description, $kind); + wxTheApp->set_menu_item_icon($item, $icon); + + EVT_MENU($self, $id, $cb); + return $item; +} + package Slic3r::GUI::Plater::ObjectDialog::BaseTab; use base 'Wx::Panel'; diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp index cb415ad14..a53065236 100644 --- a/xs/xsp/Model.xsp +++ b/xs/xsp/Model.xsp @@ -248,6 +248,15 @@ ModelMaterial::attributes() void set_material_id(t_model_material_id material_id) %code%{ THIS->material_id(material_id); %}; Ref material(); + + Clone bounding_box() + %code%{ + try { + RETVAL = THIS->mesh.bounding_box(); + } catch (std::exception& e) { + croak("%s", e.what()); + } + %}; Ref config() %code%{ RETVAL = &THIS->config; %}; From 1857bf63910a7ade053390157fbd1bb9533629a0 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Sat, 15 Apr 2017 14:31:31 -0500 Subject: [PATCH 05/22] SupportMaterial operates in angle, underling XS Fill operates in radians. Convert degrees->radians Fixes #3861 --- lib/Slic3r/Print/SupportMaterial.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index c533aa433..ecb044068 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -722,7 +722,7 @@ sub generate_toolpaths { # interface and contact infill if (@$interface || @$contact_infill) { - $fillers{interface}->set_angle($interface_angle); + $fillers{interface}->set_angle(deg2rad($interface_angle)); $fillers{interface}->set_min_spacing($_interface_flow->spacing); # find centerline of the external loop @@ -772,7 +772,7 @@ sub generate_toolpaths { # support or flange if (@$base) { my $filler = $fillers{support}; - $filler->set_angle($angles[ ($layer_id) % @angles ]); + $filler->set_angle(deg2rad($angles[ ($layer_id) % @angles ])); # We don't use $base_flow->spacing because we need a constant spacing # value that guarantees that all layers are correctly aligned. @@ -789,7 +789,7 @@ sub generate_toolpaths { # base flange if ($layer_id == 0) { $filler = $fillers{interface}; - $filler->set_angle($self->object_config->support_material_angle + 90); + $filler->set_angle(deg2rad($self->object_config->support_material_angle + 90)); $density = 0.5; $base_flow = $self->first_layer_flow; From 0952b6dbe3d2672c50bfbfea9bab9c1d11987193 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Sat, 15 Apr 2017 18:37:42 -0500 Subject: [PATCH 06/22] Added test for enforced support generation. --- t/support.t | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/t/support.t b/t/support.t index 33e5d9cb3..8d4655b3f 100644 --- a/t/support.t +++ b/t/support.t @@ -1,4 +1,4 @@ -use Test::More tests => 27; +use Test::More tests => 28; use strict; use warnings; @@ -258,5 +258,32 @@ use Slic3r::Test; @{ $layer_heights_by_tool{$config->support_material_extruder-1} }), 'no support material layer is as thin as object layers'; } - +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('support_material_enforce_layers', 100); + $config->set('support_material', 0); + my @contact_z = my @top_z = (); + + my $test = sub { + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + my $flow = $print->print->objects->[0]->support_material_flow; + my $support = Slic3r::Print::SupportMaterial->new( + object_config => $print->print->objects->[0]->config, + print_config => $print->print->config, + flow => $flow, + interface_flow => $flow, + first_layer_flow => $flow, + ); + my $support_z = $support->support_layers_z(\@contact_z, \@top_z, $config->layer_height); + + is scalar(grep { $support_z->[$_]-$support_z->[$_-1] <= 0 } 1..$#$support_z), 0, + 'forced support is generated'; + + }; + $config->set('layer_height', 0.2); + $config->set('first_layer_height', 0.3); + @contact_z = (1.9); + @top_z = (1.1); + $test->(); +} __END__ From 3776f1afc64d5bcf8079b4e83e0376a79f91573e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 15 Apr 2017 11:10:53 +0200 Subject: [PATCH 07/22] Fixed regression causing posPrepareInfill invalidation to have no effects. #3874 --- lib/Slic3r/Print/Object.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 368a23406..300b8e361 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -156,7 +156,6 @@ sub prepare_infill { my ($self) = @_; return if $self->step_done(STEP_PREPARE_INFILL); - $self->set_step_started(STEP_PREPARE_INFILL); # This prepare_infill() is not really idempotent. # TODO: It should clear and regenerate fill_surfaces at every run @@ -164,6 +163,9 @@ sub prepare_infill { $self->invalidate_step(STEP_PERIMETERS); $self->make_perimeters; + # Do this after invalidating STEP_PERIMETERS because that would re-invalidate STEP_PREPARE_INFILL + $self->set_step_started(STEP_PREPARE_INFILL); + # prerequisites $self->detect_surfaces_type; From cf984e17a3b4e1ea560c6e6951e12ed5d62700ae Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 18 Apr 2017 19:25:18 +0200 Subject: [PATCH 08/22] Fix SLAPrint default overrides --- lib/Slic3r/GUI/SLAPrintOptions.pm | 4 ++++ xs/src/libslic3r/PrintConfig.hpp | 12 ------------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/Slic3r/GUI/SLAPrintOptions.pm b/lib/Slic3r/GUI/SLAPrintOptions.pm index 042ddc288..289f4e5a1 100644 --- a/lib/Slic3r/GUI/SLAPrintOptions.pm +++ b/lib/Slic3r/GUI/SLAPrintOptions.pm @@ -12,6 +12,10 @@ sub new { $self->config(Slic3r::Config::SLAPrint->new); $self->config->apply_dynamic(wxTheApp->{mainframe}->{plater}->config); + # Set some defaults + $self->config->set('infill_extrusion_width', 0.5) if $self->config->infill_extrusion_width == 0; + $self->config->set('perimeter_extrusion_width', 1) if $self->config->perimeter_extrusion_width == 0; + my $sizer = Wx::BoxSizer->new(wxVERTICAL); my $new_optgroup = sub { my ($title) = @_; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 5b4206266..ce5162ffa 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -574,18 +574,6 @@ class SLAPrintConfig ConfigOptionFloat support_material_spacing; ConfigOptionInt threads; - SLAPrintConfig() : StaticPrintConfig() { - this->set_defaults(); - - // override some defaults - this->fill_density.value = 100; - this->fill_pattern.value = ipGrid; - this->infill_extrusion_width.value = 0.5; - this->infill_extrusion_width.percent = false; - this->perimeter_extrusion_width.value = 1; - this->perimeter_extrusion_width.percent = false; - }; - virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(fill_angle); OPT_PTR(fill_density); From e0301acad991f5a0e273a85497cd30d4c57746b2 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Tue, 18 Apr 2017 15:47:41 -0500 Subject: [PATCH 09/22] abort download if no package. --- package/win/appveyor_deploy.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/win/appveyor_deploy.ps1 b/package/win/appveyor_deploy.ps1 index 818565820..d596190ca 100644 --- a/package/win/appveyor_deploy.ps1 +++ b/package/win/appveyor_deploy.ps1 @@ -3,10 +3,10 @@ cd package/win ./compile_wrapper.ps1 524 | Write-Output ./package_win32.ps1 524| Write-Output cd ../../ -Add-AppveyorCompilationMessage -Message "Uploading to server." -& ./package/deploy/winscp.ps1 -DIR win -KEY $env:APPVEYOR_BUILD_FOLDER/package/deploy/slic3r-upload.ppk -FILE *.zip *>> ./sftplog.txt - if (!(Test-Path C:\project\slic3r\slic3r.par)) { Add-AppveyorCompilationMessage -Message "Failed to package!" -Category Error return 1 } + +Add-AppveyorCompilationMessage -Message "Uploading to server." +& ./package/deploy/winscp.ps1 -DIR win -KEY $env:APPVEYOR_BUILD_FOLDER/package/deploy/slic3r-upload.ppk -FILE *.zip *>> ./sftplog.txt From 85374b8c30b66991fec2d2db72275477e3220d9f Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Tue, 18 Apr 2017 16:11:38 -0500 Subject: [PATCH 10/22] Removed useless test. --- package/win/appveyor_deploy.ps1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package/win/appveyor_deploy.ps1 b/package/win/appveyor_deploy.ps1 index d596190ca..28616f02c 100644 --- a/package/win/appveyor_deploy.ps1 +++ b/package/win/appveyor_deploy.ps1 @@ -3,10 +3,6 @@ cd package/win ./compile_wrapper.ps1 524 | Write-Output ./package_win32.ps1 524| Write-Output cd ../../ -if (!(Test-Path C:\project\slic3r\slic3r.par)) { - Add-AppveyorCompilationMessage -Message "Failed to package!" -Category Error - return 1 -} Add-AppveyorCompilationMessage -Message "Uploading to server." & ./package/deploy/winscp.ps1 -DIR win -KEY $env:APPVEYOR_BUILD_FOLDER/package/deploy/slic3r-upload.ppk -FILE *.zip *>> ./sftplog.txt From b500f0cc0180668f8fd4972eeedec9a79e5b7103 Mon Sep 17 00:00:00 2001 From: Jaggz H Date: Tue, 18 Apr 2017 18:05:54 -0700 Subject: [PATCH 11/22] changed overhang threshold for enforced supports from 75 to 89 --- lib/Slic3r/Print/SupportMaterial.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 0fa27441c..b4ce3c357 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -171,7 +171,7 @@ sub contact_area { my $layer_threshold_rad = $threshold_rad; if ($layer_id <= $conf->support_material_enforce_layers) { # Use ~45 deg number for enforced supports if we are in auto - $layer_threshold_rad = deg2rad(75); + $layer_threshold_rad = deg2rad(89); } if (defined $layer_threshold_rad) { $d = scale $lower_layer->height From 5f6a12c16348cd796e81e291ef2c9f9cea391481 Mon Sep 17 00:00:00 2001 From: Travis CI User Date: Wed, 19 Apr 2017 02:03:11 +0000 Subject: [PATCH 12/22] stable-ish libraries for Linux --- package/linux/libpaths.txt | 28 ++++++++++++++++++++++++++++ package/linux/make_archive.sh | 6 ++++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 package/linux/libpaths.txt diff --git a/package/linux/libpaths.txt b/package/linux/libpaths.txt new file mode 100644 index 000000000..798e9103d --- /dev/null +++ b/package/linux/libpaths.txt @@ -0,0 +1,28 @@ +/home/travis/builds/alexrj/Slic3r/local-lib/lib/perl5/x86_64-linux-thread-multi/Alien/wxWidgets/gtk_3_0_2_uni/lib/libwx_baseu-3.0.so.0 +/home/travis/builds/alexrj/Slic3r/local-lib/lib/perl5/x86_64-linux-thread-multi/Alien/wxWidgets/gtk_3_0_2_uni/lib/libwx_gtk2u_adv-3.0.so.0 +/home/travis/builds/alexrj/Slic3r/local-lib/lib/perl5/x86_64-linux-thread-multi/Alien/wxWidgets/gtk_3_0_2_uni/lib/libwx_gtk2u_core-3.0.so.0 +/lib/x86_64-linux-gnu/liblzma.so.5 +/lib/x86_64-linux-gnu/libm.so.6 +/lib/x86_64-linux-gnu/libpcre.so.3 +/lib/x86_64-linux-gnu/libpng12.so.0 +/lib/x86_64-linux-gnu/libresolv.so.2 +/lib/x86_64-linux-gnu/libuuid.so.1 +/usr/lib/x86_64-linux-gnu/libSM.so.6 +/usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 +/usr/lib/x86_64-linux-gnu/libdatrie.so.1 +/usr/lib/x86_64-linux-gnu/libfreetype.so.6 +/usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0 +/usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 +/usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 +/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 +/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 +/usr/lib/x86_64-linux-gnu/libgraphite2.so.3 +/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 +/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0 +/usr/lib/x86_64-linux-gnu/libjbig.so.0 +/usr/lib/x86_64-linux-gnu/libjpeg.so.8 +/usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 +/usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 +/usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 +/usr/lib/x86_64-linux-gnu/libpixman-1.so.0 +/usr/lib/x86_64-linux-gnu/libtiff.so.5 diff --git a/package/linux/make_archive.sh b/package/linux/make_archive.sh index 1e34dc49a..422ac19a0 100755 --- a/package/linux/make_archive.sh +++ b/package/linux/make_archive.sh @@ -47,7 +47,7 @@ echo "Appfolder: $appfolder, archivefolder: $archivefolder" # Our slic3r dir and location of perl PERL_BIN=$(which perl) -PP_BIN=$(which wxpar) +PP_BIN=$(which pp) SLIC3R_DIR="./" if [[ -d "${appfolder}" ]]; then @@ -104,8 +104,10 @@ ${PP_BIN} wxextension .0 \ unzip -qq -o $WD/_tmp/test.par -d $WD/_tmp/ cp -rf $WD/_tmp/lib/* $archivefolder/local-lib/lib/perl5/ cp -rf $WD/_tmp/shlib $archivefolder/ - rm -rf $WD/_tmp +for i in $(cat $WD/libpaths.txt); do + install -v $i $archivefolder/bin +done echo "Cleaning local-lib" rm -rf $archivefolder/local-lib/bin From b26681ef58b964d9889cd4d7e0eff6c606c323ff Mon Sep 17 00:00:00 2001 From: Travis CI User Date: Wed, 19 Apr 2017 02:09:54 +0000 Subject: [PATCH 13/22] updated travis for new linux package script --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dc2cefdcb..f399c1de8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ install: - export SLIC3R_STATIC=1 - export CXX=g++-4.9 - export CC=g++-4.9 -- export WXDIR=$HOME/wx302 - source $HOME/perl5/perlbrew/etc/bashrc script: - bash package/linux/travis-setup.sh @@ -32,6 +31,8 @@ addons: packages: - g++-4.9 - gcc-4.9 + - libgtk2.0-0 + - libgtk2.0-dev ssh_known_hosts: dl.slic3r.org notifications: irc: From 3274b75e5fca595f90b471890a9033dbd30d8ae1 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Wed, 19 Apr 2017 02:30:19 +0000 Subject: [PATCH 14/22] Update file encodings and add some commentary. Also make 524 the default perl lib --- package/common/shell.cpp | 6 ------ package/win/autorun.bat | 1 - package/win/compile_wrapper.ps1 | 13 ++++++++++++- package/win/package_win32.ps1 | 4 ++-- 4 files changed, 14 insertions(+), 10 deletions(-) delete mode 100644 package/win/autorun.bat diff --git a/package/common/shell.cpp b/package/common/shell.cpp index 166f72111..4ce3c9afa 100644 --- a/package/common/shell.cpp +++ b/package/common/shell.cpp @@ -1,7 +1,6 @@ #include // from the Perl distribution #include // from the Perl distribution - #ifdef WIN32 // Perl win32 specific includes, found in perl\\lib\\CORE\\win32.h // Defines the windows specific convenience RunPerl() function, @@ -17,13 +16,8 @@ int main(int argc, char **argv, char **env) { - // replaces following Windows batch file: @"%~dp0\perl5.24.0.exe" - // "%~dp0\slic3r.pl" --DataDir "C:\Users\Public\Documents\Prusa3D\Slic3r - // settings MK2"%* - // If the Slic3r is installed in a localized directory (containing non-iso // characters), spaces or semicolons, use short file names. - char exe_path[MAX_PATH] = {0}; char script_path[MAX_PATH]; char gui_flag[6] = {"--gui"}; diff --git a/package/win/autorun.bat b/package/win/autorun.bat deleted file mode 100644 index be2c7b3f0..000000000 --- a/package/win/autorun.bat +++ /dev/null @@ -1 +0,0 @@ -@perl5.24.0.exe slic3r.pl %* diff --git a/package/win/compile_wrapper.ps1 b/package/win/compile_wrapper.ps1 index abd929287..c5d603ef3 100644 --- a/package/win/compile_wrapper.ps1 +++ b/package/win/compile_wrapper.ps1 @@ -4,16 +4,27 @@ if ($args[0]) $perlver = $args[0] } else { - $perlver = 518 + $perlver = 524 } $perllib = "-lperl$perlver" $shell_loc = "..\common\shell.cpp" +# Build the resource file (used to load icon, etc) windres slic3r.rc -O coff -o slic3r.res + +# Compile an object file that does not have gui forced. g++ -c -I'C:\strawberry\perl\lib\CORE\' $shell_loc -o slic3r.o + +# Compile an object file with --gui automatically passed as an argument g++ -c -I'C:\strawberry\perl\lib\CORE\' -DFORCE_GUI $shell_loc -o slic3r-gui.o + +# Build the EXE for the unforced version as slic3r-console g++ -static-libgcc -static-libstdc++ -L'C:\strawberry\c\lib' -L'C:\strawberry\perl\bin' -L'C:\strawberry\perl\lib\CORE\' $perllib slic3r.o slic3r.res -o slic3r-console.exe | Write-Host + +# Build the EXE for the forced GUI g++ -static-libgcc -static-libstdc++ -L'C:\strawberry\c\lib' -mwindows -L'C:\strawberry\perl\bin' -L'C:\strawberry\perl\lib\CORE\' $perllib slic3r-gui.o slic3r.res -o slic3r.exe | Write-Host + +# Build an extra copy of the GUI version that creates a console window g++ -static-libgcc -static-libstdc++ -L'C:\strawberry\c\lib' -L'C:\strawberry\perl\bin' -L'C:\strawberry\perl\lib\CORE\' $perllib slic3r-gui.o slic3r.res -o slic3r-debug-console.exe | Write-Host diff --git a/package/win/package_win32.ps1 b/package/win/package_win32.ps1 index 1a98bcf27..07396ea37 100644 --- a/package/win/package_win32.ps1 +++ b/package/win/package_win32.ps1 @@ -1,7 +1,7 @@ -# Written by Joseph Lenox +# Written by Joseph Lenox # Licensed under the same license as the rest of Slic3r. # ------------------------ -# You need to have Strawberry Perl 5.24.0.1 installed for this to work, +# You need to have Strawberry Perl 5.24.0.1 (or slic3r-perl) installed for this to work, param ( [switch]$exe = $false ) From cff79b6555427064a793d8e1b1805a5467c7af3a Mon Sep 17 00:00:00 2001 From: platsch Date: Thu, 20 Apr 2017 14:03:23 +0200 Subject: [PATCH 15/22] Command line help for --datadir option (#3897) --- slic3r.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/slic3r.pl b/slic3r.pl index 9526ab6c2..a21509843 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -316,6 +316,9 @@ Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ... --save Save configuration to the specified file --load Load configuration from the specified file. It can be used more than once to load options from multiple files. + --datadir Load and store settings at the given directory. + This is useful for maintaining different profiles or including + configurations from a network storage. -o, --output File to output gcode to (by default, the file will be saved into the same directory as the input file using the --output-filename-format to generate the filename.) If a From f24fc2c6757a819ceaf5344bb6ecd5479b0eacb1 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 21 Apr 2017 15:42:36 +0200 Subject: [PATCH 16/22] One more fix for BOOST_DIR --- xs/Build.PL | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/xs/Build.PL b/xs/Build.PL index 2fc5b33c1..8b622b5c3 100644 --- a/xs/Build.PL +++ b/xs/Build.PL @@ -67,15 +67,13 @@ my @boost_include = (); if (defined $ENV{BOOST_INCLUDEDIR}) { push @boost_include, $ENV{BOOST_INCLUDEDIR} } elsif (defined $ENV{BOOST_DIR}) { - my $subdir = $ENV{BOOST_DIR} . (($mswin == 1) ? '\include' : '/include'); - if (-d $subdir) { - push @boost_include, $subdir; - } elsif (-d "../$subdir") { - # User might have provided a path relative to the Build.PL in the main directory - push @boost_include, "../$subdir"; - } else { - push @boost_include, $ENV{BOOST_DIR}; + # User might have provided a path relative to the Build.PL in the main directory + foreach my $subdir ($ENV{BOOST_DIR}, "../$ENV{BOOST_DIR}", "$ENV{BOOST_DIR}/include", "../$ENV{BOOST_DIR}/include") { + if (-d $subdir) { + push @boost_include, $subdir; + } } + die "Invalid BOOST_DIR: no such directory\n" if !@boost_include; } else { # Boost library was not defined by the environment. # Try to guess at some default paths. @@ -99,15 +97,13 @@ my @boost_libs = (); if (defined $ENV{BOOST_LIBRARYPATH}) { push @boost_libs, $ENV{BOOST_LIBRARYPATH} } elsif (defined $ENV{BOOST_DIR}) { - my $subdir = $ENV{BOOST_DIR} . ($mswin ? '\stage\lib' : '/stage/lib'); - if (-d $subdir) { - push @boost_libs, $subdir; - } elsif (-d "../$subdir") { - # User might have provided a path relative to the Build.PL in the main directory - push @boost_libs, "../$subdir"; - } else { - push @boost_libs, $ENV{BOOST_DIR}; + # User might have provided a path relative to the Build.PL in the main directory + foreach my $subdir ("$ENV{BOOST_DIR}/stage/lib", "../$ENV{BOOST_DIR}/stage/lib") { + if (-d $subdir) { + push @boost_libs, $subdir; + } } + die "Invalid BOOST_DIR: no such directory\n" if !@boost_libs; } else { # Boost library was not defined by the environment. # Try to guess at some default paths. From ec4f618cb51abae00cfed11cfeab0d93873314d0 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 26 Apr 2017 22:18:36 +0200 Subject: [PATCH 17/22] Fixed regression in DLP manual control --- lib/Slic3r/GUI/Projector.pm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Projector.pm b/lib/Slic3r/GUI/Projector.pm index c41b7e8ad..8443000d0 100644 --- a/lib/Slic3r/GUI/Projector.pm +++ b/lib/Slic3r/GUI/Projector.pm @@ -9,7 +9,7 @@ use Wx::Event qw(EVT_BUTTON EVT_CLOSE EVT_TEXT_ENTER EVT_SPINCTRL EVT_SLIDER); use base qw(Wx::Dialog Class::Accessor); use utf8; -__PACKAGE__->mk_accessors(qw(config config2 screen controller _optgroups)); +__PACKAGE__->mk_accessors(qw(config config2 manual_control_config screen controller _optgroups)); sub new { my ($class, $parent) = @_; @@ -27,6 +27,12 @@ sub new { z_lift_speed => 8, offset => [0,0], }); + $self->manual_control_config({ + xy_travel_speed => 130, + z_travel_speed => 10, + temperature => '', + bed_temperature => '', + }); my $ini = eval { Slic3r::Config->read_ini("$Slic3r::GUI::datadir/DLP.ini") }; if ($ini) { @@ -286,7 +292,7 @@ sub new { return; } my $dlg = Slic3r::GUI::Controller::ManualControlDialog->new - ($self, $self->config, $sender); + ($self, $self->config, $sender, $self->manual_control_config); $dlg->ShowModal; $sender->disconnect; }); From 9adbae29a59c9d05a6ab1ead3f96b29fe9aecb3e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 27 Apr 2017 12:14:54 +0200 Subject: [PATCH 18/22] Bugfix: menu icons were not shown on GTK because SetBitmap() must be called before Append(). Thank you @xoan --- lib/Slic3r/GUI.pm | 25 ++++ lib/Slic3r/GUI/MainFrame.pm | 92 +++++------- lib/Slic3r/GUI/Plater.pm | 140 +++++++++--------- lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm | 53 +++---- lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm | 10 -- .../GUI/Plater/OverrideSettingsPanel.pm | 12 +- 6 files changed, 166 insertions(+), 166 deletions(-) diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index ce94d0882..def50e167 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -5,6 +5,7 @@ use utf8; use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow :filedialog :font); +use Wx::Event qw(EVT_MENU); BEGIN { # Wrap the Wx::_load_plugin() function which doesn't work with non-ASCII paths @@ -436,6 +437,30 @@ sub scan_serial_ports { return grep !/Bluetooth|FireFly/, @ports; } +sub append_menu_item { + my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_; + + $id //= &Wx::NewId(); + my $item = Wx::MenuItem->new($menu, $id, $string, $description // '', $kind // 0); + $self->set_menu_item_icon($item, $icon); + $menu->Append($item); + + EVT_MENU($self, $id, $cb); + return $item; +} + +sub append_submenu { + my ($self, $menu, $string, $description, $submenu, $id, $icon) = @_; + + $id //= &Wx::NewId(); + my $item = Wx::MenuItem->new($menu, $id, $string, $description // ''); + $self->set_menu_item_icon($item, $icon); + $item->SetSubMenu($submenu); + $menu->Append($item); + + return $item; +} + sub set_menu_item_icon { my ($self, $menuItem, $icon) = @_; diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 1b07d37ef..12ae8abbc 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -10,7 +10,7 @@ use List::Util qw(min); use Slic3r::Geometry qw(X Y Z); use Wx qw(:frame :bitmap :id :misc :notebook :panel :sizer :menu :dialog :filedialog :font :icon wxTheApp); -use Wx::Event qw(EVT_CLOSE EVT_MENU EVT_NOTEBOOK_PAGE_CHANGED); +use Wx::Event qw(EVT_CLOSE EVT_NOTEBOOK_PAGE_CHANGED); use base 'Wx::Frame'; our $qs_last_input_file; @@ -109,60 +109,60 @@ sub _init_menubar { # File menu my $fileMenu = Wx::Menu->new; { - $self->_append_menu_item($fileMenu, "Open STL/OBJ/AMF…\tCtrl+O", 'Open a model', sub { + wxTheApp->append_menu_item($fileMenu, "Open STL/OBJ/AMF…\tCtrl+O", 'Open a model', sub { $self->{plater}->add if $self->{plater}; }, undef, 'brick_add.png'); - $self->_append_menu_item($fileMenu, "Open 2.5D TIN mesh…", 'Import a 2.5D TIN mesh', sub { + wxTheApp->append_menu_item($fileMenu, "Open 2.5D TIN mesh…", 'Import a 2.5D TIN mesh', sub { $self->{plater}->add_tin if $self->{plater}; }, undef, 'map_add.png'); $fileMenu->AppendSeparator(); - $self->_append_menu_item($fileMenu, "&Load Config…\tCtrl+L", 'Load exported configuration file', sub { + wxTheApp->append_menu_item($fileMenu, "&Load Config…\tCtrl+L", 'Load exported configuration file', sub { $self->load_config_file; }, undef, 'plugin_add.png'); - $self->_append_menu_item($fileMenu, "&Export Config…\tCtrl+E", 'Export current configuration to file', sub { + wxTheApp->append_menu_item($fileMenu, "&Export Config…\tCtrl+E", 'Export current configuration to file', sub { $self->export_config; }, undef, 'plugin_go.png'); - $self->_append_menu_item($fileMenu, "&Load Config Bundle…", 'Load presets from a bundle', sub { + wxTheApp->append_menu_item($fileMenu, "&Load Config Bundle…", 'Load presets from a bundle', sub { $self->load_configbundle; }, undef, 'lorry_add.png'); - $self->_append_menu_item($fileMenu, "&Export Config Bundle…", 'Export all presets to file', sub { + wxTheApp->append_menu_item($fileMenu, "&Export Config Bundle…", 'Export all presets to file', sub { $self->export_configbundle; }, undef, 'lorry_go.png'); $fileMenu->AppendSeparator(); my $repeat; - $self->_append_menu_item($fileMenu, "Q&uick Slice…\tCtrl+U", 'Slice file', sub { + wxTheApp->append_menu_item($fileMenu, "Q&uick Slice…\tCtrl+U", 'Slice file', sub { wxTheApp->CallAfter(sub { $self->quick_slice; $repeat->Enable(defined $Slic3r::GUI::MainFrame::last_input_file); }); }, undef, 'cog_go.png'); - $self->_append_menu_item($fileMenu, "Quick Slice and Save &As…\tCtrl+Alt+U", 'Slice file and save as', sub { + wxTheApp->append_menu_item($fileMenu, "Quick Slice and Save &As…\tCtrl+Alt+U", 'Slice file and save as', sub { wxTheApp->CallAfter(sub { $self->quick_slice(save_as => 1); $repeat->Enable(defined $Slic3r::GUI::MainFrame::last_input_file); }); }, undef, 'cog_go.png'); - $repeat = $self->_append_menu_item($fileMenu, "&Repeat Last Quick Slice\tCtrl+Shift+U", 'Repeat last quick slice', sub { + $repeat = wxTheApp->append_menu_item($fileMenu, "&Repeat Last Quick Slice\tCtrl+Shift+U", 'Repeat last quick slice', sub { wxTheApp->CallAfter(sub { $self->quick_slice(reslice => 1); }); }, undef, 'cog_go.png'); $repeat->Enable(0); $fileMenu->AppendSeparator(); - $self->_append_menu_item($fileMenu, "Slice to SV&G…\tCtrl+G", 'Slice file to SVG', sub { + wxTheApp->append_menu_item($fileMenu, "Slice to SV&G…\tCtrl+G", 'Slice file to SVG', sub { $self->quick_slice(save_as => 1, export_svg => 1); }, undef, 'shape_handles.png'); $fileMenu->AppendSeparator(); - $self->_append_menu_item($fileMenu, "Repair STL file…", 'Automatically repair an STL file', sub { + wxTheApp->append_menu_item($fileMenu, "Repair STL file…", 'Automatically repair an STL file', sub { $self->repair_stl; }, undef, 'wrench.png'); $fileMenu->AppendSeparator(); # Cmd+, is standard on OS X - what about other operating systems? - $self->_append_menu_item($fileMenu, "Preferences…\tCtrl+,", 'Application preferences', sub { + wxTheApp->append_menu_item($fileMenu, "Preferences…\tCtrl+,", 'Application preferences', sub { Slic3r::GUI::Preferences->new($self)->ShowModal; }, wxID_PREFERENCES); $fileMenu->AppendSeparator(); - $self->_append_menu_item($fileMenu, "&Quit", 'Quit Slic3r', sub { + wxTheApp->append_menu_item($fileMenu, "&Quit", 'Quit Slic3r', sub { $self->Close(0); }, wxID_EXIT); } @@ -174,23 +174,22 @@ sub _init_menubar { $self->{plater_menu} = Wx::Menu->new; { my $selectMenu = $self->{plater_select_menu} = Wx::Menu->new; - my $selectMenuItem = $self->{plater_menu}->AppendSubMenu($selectMenu, "Select", 'Select an object in the plater'); - wxTheApp->set_menu_item_icon($selectMenuItem, 'brick.png'); + wxTheApp->append_submenu($self->{plater_menu}, "Select", 'Select an object in the plater', $selectMenu, undef, 'brick.png'); } - $self->_append_menu_item($self->{plater_menu}, "Select Next Object\tCtrl+Right", 'Select Next Object in the plater', sub { + wxTheApp->append_menu_item($self->{plater_menu}, "Select Next Object\tCtrl+Right", 'Select Next Object in the plater', sub { $plater->select_next; }, undef, 'arrow_right.png'); - $self->_append_menu_item($self->{plater_menu}, "Select Prev Object\tCtrl+Left", 'Select Previous Object in the plater', sub { + wxTheApp->append_menu_item($self->{plater_menu}, "Select Prev Object\tCtrl+Left", 'Select Previous Object in the plater', sub { $plater->select_prev; }, undef, 'arrow_left.png'); $self->{plater_menu}->AppendSeparator(); - $self->_append_menu_item($self->{plater_menu}, "Export G-code...", 'Export current plate as G-code', sub { + wxTheApp->append_menu_item($self->{plater_menu}, "Export G-code...", 'Export current plate as G-code', sub { $plater->export_gcode; }, undef, 'cog_go.png'); - $self->_append_menu_item($self->{plater_menu}, "Export plate as STL...", 'Export current plate as STL', sub { + wxTheApp->append_menu_item($self->{plater_menu}, "Export plate as STL...", 'Export current plate as STL', sub { $plater->export_stl; }, undef, 'brick_go.png'); - $self->_append_menu_item($self->{plater_menu}, "Export plate with modifiers as AMF...", 'Export current plate as AMF, including all modifier meshes', sub { + wxTheApp->append_menu_item($self->{plater_menu}, "Export plate with modifiers as AMF...", 'Export current plate as AMF, including all modifier meshes', sub { $plater->export_amf; }, undef, 'brick_go.png'); @@ -201,13 +200,13 @@ sub _init_menubar { # Settings menu my $settingsMenu = Wx::Menu->new; { - $self->_append_menu_item($settingsMenu, "P&rint Settings…\tCtrl+1", 'Show the print settings editor', sub { + wxTheApp->append_menu_item($settingsMenu, "P&rint Settings…\tCtrl+1", 'Show the print settings editor', sub { $self->{plater}->show_preset_editor('print'); }, undef, 'cog.png'); - $self->_append_menu_item($settingsMenu, "&Filament Settings…\tCtrl+2", 'Show the filament settings editor', sub { + wxTheApp->append_menu_item($settingsMenu, "&Filament Settings…\tCtrl+2", 'Show the filament settings editor', sub { $self->{plater}->show_preset_editor('filament'); }, undef, 'spool.png'); - $self->_append_menu_item($settingsMenu, "Print&er Settings…\tCtrl+3", 'Show the printer settings editor', sub { + wxTheApp->append_menu_item($settingsMenu, "Print&er Settings…\tCtrl+3", 'Show the printer settings editor', sub { $self->{plater}->show_preset_editor('printer'); }, undef, 'printer_empty.png'); } @@ -215,15 +214,15 @@ sub _init_menubar { # View menu { $self->{viewMenu} = Wx::Menu->new; - $self->_append_menu_item($self->{viewMenu}, "Top\tCtrl+4" , 'Top View' , sub { $self->select_view('top' ); }); - $self->_append_menu_item($self->{viewMenu}, "Bottom\tCtrl+5" , 'Bottom View' , sub { $self->select_view('bottom' ); }); - $self->_append_menu_item($self->{viewMenu}, "Left\tCtrl+6" , 'Left View' , sub { $self->select_view('left' ); }); - $self->_append_menu_item($self->{viewMenu}, "Right\tCtrl+7" , 'Right View' , sub { $self->select_view('right' ); }); - $self->_append_menu_item($self->{viewMenu}, "Front\tCtrl+8" , 'Front View' , sub { $self->select_view('front' ); }); - $self->_append_menu_item($self->{viewMenu}, "Back\tCtrl+9" , 'Back View' , sub { $self->select_view('back' ); }); - $self->_append_menu_item($self->{viewMenu}, "Diagonal\tCtrl+0", 'Diagonal View', sub { $self->select_view('diagonal'); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Top\tCtrl+4" , 'Top View' , sub { $self->select_view('top' ); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Bottom\tCtrl+5" , 'Bottom View' , sub { $self->select_view('bottom' ); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Left\tCtrl+6" , 'Left View' , sub { $self->select_view('left' ); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Right\tCtrl+7" , 'Right View' , sub { $self->select_view('right' ); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Front\tCtrl+8" , 'Front View' , sub { $self->select_view('front' ); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Back\tCtrl+9" , 'Back View' , sub { $self->select_view('back' ); }); + wxTheApp->append_menu_item($self->{viewMenu}, "Diagonal\tCtrl+0", 'Diagonal View', sub { $self->select_view('diagonal'); }); $self->{viewMenu}->AppendSeparator(); - $self->{color_toolpaths_by_role} = $self->_append_menu_item($self->{viewMenu}, + $self->{color_toolpaths_by_role} = wxTheApp->append_menu_item($self->{viewMenu}, "Color Toolpaths by Role", 'Color toolpaths according to perimeter/infill/support material', sub { @@ -233,7 +232,7 @@ sub _init_menubar { }, undef, undef, wxITEM_RADIO ); - $self->{color_toolpaths_by_extruder} = $self->_append_menu_item($self->{viewMenu}, + $self->{color_toolpaths_by_extruder} = wxTheApp->append_menu_item($self->{viewMenu}, "Color Toolpaths by Filament", 'Color toolpaths using the configured extruder/filament color', sub { @@ -253,13 +252,13 @@ sub _init_menubar { # Window menu my $windowMenu = Wx::Menu->new; { - $self->_append_menu_item($windowMenu, "&Plater\tCtrl+T", 'Show the plater', sub { + wxTheApp->append_menu_item($windowMenu, "&Plater\tCtrl+T", 'Show the plater', sub { $self->select_tab(0); }, undef, 'application_view_tile.png'); - $self->_append_menu_item($windowMenu, "&Controller\tCtrl+Y", 'Show the printer controller', sub { + wxTheApp->append_menu_item($windowMenu, "&Controller\tCtrl+Y", 'Show the printer controller', sub { $self->select_tab(1); }, undef, 'printer_empty.png') unless ($Slic3r::GUI::Settings->{_}{no_controller}); - $self->_append_menu_item($windowMenu, "DLP Projector…\tCtrl+P", 'Open projector window for DLP printing', sub { + wxTheApp->append_menu_item($windowMenu, "DLP Projector…\tCtrl+P", 'Open projector window for DLP printing', sub { $self->{plater}->pause_background_process; Slic3r::GUI::SLAPrintOptions->new($self)->ShowModal; $self->{plater}->resume_background_process; @@ -269,22 +268,22 @@ sub _init_menubar { # Help menu my $helpMenu = Wx::Menu->new; { - $self->_append_menu_item($helpMenu, "&Configuration $Slic3r::GUI::ConfigWizard::wizard…", "Run Configuration $Slic3r::GUI::ConfigWizard::wizard", sub { + wxTheApp->append_menu_item($helpMenu, "&Configuration $Slic3r::GUI::ConfigWizard::wizard…", "Run Configuration $Slic3r::GUI::ConfigWizard::wizard", sub { $self->config_wizard; }); $helpMenu->AppendSeparator(); - $self->_append_menu_item($helpMenu, "Slic3r &Website", 'Open the Slic3r website in your browser', sub { + wxTheApp->append_menu_item($helpMenu, "Slic3r &Website", 'Open the Slic3r website in your browser', sub { Wx::LaunchDefaultBrowser('http://slic3r.org/'); }); - my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub { + my $versioncheck = wxTheApp->append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub { wxTheApp->check_version(1); }); $versioncheck->Enable(wxTheApp->have_version_check); - $self->_append_menu_item($helpMenu, "Slic3r &Manual", 'Open the Slic3r manual in your browser', sub { + wxTheApp->append_menu_item($helpMenu, "Slic3r &Manual", 'Open the Slic3r manual in your browser', sub { Wx::LaunchDefaultBrowser('http://manual.slic3r.org/'); }); $helpMenu->AppendSeparator(); - $self->_append_menu_item($helpMenu, "&About Slic3r", 'Show about dialog', sub { + wxTheApp->append_menu_item($helpMenu, "&About Slic3r", 'Show about dialog', sub { wxTheApp->about; }); } @@ -631,15 +630,4 @@ sub select_view { $self->{plater}->select_view($direction); } -sub _append_menu_item { - my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_; - - $id //= &Wx::NewId(); - my $item = $menu->Append($id, $string, $description, $kind); - wxTheApp->set_menu_item_icon($item, $icon); - - EVT_MENU($self, $id, $cb); - return $item; -} - 1; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 5df6e6766..57c33c7ed 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1962,7 +1962,7 @@ sub on_model_change { if ($count > 1) { $name .= " (${count}x)"; } - my $item = $self->GetFrame->_append_menu_item($menu, $name, 'Select object', sub { + my $item = wxTheApp->append_menu_item($menu, $name, 'Select object', sub { $self->select_object($i); $self->refresh_canvases; }, undef, undef, wxITEM_CHECK); @@ -2313,105 +2313,109 @@ sub object_menu { my $frame = $self->GetFrame; my $menu = Wx::Menu->new; - $frame->_append_menu_item($menu, "Delete\tCtrl+Del", 'Remove the selected object', sub { + wxTheApp->append_menu_item($menu, "Delete\tCtrl+Del", 'Remove the selected object', sub { $self->remove; }, undef, 'brick_delete.png'); - $frame->_append_menu_item($menu, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub { + wxTheApp->append_menu_item($menu, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub { $self->increase; }, undef, 'add.png'); - $frame->_append_menu_item($menu, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub { + wxTheApp->append_menu_item($menu, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub { $self->decrease; }, undef, 'delete.png'); - $frame->_append_menu_item($menu, "Set number of copies…", 'Change the number of copies of the selected object', sub { + wxTheApp->append_menu_item($menu, "Set number of copies…", 'Change the number of copies of the selected object', sub { $self->set_number_of_copies; }, undef, 'textfield.png'); $menu->AppendSeparator(); - $frame->_append_menu_item($menu, "Move to bed center", 'Center object around bed center', sub { + wxTheApp->append_menu_item($menu, "Move to bed center", 'Center object around bed center', sub { $self->center_selected_object_on_bed; }, undef, 'arrow_in.png'); - $frame->_append_menu_item($menu, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub { + wxTheApp->append_menu_item($menu, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub { $self->rotate(-45); }, undef, 'arrow_rotate_clockwise.png'); - $frame->_append_menu_item($menu, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub { + wxTheApp->append_menu_item($menu, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub { $self->rotate(+45); }, undef, 'arrow_rotate_anticlockwise.png'); - my $rotateMenu = Wx::Menu->new; - my $rotateMenuItem = $menu->AppendSubMenu($rotateMenu, "Rotate", 'Rotate the selected object by an arbitrary angle'); - wxTheApp->set_menu_item_icon($rotateMenuItem, 'textfield.png'); - $frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub { - $self->rotate(undef, X); - }, undef, 'bullet_red.png'); - $frame->_append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub { - $self->rotate(undef, Y); - }, undef, 'bullet_green.png'); - $frame->_append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub { - $self->rotate(undef, Z); - }, undef, 'bullet_blue.png'); + { + my $rotateMenu = Wx::Menu->new; + wxTheApp->append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub { + $self->rotate(undef, X); + }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub { + $self->rotate(undef, Y); + }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub { + $self->rotate(undef, Z); + }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Rotate", 'Rotate the selected object by an arbitrary angle', $rotateMenu, undef, 'textfield.png'); + } - my $mirrorMenu = Wx::Menu->new; - my $mirrorMenuItem = $menu->AppendSubMenu($mirrorMenu, "Mirror", 'Mirror the selected object'); - wxTheApp->set_menu_item_icon($mirrorMenuItem, 'shape_flip_horizontal.png'); - $frame->_append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub { - $self->mirror(X); - }, undef, 'bullet_red.png'); - $frame->_append_menu_item($mirrorMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub { - $self->mirror(Y); - }, undef, 'bullet_green.png'); - $frame->_append_menu_item($mirrorMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub { - $self->mirror(Z); - }, undef, 'bullet_blue.png'); + { + my $mirrorMenu = Wx::Menu->new; + wxTheApp->append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub { + $self->mirror(X); + }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($mirrorMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub { + $self->mirror(Y); + }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($mirrorMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub { + $self->mirror(Z); + }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Mirror", 'Mirror the selected object', $mirrorMenu, undef, 'shape_flip_horizontal.png'); + } - my $scaleMenu = Wx::Menu->new; - my $scaleMenuItem = $menu->AppendSubMenu($scaleMenu, "Scale", 'Scale the selected object along a single axis'); - wxTheApp->set_menu_item_icon($scaleMenuItem, 'arrow_out.png'); - $frame->_append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub { - $self->changescale(undef); - }); - $frame->_append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis', sub { - $self->changescale(X); - }, undef, 'bullet_red.png'); - $frame->_append_menu_item($scaleMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub { - $self->changescale(Y); - }, undef, 'bullet_green.png'); - $frame->_append_menu_item($scaleMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { - $self->changescale(Z); - }, undef, 'bullet_blue.png'); + { + my $scaleMenu = Wx::Menu->new; + wxTheApp->append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub { + $self->changescale(undef); + }); + wxTheApp->append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis', sub { + $self->changescale(X); + }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($scaleMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub { + $self->changescale(Y); + }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($scaleMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { + $self->changescale(Z); + }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Scale", 'Scale the selected object by a given factor', $scaleMenu, undef, 'arrow_out.png'); + } - my $scaleToSizeMenu = Wx::Menu->new; - my $scaleToSizeMenuItem = $menu->AppendSubMenu($scaleToSizeMenu, "Scale to size", 'Scale the selected object along a single axis'); - wxTheApp->set_menu_item_icon($scaleToSizeMenuItem, 'arrow_out.png'); - $frame->_append_menu_item($scaleToSizeMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub { - $self->changescale(undef, 1); - }); - $frame->_append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', sub { - $self->changescale(X, 1); - }, undef, 'bullet_red.png'); - $frame->_append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub { - $self->changescale(Y, 1); - }, undef, 'bullet_green.png'); - $frame->_append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { - $self->changescale(Z, 1); - }, undef, 'bullet_blue.png'); + { + my $scaleToSizeMenu = Wx::Menu->new; + wxTheApp->append_menu_item($scaleToSizeMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub { + $self->changescale(undef, 1); + }); + wxTheApp->append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', sub { + $self->changescale(X, 1); + }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub { + $self->changescale(Y, 1); + }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { + $self->changescale(Z, 1); + }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Scale to size", 'Scale the selected object to match a given size', $scaleToSizeMenu, undef, 'arrow_out.png'); + } - $frame->_append_menu_item($menu, "Split", 'Split the selected object into individual parts', sub { + wxTheApp->append_menu_item($menu, "Split", 'Split the selected object into individual parts', sub { $self->split_object; }, undef, 'shape_ungroup.png'); - $frame->_append_menu_item($menu, "Cut…", 'Open the 3D cutting tool', sub { + wxTheApp->append_menu_item($menu, "Cut…", 'Open the 3D cutting tool', sub { $self->object_cut_dialog; }, undef, 'package.png'); $menu->AppendSeparator(); - $frame->_append_menu_item($menu, "Settings…", 'Open the object editor dialog', sub { + wxTheApp->append_menu_item($menu, "Settings…", 'Open the object editor dialog', sub { $self->object_settings_dialog; }, undef, 'cog.png'); $menu->AppendSeparator(); - $frame->_append_menu_item($menu, "Reload from Disk", 'Reload the selected file from Disk', sub { + wxTheApp->append_menu_item($menu, "Reload from Disk", 'Reload the selected file from Disk', sub { $self->reload_from_disk; }, undef, 'arrow_refresh.png'); - $frame->_append_menu_item($menu, "Export object as STL…", 'Export this single object as STL file', sub { + wxTheApp->append_menu_item($menu, "Export object as STL…", 'Export this single object as STL file', sub { $self->export_object_stl; }, undef, 'brick_go.png'); - $frame->_append_menu_item($menu, "Export object and modifiers as AMF…", 'Export this single object and all associated modifiers as AMF file', sub { + wxTheApp->append_menu_item($menu, "Export object and modifiers as AMF…", 'Export this single object and all associated modifiers as AMF file', sub { $self->export_object_amf; }, undef, 'brick_go.png'); diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index 17090438d..308627b3f 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -163,35 +163,30 @@ sub new { my $item = $event->GetItem; my $frame = $self->GetFrame; my $menu = Wx::Menu->new; - - my $scaleToSizeMenu = Wx::Menu->new; - my $scaleToSizeMenuItem = $menu->AppendSubMenu($scaleToSizeMenu, "Scale to size", 'Scale the selected object along a single axis'); - wxTheApp->set_menu_item_icon($scaleToSizeMenuItem, 'arrow_out.png'); - $frame->_append_menu_item($scaleToSizeMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes', sub { - $self->changescale(undef, 1); - }); - $frame->_append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', sub { - $self->changescale(X, 1); - }, undef, 'bullet_red.png'); - $frame->_append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub { - $self->changescale(Y, 1); - }, undef, 'bullet_green.png'); - $frame->_append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { - $self->changescale(Z, 1); - }, undef, 'bullet_blue.png'); - my $rotateMenu = Wx::Menu->new; - my $rotateMenuItem = $menu->AppendSubMenu($rotateMenu, "Rotate", 'Rotate the selected object by an arbitrary angle'); - wxTheApp->set_menu_item_icon($rotateMenuItem, 'textfield.png'); - $frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub { - $self->rotate(undef, X); - }, undef, 'bullet_red.png'); - $frame->_append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub { - $self->rotate(undef, Y); - }, undef, 'bullet_green.png'); - $frame->_append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub { - $self->rotate(undef, Z); - }, undef, 'bullet_blue.png'); - + + { + my $scaleToSizeMenu = Wx::Menu->new; + wxTheApp->append_menu_item($scaleToSizeMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes', + sub { $self->changescale(undef, 1) }); + wxTheApp->append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', + sub { $self->changescale(X, 1) }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', + sub { $self->changescale(Y, 1) }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', + sub { $self->changescale(Z, 1) }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Scale to size", 'Scale the selected object along a single axis', + $scaleToSizeMenu, undef, 'arrow_out.png'); + } + { + my $rotateMenu = Wx::Menu->new; + wxTheApp->append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', + sub { $self->rotate(undef, X) }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', + sub { $self->rotate(undef, Y) }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', + sub { $self->rotate(undef, Z) }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Rotate", 'Rotate the selected object by an arbitrary angle', $rotateMenu, undef, 'textfield.png'); + } $frame->PopupMenu($menu, $event->GetPoint); }); EVT_BUTTON($self, $self->{btn_load_part}, sub { $self->on_btn_load(0) }); diff --git a/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm b/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm index 2cca0d901..854748765 100644 --- a/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm @@ -53,16 +53,6 @@ sub PartSettingsChanged { my ($self) = @_; return $self->{parts}->PartSettingsChanged || $self->{layers}->LayersChanged; } -sub _append_menu_item { - my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_; - - $id //= &Wx::NewId(); - my $item = $menu->Append($id, $string, $description, $kind); - wxTheApp->set_menu_item_icon($item, $icon); - - EVT_MENU($self, $id, $cb); - return $item; -} package Slic3r::GUI::Plater::ObjectDialog::BaseTab; diff --git a/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm b/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm index 8e5e6b52b..9e91a7a56 100644 --- a/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm +++ b/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm @@ -53,8 +53,6 @@ sub new { my $menu = Wx::Menu->new; my $last_cat = ''; foreach my $opt_key (@{$self->{options}}) { - my $id = &Wx::NewId(); - # add icon, if we have one for this category my $icon; if (my $cat = $Slic3r::Config::Options->{$opt_key}{category}) { @@ -65,14 +63,14 @@ sub new { $icon = $icons{$cat}; } - my $menuItem = $menu->Append($id, $self->{option_labels}{$opt_key}); - wxTheApp->set_menu_item_icon($menuItem, $icon) if $icon; - - EVT_MENU($menu, $id, sub { + my $cb = sub { $self->{config}->set($opt_key, $self->{default_config}->get($opt_key)); $self->update_optgroup; $self->{on_change}->($opt_key) if $self->{on_change}; - }); + }; + + wxTheApp->append_menu_item($menu, $self->{option_labels}{$opt_key}, + $Slic3r::Config::Options->{$opt_key}{tooltip}, $cb, undef, $icon); } $self->PopupMenu($menu, $btn->GetPosition); $menu->Destroy; From 3ddcb952114bd03b469e4115bcaf5fa44b7c5c2a Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 27 Apr 2017 12:46:08 +0200 Subject: [PATCH 19/22] Bugfix: background processing was not triggered when loading files from command line. #3887 --- lib/Slic3r/GUI/Plater.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 57c33c7ed..3cbee451b 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -323,7 +323,6 @@ sub new { if ($self->{preview3D}) { $self->{preview3D}->set_bed_shape($self->{config}->bed_shape); } - $self->on_model_change; { my $presets = $self->{presets_sizer} = Wx::FlexGridSizer->new(3, 3, 1, 2); @@ -887,6 +886,11 @@ sub load_file { sub load_model_objects { my ($self, @model_objects) = @_; + # Always restart background process when adding new objects. + # This prevents lack of processing in some circumstances when background process is + # running but adding a new object does not invalidate anything. + $self->stop_background_process; + my $bed_centerf = $self->bed_centerf; my $bed_shape = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape}); my $bed_size = $bed_shape->bounding_box->size; From 5257f373e7c7fe041dca059872fb206e05b4056c Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 29 Apr 2017 10:38:00 +0200 Subject: [PATCH 20/22] Bugfix: some lifts were skipped when retract_lift == layer_height and retract_layer_change = yes. #3904 --- t/retraction.t | 68 ++++++++++++++++++++++++++++---- xs/src/libslic3r/GCodeWriter.cpp | 9 ++++- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/t/retraction.t b/t/retraction.t index 571e9755d..237af3abf 100644 --- a/t/retraction.t +++ b/t/retraction.t @@ -1,4 +1,4 @@ -use Test::More tests => 26; +use Test::More tests => 27; use strict; use warnings; @@ -10,6 +10,7 @@ BEGIN { use List::Util qw(any); use Slic3r; +use Slic3r::Geometry qw(epsilon); use Slic3r::Test qw(_eq); { @@ -209,20 +210,55 @@ use Slic3r::Test qw(_eq); my $config = Slic3r::Config->new_from_defaults; $config->set('start_gcode', ''); $config->set('retract_lift', [3, 4]); + $config->set('only_retract_when_crossing_perimeters', 0); my @lifted_at = (); my $test = sub { my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2); @lifted_at = (); + my $retracted = 0; + my $lifted = 0; + my $tool = 0; Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { my ($self, $cmd, $args, $info) = @_; - if ($cmd eq 'G1' && $info->{dist_Z} < 0) { - push @lifted_at, $info->{new_Z}; + if ($cmd eq 'G1') { + if ($info->{dist_Z} < 0) { + # going downwards; this is a "restore lift" move + $lifted = 0; + push @lifted_at, $info->{new_Z}; + } elsif (abs($info->{dist_Z} - $config->get_at('retract_lift', $tool)) < &epsilon) { + # going upwards by a large amount; this is a lift move + fail 'always lift after retraction' if !$retracted; + ### It would be useful to prevent the double lift happening at layer change: + ###fail 'no double lift' if $lifted; + $lifted = 1; + } elsif ($info->{retracting}) { + $retracted = 1; + } elsif ($info->{extruding} && $info->{dist_XY} == 0) { + # consider the lift as layer change if they are configured with the same distance + $lifted = 0 if $config->get_at('retract_lift', $tool) == $config->layer_height; + fail 'always unretract after unlifting' if $lifted; + $retracted = 0; + } elsif ($info->{travel} && $info->{dist_XY} >= $config->get_at('retract_before_travel', $tool)) { + #printf "dist_XY = %f, rbt = %f\n", $info->{dist_XY}, $config->get_at('retract_before_travel', 0); + my $below = $config->get_at('retract_lift_below', $tool); + fail 'no retraction for long travel move' if !$retracted; + fail 'no lift for long travel move' + if !$lifted + && $self->Z >= $config->get_at('retract_lift_above', $tool) + && ($below == 0 || $self->Z <= $below); + } + } elsif ($cmd =~ /^T(\d+)/) { + $tool = $1; } }); }; + $config->set('retract_layer_change', [1,1]); + $test->(); + ok !!@lifted_at, 'lift is compatible with retract_layer_change'; + $config->set('retract_lift_above', [0, 0]); $config->set('retract_lift_below', [0, 0]); $test->(); @@ -234,9 +270,13 @@ use Slic3r::Test qw(_eq); ok !!@lifted_at, 'lift takes place when above/below != 0'; ok !(any { $_ < $config->get_at('retract_lift_above', 0) } @lifted_at), 'Z is not lifted below the configured value'; - ok !(any { $_ > $config->get_at('retract_lift_below', 0) } @lifted_at), - 'Z is not lifted above the configured value'; - + { + my $below = $config->get_at('retract_lift_below', 0); + $below += $config->layer_height if $config->get_at('retract_layer_change', 0); + ok !(any { $_ > $below } @lifted_at), + 'Z is not lifted above the configured value'; + } + # check lifting with different values for 2. extruder $config->set('perimeter_extruder', 2); $config->set('infill_extruder', 2); @@ -251,8 +291,20 @@ use Slic3r::Test qw(_eq); ok !!@lifted_at, 'lift takes place when above/below != 0 for 2. extruder'; ok !(any { $_ < $config->get_at('retract_lift_above', 1) } @lifted_at), 'Z is not lifted below the configured value for 2. extruder'; - ok !(any { $_ > $config->get_at('retract_lift_below', 1) } @lifted_at), - 'Z is not lifted above the configured value for 2. extruder'; + { + my $below = $config->get_at('retract_lift_below', 1); + $below += $config->layer_height if $config->get_at('retract_layer_change', 1); + ok !(any { $_ > $below } @lifted_at), + 'Z is not lifted above the configured value for 2. extruder'; + } + + $config->set('retract_lift', [$config->layer_height]); + $config->set('perimeter_extruder', 1); + $config->set('infill_extruder', 1); + $config->set('retract_lift_above', [0, 0]); + $config->set('retract_lift_below', [0, 0]); + $test->(); + } __END__ diff --git a/xs/src/libslic3r/GCodeWriter.cpp b/xs/src/libslic3r/GCodeWriter.cpp index 6ff652611..e37be8181 100644 --- a/xs/src/libslic3r/GCodeWriter.cpp +++ b/xs/src/libslic3r/GCodeWriter.cpp @@ -330,7 +330,7 @@ GCodeWriter::travel_to_z(double z, const std::string &comment) reducing the lift amount that will be used for unlift. */ if (!this->will_move_z(z)) { double nominal_z = this->_pos.z - this->_lifted; - this->_lifted = this->_lifted - (z - nominal_z); + this->_lifted -= (z - nominal_z); return ""; } @@ -500,10 +500,15 @@ GCodeWriter::lift() if (this->_pos.z >= above && (below == 0 || this->_pos.z <= below)) target_lift = this->config.retract_lift.get_at(this->_extruder->id); } - if (this->_lifted == 0 && target_lift > 0) { + + // compare against epsilon because travel_to_z() does math on it + // and subtracting layer_height from retract_lift might not give + // exactly zero + if (std::abs(this->_lifted) < EPSILON && target_lift > 0) { this->_lifted = target_lift; return this->_travel_to_z(this->_pos.z + target_lift, "lift Z"); } + return ""; } From cc1c9b0920e1cb838f2203eeb4c432a90e738f31 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 29 Apr 2017 12:27:23 +0200 Subject: [PATCH 21/22] Some fixes and additions to the scale/rotate commands in the object parts dialog. #3900 --- lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index 308627b3f..e0fe90f6e 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -164,6 +164,19 @@ sub new { my $frame = $self->GetFrame; my $menu = Wx::Menu->new; + { + my $scaleMenu = Wx::Menu->new; + wxTheApp->append_menu_item($scaleMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes', + sub { $self->changescale(undef, 0) }); + wxTheApp->append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis', + sub { $self->changescale(X, 0) }, undef, 'bullet_red.png'); + wxTheApp->append_menu_item($scaleMenu, "Along Y axis…", 'Scale the selected object along the Y axis', + sub { $self->changescale(Y, 0) }, undef, 'bullet_green.png'); + wxTheApp->append_menu_item($scaleMenu, "Along Z axis…", 'Scale the selected object along the Z axis', + sub { $self->changescale(Z, 0) }, undef, 'bullet_blue.png'); + wxTheApp->append_submenu($menu, "Scale", 'Scale the selected object by a given factor', + $scaleMenu, undef, 'arrow_out.png'); + } { my $scaleToSizeMenu = Wx::Menu->new; wxTheApp->append_menu_item($scaleToSizeMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes', @@ -174,7 +187,7 @@ sub new { sub { $self->changescale(Y, 1) }, undef, 'bullet_green.png'); wxTheApp->append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub { $self->changescale(Z, 1) }, undef, 'bullet_blue.png'); - wxTheApp->append_submenu($menu, "Scale to size", 'Scale the selected object along a single axis', + wxTheApp->append_submenu($menu, "Scale to size", 'Scale the selected object to match a given size', $scaleToSizeMenu, undef, 'arrow_out.png'); } { @@ -185,7 +198,8 @@ sub new { sub { $self->rotate(undef, Y) }, undef, 'bullet_green.png'); wxTheApp->append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub { $self->rotate(undef, Z) }, undef, 'bullet_blue.png'); - wxTheApp->append_submenu($menu, "Rotate", 'Rotate the selected object by an arbitrary angle', $rotateMenu, undef, 'textfield.png'); + wxTheApp->append_submenu($menu, "Rotate", 'Rotate the selected object by an arbitrary angle', + $rotateMenu, undef, 'arrow_rotate_anticlockwise.png'); } $frame->PopupMenu($menu, $event->GetPoint); }); @@ -404,7 +418,6 @@ sub on_btn_lambda { # set a default extruder value, since user can't add it manually $new_volume->config->set_ifndef('extruder', 0); - $self->{parts_changed} = 1; $self->_parts_changed($self->{model_object}->volumes_count-1); } @@ -431,6 +444,7 @@ sub on_btn_delete { sub _parts_changed { my ($self, $selected_volume_idx) = @_; + $self->{parts_changed} = 1; $self->reload_tree($selected_volume_idx); if ($self->{canvas}) { $self->{canvas}->reset_objects; From 1a788196fada65528fc28ced144d9d5c9537412a Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 29 Apr 2017 14:13:14 +0200 Subject: [PATCH 22/22] Try to fix LWP not working in packages. #3906 --- package/linux/make_archive.sh | 2 +- package/osx/make_dmg.sh | 2 +- package/win/package_win32.ps1 | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package/linux/make_archive.sh b/package/linux/make_archive.sh index 422ac19a0..7b0503b15 100755 --- a/package/linux/make_archive.sh +++ b/package/linux/make_archive.sh @@ -96,7 +96,7 @@ cp -f $PERL_BIN $archivefolder/perl-local ${PP_BIN} wxextension .0 \ -M attributes -M base -M bytes -M B -M POSIX \ -M FindBin -M Unicode::Normalize -M Tie::Handle \ - -M Time::Local -M Math::Trig \ + -M Time::Local -M Math::Trig -M IO::Socket -M Errno \ -M lib -M overload \ -M warnings -M local::lib \ -M strict -M utf8 -M parent \ diff --git a/package/osx/make_dmg.sh b/package/osx/make_dmg.sh index 8167e6d06..eb9c5ce60 100755 --- a/package/osx/make_dmg.sh +++ b/package/osx/make_dmg.sh @@ -101,7 +101,7 @@ echo "Copying perl from $PERL_BIN" cp -f $PERL_BIN $macosfolder/perl-local ${PP_BIN} -M attributes -M base -M bytes -M B -M POSIX \ -M FindBin -M Unicode::Normalize -M Tie::Handle \ - -M Time::Local -M Math::Trig \ + -M Time::Local -M Math::Trig -M IO::Socket -M Errno \ -M lib -M overload \ -M warnings -M local::lib \ -M strict -M utf8 -M parent \ diff --git a/package/win/package_win32.ps1 b/package/win/package_win32.ps1 index 07396ea37..8c1cc977a 100644 --- a/package/win/package_win32.ps1 +++ b/package/win/package_win32.ps1 @@ -93,6 +93,7 @@ pp ` -M IO ` -M IO::Handle ` -M IO::Select ` +-M IO::Socket ` -M LWP ` -M LWP::MediaTypes ` -M LWP::MemberMixin `