From 97c65bac90191f5d286fd3f24c31c486e76d5c12 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 23 Nov 2013 22:43:30 +0100 Subject: [PATCH 1/5] Do perimeters one island at time instead of doing all holes before all contours --- lib/Slic3r/Layer/Region.pm | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 312dce32a..b10b2dac5 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -242,7 +242,21 @@ sub make_perimeters { )}; my @loops = (); + foreach my $polynode (@nodes) { + # if this is an external contour find all holes belonging to this contour(s) + # and prepend them + if ($is_contour && $depth == 0) { + # $polynode is the outermost loop of an island + my @holes = (); + for (my $i = 0; $i <= $#$holes_pt; $i++) { + if ($polynode->{outer}->encloses_point($holes_pt->[$i]{outer}->first_point)) { + push @holes, splice @$holes_pt, $i, 1; # remove from candidates to reduce complexity + $i--; + } + } + push @loops, reverse map $traverse->([$_], 0), @holes; + } push @loops, $traverse->($polynode->{children}, $depth+1, $is_contour); # return ccw contours and cw holes @@ -272,10 +286,7 @@ sub make_perimeters { }; # order loops from inner to outer (in terms of object slices) - my @loops = ( - (reverse $traverse->($holes_pt, 0)), - $traverse->($contours_pt, 0, 1), - ); + my @loops = $traverse->($contours_pt, 0, 1); # if brim will be printed, reverse the order of perimeters so that # we continue inwards after having finished the brim From 5217bc370a2941221322c26c8cb08b6de4c0e0fd Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Nov 2013 12:37:36 +0100 Subject: [PATCH 2/5] Fix regression causing retraction restarts to ignore extrusion_axis. Includes regression test. #1547 --- lib/Slic3r/GCode.pm | 3 ++- t/gcode.t | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 4563cd734..9ae5d952a 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -546,7 +546,8 @@ sub unretract { $gcode .= "G11 ; unretract\n"; } elsif ($self->config->extrusion_axis) { # use G1 instead of G0 because G0 will blend the restart with the previous travel move - $gcode .= sprintf "G1 E%.5f F%.3f", + $gcode .= sprintf "G1 %s%.5f F%.3f", + $self->config->extrusion_axis, $self->extruder->extrude($to_unretract), $self->extruder->retract_speed_mm_min; $gcode .= " ; compensate retraction" if $self->config->gcode_comments; diff --git a/t/gcode.t b/t/gcode.t index bb51698d4..f8ee4158c 100644 --- a/t/gcode.t +++ b/t/gcode.t @@ -46,8 +46,13 @@ use Slic3r::Test; my $config = Slic3r::Config->new_from_defaults; $config->set('complete_objects', 1); $config->set('duplicate', 2); + $config->set('extrusion_axis', 'A'); my $print = Slic3r::Test::init_print('20mm_cube', config => $config); - ok Slic3r::Test::gcode($print), "complete_objects"; + ok my $gcode = Slic3r::Test::gcode($print), "complete_objects"; + Slic3r::GCode::Reader->new->parse($gcode, sub { + my ($self, $cmd, $args, $info) = @_; + fail 'unexpected E argument' if defined $args->{E}; + }); } __END__ From 387df3b90024f99c4cd540488374ab41c60ddb60 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Nov 2013 13:04:16 +0100 Subject: [PATCH 3/5] Fix regression causing toolchange_gcode to crash Slic3r. Includes regression test. #1545 --- lib/Slic3r/GCode.pm | 8 +++++++- lib/Slic3r/GCode/Layer.pm | 2 +- lib/Slic3r/Print.pm | 12 ++++-------- t/multi.t | 1 + 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 9ae5d952a..c89d98c82 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -8,6 +8,7 @@ use Slic3r::Geometry::Clipper qw(union_ex); use Slic3r::Surface ':types'; has 'config' => (is => 'ro', required => 1); +has 'extra_variables' => (is => 'rw', default => sub {{}}); has 'extruders' => (is => 'ro', required => 1); has 'multiple_extruders' => (is => 'lazy'); has 'standby_points' => (is => 'rw'); @@ -642,7 +643,7 @@ sub set_extruder { # append custom toolchange G-code if (defined $self->extruder && $self->config->toolchange_gcode) { - $gcode .= sprintf "%s\n", $self->print->replace_variables($self->config->toolchange_gcode, { + $gcode .= sprintf "%s\n", $self->replace_variables($self->config->toolchange_gcode, { previous_extruder => $self->extruder->id, next_extruder => $extruder->id, }); @@ -741,4 +742,9 @@ sub set_bed_temperature { return $gcode; } +sub replace_variables { + my ($self, $string, $extra) = @_; + return $self->config->replace_options($string, { %{$self->extra_variables}, %{ $extra || {} } }); +} + 1; diff --git a/lib/Slic3r/GCode/Layer.pm b/lib/Slic3r/GCode/Layer.pm index 1fd709693..8709ed8e9 100644 --- a/lib/Slic3r/GCode/Layer.pm +++ b/lib/Slic3r/GCode/Layer.pm @@ -66,7 +66,7 @@ sub process_layer { # set new layer - this will change Z and force a retraction if retract_layer_change is enabled $gcode .= $self->gcodegen->change_layer($layer); - $gcode .= $self->print->replace_variables($Slic3r::Config->layer_gcode, { + $gcode .= $self->gcodegen->replace_variables($Slic3r::Config->layer_gcode, { layer_num => $self->gcodegen->layer->id, }) . "\n" if $Slic3r::Config->layer_gcode; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index a9c9ef333..ed0d8068f 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -726,6 +726,7 @@ sub write_gcode { # set up our extruder object my $gcodegen = Slic3r::GCode->new( config => $self->config, + extra_variables => $self->extra_variables, extruders => $self->extruders, # we should only pass the *used* extruders (but maintain the Tx indices right!) layer_count => $self->layer_count, ); @@ -749,7 +750,7 @@ sub write_gcode { } }; $print_first_layer_temperature->(0); - printf $fh "%s\n", $self->replace_variables($Slic3r::Config->start_gcode); + printf $fh "%s\n", $gcodegen->replace_variables($Slic3r::Config->start_gcode); $print_first_layer_temperature->(1); # set other general things @@ -902,7 +903,7 @@ sub write_gcode { # write end commands to file print $fh $gcodegen->retract if $gcodegen->extruder; # empty prints don't even set an extruder print $fh $gcodegen->set_fan(0); - printf $fh "%s\n", $self->replace_variables($Slic3r::Config->end_gcode); + printf $fh "%s\n", $gcodegen->replace_variables($Slic3r::Config->end_gcode); foreach my $extruder (@{$self->extruders}) { printf $fh "; filament used = %.1fmm (%.1fcm3)\n", @@ -949,12 +950,7 @@ sub expanded_output_filepath { # path is a full path to a file so we use it as it is } - return $self->replace_variables($path, $extra_variables); -} - -sub replace_variables { - my ($self, $string, $extra) = @_; - return $self->config->replace_options($string, { %{$self->extra_variables}, %{ $extra || {} } }); + return $self->config->replace_options($path, { %{$self->extra_variables}, %$extra_variables }); } # given the path to a file, this function returns its filename with and without extension diff --git a/t/multi.t b/t/multi.t index d338a2d4e..c7214e8b9 100644 --- a/t/multi.t +++ b/t/multi.t @@ -22,6 +22,7 @@ use Slic3r::Test; $config->set('extruder_offset', [ [0,0], [20,0], [0,20] ]); $config->set('temperature', [200, 180, 170]); $config->set('first_layer_temperature', [206, 186, 166]); + $config->set('toolchange_gcode', ';toolchange'); # test that it doesn't crash when this is supplied my $print = Slic3r::Test::init_print('20mm_cube', config => $config); From 22605418ba506d77fc315ac5aee0d0db1c313681 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Nov 2013 13:08:13 +0100 Subject: [PATCH 4/5] Removed recursion warning in brim --- lib/Slic3r/Geometry/Clipper.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 9e23b6c79..0912dc564 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -13,6 +13,7 @@ use Slic3r::Geometry qw(scale); sub traverse_pt { my ($polynodes) = @_; + no warnings 'recursion'; # use a nearest neighbor search to order these children # TODO: supply second argument to chained_path_items() too? From bed1625d6b0fa92da0afb4fae2ec6d036dfbea33 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Nov 2013 14:28:17 +0100 Subject: [PATCH 5/5] Split objects could not be repositioned in plater. 3D preview and stats were not available too. #1543 --- lib/Slic3r/GUI/Plater.pm | 6 ++++-- lib/Slic3r/Model.pm | 2 +- xs/src/TriangleMesh.cpp | 3 +++ xs/src/admesh/stl.h | 2 +- xs/t/01_trianglemesh.t | 3 ++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 66d6d35cf..5eec59547 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -594,8 +594,10 @@ sub split_object { input_file_object_id => undef, model => $new_model, model_object_idx => $#{$new_model->objects}, - instances => [ map $bb->min_point, 1..$current_copies_num ], + mesh_stats => $mesh->stats, # so that we can free model + instances => [ map $bb->min_point->pp, 1..$current_copies_num ], ); + push @{ $self->{objects} }, $object; $self->object_loaded($#{ $self->{objects} }, no_arrange => 1); } @@ -1274,7 +1276,7 @@ has 'thumbnail_scaling_factor' => (is => 'rw', trigger => \&_transform_thumbnail has 'config' => (is => 'rw', default => sub { Slic3r::Config->new }); has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ] has 'material_mapping' => (is => 'rw', default => sub { {} }); # { material_id => extruder_idx } -has 'mesh_stats' => (is => 'rw'); +has 'mesh_stats' => (is => 'ro', required => 1); # statistics has 'facets' => (is => 'rw'); diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 3bddb6824..3594c9bc4 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -308,7 +308,7 @@ use Storable qw(dclone); has 'input_file' => (is => 'rw'); has 'model' => (is => 'ro', weak_ref => 1, required => 1); has 'volumes' => (is => 'ro', default => sub { [] }); -has 'instances' => (is => 'rw'); +has 'instances' => (is => 'rw'); # in unscaled coordinates has 'config' => (is => 'rw', default => sub { Slic3r::Config->new }); has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ] has 'material_mapping' => (is => 'rw', default => sub { {} }); # { material_id => extruder_idx } diff --git a/xs/src/TriangleMesh.cpp b/xs/src/TriangleMesh.cpp index bc653d8ec..9eae734c8 100644 --- a/xs/src/TriangleMesh.cpp +++ b/xs/src/TriangleMesh.cpp @@ -532,8 +532,11 @@ TriangleMesh::split() const mesh->stl.stats.original_num_facets = mesh->stl.stats.number_of_facets; stl_allocate(&mesh->stl); + int first = 1; for (std::deque::const_iterator facet = facets.begin(); facet != facets.end(); facet++) { mesh->stl.facet_start[facet - facets.begin()] = this->stl.facet_start[*facet]; + stl_facet_stats(&mesh->stl, this->stl.facet_start[*facet], first); + first = 0; } } diff --git a/xs/src/admesh/stl.h b/xs/src/admesh/stl.h index 332a5bf2f..ac4143858 100644 --- a/xs/src/admesh/stl.h +++ b/xs/src/admesh/stl.h @@ -178,6 +178,6 @@ extern void stl_initialize(stl_file *stl); static void stl_count_facets(stl_file *stl, char *file); extern void stl_allocate(stl_file *stl); static void stl_read(stl_file *stl, int first_facet, int first); -static void stl_facet_stats(stl_file *stl, stl_facet facet, int first); +extern void stl_facet_stats(stl_file *stl, stl_facet facet, int first); extern void stl_reallocate(stl_file *stl); extern void stl_get_size(stl_file *stl); diff --git a/xs/t/01_trianglemesh.t b/xs/t/01_trianglemesh.t index 71ae47319..127c8c925 100644 --- a/xs/t/01_trianglemesh.t +++ b/xs/t/01_trianglemesh.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 51; +use Test::More tests => 52; is Slic3r::TriangleMesh::hello_world(), 'Hello world!', 'hello world'; @@ -59,6 +59,7 @@ my $cube = { my $meshes = $m->split; is scalar(@$meshes), 1, 'split'; isa_ok $meshes->[0], 'Slic3r::TriangleMesh', 'split'; + is_deeply $m->bb3, $meshes->[0]->bb3, 'split populates stats'; } my $m2 = Slic3r::TriangleMesh->new;