From 2bcac88683c8d4f6ce31127e8789f3df4f97fe2e Mon Sep 17 00:00:00 2001 From: Mike Sheldrake Date: Thu, 27 Sep 2012 05:50:54 -0700 Subject: [PATCH 01/15] Increase scale factor for Clipper::offset A default scale of 1 was being calculated most of the time. That's too low to avoid artifacts from offsetting concave curves. Setting scale to a default of 100000 eliminates artifacts in the test cases in issues #700, #702 and #703. There is a risk of large point proliferation with this scale in combination with the JT_ROUND option, but in the four places where that option is used, scale is already explicitly set to a safer low value. --- lib/Slic3r/Geometry/Clipper.pm | 4 ++-- lib/Slic3r/Layer/Region.pm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 5a1dfdd91..fca00af57 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -14,12 +14,12 @@ our $clipper = Math::Clipper->new; sub safety_offset { my ($polygons, $factor) = @_; - return Math::Clipper::offset($polygons, $factor || (scale 1e-05), 100, JT_MITER, 2); + return Math::Clipper::offset($polygons, $factor || (scale 1e-05), 100000, JT_MITER, 2); } sub offset { my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_; - $scale ||= &Slic3r::SCALING_FACTOR * 1000000; + $scale ||= 100000; $joinType = JT_MITER if !defined $joinType; $miterLimit ||= 2; diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 78de6499e..5c34496e5 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -330,7 +330,7 @@ sub prepare_fill_surfaces { # offset inwards my @offsets = $surface->expolygon->offset_ex(-$distance); - @offsets = @{union_ex(Math::Clipper::offset([ map @$_, @offsets ], $distance, 100, JT_MITER))}; + @offsets = @{union_ex(Math::Clipper::offset([ map @$_, @offsets ], $distance, 100000, JT_MITER))}; map Slic3r::Surface->new( expolygon => $_, surface_type => $surface->surface_type, From 5ee68aa91619fa0e1ecff06d84d74bdc3722e38c Mon Sep 17 00:00:00 2001 From: Mike Sheldrake Date: Thu, 27 Sep 2012 06:14:54 -0700 Subject: [PATCH 02/15] $parallel_degrees_limit decreased, 3 to 0.1, #704 Geometry::lines_parallel() test used for collapsing adjacent colinear lines was too loose in testing for colinearity, because of this constant setting. Gradualy curving and high-res outer perimiters would over-simplify into straight lines. --- lib/Slic3r/Geometry.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Slic3r/Geometry.pm b/lib/Slic3r/Geometry.pm index b5bec3a8d..c89faaf6f 100644 --- a/lib/Slic3r/Geometry.pm +++ b/lib/Slic3r/Geometry.pm @@ -36,7 +36,7 @@ use constant X2 => 2; use constant Y2 => 3; use constant MIN => 0; use constant MAX => 1; -our $parallel_degrees_limit = abs(deg2rad(3)); +our $parallel_degrees_limit = abs(deg2rad(0.1)); sub epsilon () { 1E-4 } sub scaled_epsilon () { epsilon / &Slic3r::SCALING_FACTOR } From 4b91496eddbdfc1eaaf3828ec974a123dfdc4885 Mon Sep 17 00:00:00 2001 From: Mike Sheldrake Date: Thu, 27 Sep 2012 06:47:38 -0700 Subject: [PATCH 03/15] use remove_coinciding_points before convex_hull convex_hull returns polygons with sharp concaves sometimes when duplicate points are present --- lib/Slic3r/GUI/Plater.pm | 3 ++- lib/Slic3r/Print.pm | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index a1263dc95..21ef094b3 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -999,7 +999,7 @@ package Slic3r::GUI::Plater::Object; use Moo; use Math::ConvexHull qw(convex_hull); -use Slic3r::Geometry qw(X Y); +use Slic3r::Geometry qw(X Y remove_coinciding_points); has 'name' => (is => 'rw', required => 1); has 'input_file' => (is => 'rw', required => 1); @@ -1034,6 +1034,7 @@ sub make_thumbnail { my %params = @_; my @points = map [ @$_[X,Y] ], @{$self->mesh->vertices}; + remove_coinciding_points(\@points); my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points)); for (@$convex_hull) { @$_ = map $_ * $params{scaling_factor}, @$_; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 4c8cc0ba5..262ef166d 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -6,7 +6,7 @@ use File::Spec; use List::Util qw(max); use Math::ConvexHull 1.0.4 qw(convex_hull); use Slic3r::ExtrusionPath ':roles'; -use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point); +use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point remove_coinciding_points); use Slic3r::Geometry::Clipper qw(diff_ex union_ex intersection_ex offset JT_ROUND JT_SQUARE); use Time::HiRes qw(gettimeofday tv_interval); @@ -139,6 +139,7 @@ sub validate { my $clearance; { my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes}; + remove_coinciding_points(\@points); my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points)); $clearance = +($convex_hull->offset(scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND))[0]; } @@ -552,6 +553,7 @@ sub make_skirt { return if @points < 3; # at least three points required for a convex hull # find out convex hull + remove_coinciding_points(\@points); my $convex_hull = convex_hull(\@points); # draw outlines from outside to inside From 048e58c07123e5f56172cfab42be271d543d375a Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 13 Oct 2012 19:03:08 +0200 Subject: [PATCH 04/15] Update file_info.pl after the recent introduction of Slic3r::Model --- utils/file_info.pl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils/file_info.pl b/utils/file_info.pl index 36e57e9b0..e8eb09456 100755 --- a/utils/file_info.pl +++ b/utils/file_info.pl @@ -25,12 +25,14 @@ my %opt = (); { my $input_file = $ARGV[0]; - my $mesh; - $mesh = Slic3r::Format::STL->read_file($input_file) if $input_file =~ /\.stl$/i; die "This script doesn't support AMF yet\n" if $input_file =~ /\.amf$/i; - die "Unable to read file\n" if !$mesh; + + my $model; + $model = Slic3r::Format::STL->read_file($input_file) if $input_file =~ /\.stl$/i; + die "Unable to read file\n" if !$model; printf "Info about %s:\n", basename($input_file); + my $mesh = $model->mesh; $mesh->check_manifoldness; printf " number of facets: %d\n", scalar @{$mesh->facets}; printf " size: x=%s y=%s z=%s\n", $mesh->size; From 8ac367bfa79c356c6215757522444635a3761a5e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 14 Oct 2012 22:10:49 +0200 Subject: [PATCH 05/15] If brim overlaps with skirt, make brim around skirt too instead of just ignoring skirt on first layer --- lib/Slic3r/Print.pm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 9231fa9cc..0494ea9cb 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -421,7 +421,7 @@ sub export_gcode { # make skirt $status_cb->(88, "Generating skirt"); $self->make_skirt; - $self->make_brim; + $self->make_brim; # must come after make_skirt # output everything to a G-code file my $output_file = $self->expanded_output_filepath($params{output_file}); @@ -560,16 +560,14 @@ sub make_skirt { # draw outlines from outside to inside my $flow = $Slic3r::first_layer_flow || $Slic3r::flow; - my @skirt = (); for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) { my $distance = scale ($Slic3r::Config->skirt_distance + ($flow->spacing * $i)); my $outline = Math::Clipper::offset([$convex_hull], $distance, &Slic3r::SCALING_FACTOR * 100, JT_ROUND); - push @skirt, Slic3r::ExtrusionLoop->pack( + push @{$self->skirt}, Slic3r::ExtrusionLoop->pack( polygon => Slic3r::Polygon->new(@{$outline->[0]}), role => EXTR_ROLE_SKIRT, ); } - unshift @{$self->skirt}, @skirt; } sub make_brim { @@ -591,6 +589,11 @@ sub make_brim { } } + # if brim touches skirt, make it around skirt too + if ($Slic3r::Config->skirt_distance + (($Slic3r::Config->skirts - 1) * $Slic3r::flow->spacing) <= $Slic3r::Config->brim_width) { + push @islands, map $_->unpack->split_at_first_point->polyline->grow($grow_distance), @{$self->skirt}; + } + my $num_loops = sprintf "%.0f", $Slic3r::Config->brim_width / $flow->width; for my $i (reverse 1 .. $num_loops) { # JT_SQUARE ensures no vertex is outside the given offset distance @@ -699,7 +702,7 @@ sub write_gcode { $gcodegen->shift_y($shift[Y]); $gcode .= $gcodegen->set_acceleration($Slic3r::Config->perimeter_acceleration); # skip skirt if we have a large brim - if ($layer_id < $Slic3r::Config->skirt_height && ($layer_id != 0 || $Slic3r::Config->skirt_distance + (($Slic3r::Config->skirts - 1) * $Slic3r::flow->spacing) > $Slic3r::Config->brim_width)) { + if ($layer_id < $Slic3r::Config->skirt_height) { $gcode .= $gcodegen->extrude_loop($_, 'skirt') for @{$self->skirt}; } $skirt_done++; From 769134bb6f807c7860e900158abe76689a978542 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 15 Oct 2012 10:57:15 +0200 Subject: [PATCH 06/15] Fixed regression causing skirt ignoring the first layer extrusion width override. #728 --- lib/Slic3r.pm | 1 + lib/Slic3r/Print.pm | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index e80357767..410e0b0b0 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -66,6 +66,7 @@ use constant SMALL_PERIMETER_LENGTH => (6.5 / SCALING_FACTOR) * 2 * PI; # them here because it makes accessing them slightly faster. our $Config; our $flow; +our $first_layer_flow; sub parallelize { my %params = @_; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 0494ea9cb..3cc64a69f 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -185,8 +185,16 @@ sub init_extruders { ); } + # calculate default flows + $Slic3r::flow = $self->extruders->[0]->make_flow( + width => $self->config->extrusion_width, + ); + $Slic3r::first_layer_flow = $self->extruders->[0]->make_flow( + layer_height => $self->config->get_value('first_layer_height'), + width => $self->config->first_layer_extrusion_width, + ); + # calculate regions' flows - $Slic3r::flow = $self->extruders->[0]->make_flow(width => $self->config->extrusion_width); for my $region_id (0 .. $#{$self->regions}) { my $region = $self->regions->[$region_id]; @@ -559,13 +567,13 @@ sub make_skirt { my $convex_hull = convex_hull(\@points); # draw outlines from outside to inside - my $flow = $Slic3r::first_layer_flow || $Slic3r::flow; for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) { - my $distance = scale ($Slic3r::Config->skirt_distance + ($flow->spacing * $i)); + my $distance = scale ($Slic3r::Config->skirt_distance + ($Slic3r::first_layer_flow->spacing * $i)); my $outline = Math::Clipper::offset([$convex_hull], $distance, &Slic3r::SCALING_FACTOR * 100, JT_ROUND); push @{$self->skirt}, Slic3r::ExtrusionLoop->pack( - polygon => Slic3r::Polygon->new(@{$outline->[0]}), - role => EXTR_ROLE_SKIRT, + polygon => Slic3r::Polygon->new(@{$outline->[0]}), + role => EXTR_ROLE_SKIRT, + flow_spacing => $Slic3r::first_layer_flow->spacing, ); } } @@ -574,8 +582,7 @@ sub make_brim { my $self = shift; return unless $Slic3r::Config->brim_width > 0; - my $flow = $Slic3r::first_layer_flow || $Slic3r::flow; - my $grow_distance = $flow->scaled_width / 2; + my $grow_distance = $Slic3r::first_layer_flow->scaled_width / 2; my @islands = (); # array of polygons foreach my $obj_idx (0 .. $#{$self->objects}) { my $layer0 = $self->objects->[$obj_idx]->layers->[0]; @@ -590,17 +597,18 @@ sub make_brim { } # if brim touches skirt, make it around skirt too - if ($Slic3r::Config->skirt_distance + (($Slic3r::Config->skirts - 1) * $Slic3r::flow->spacing) <= $Slic3r::Config->brim_width) { + if ($Slic3r::Config->skirt_distance + (($Slic3r::Config->skirts - 1) * $Slic3r::first_layer_flow->spacing) <= $Slic3r::Config->brim_width) { push @islands, map $_->unpack->split_at_first_point->polyline->grow($grow_distance), @{$self->skirt}; } - my $num_loops = sprintf "%.0f", $Slic3r::Config->brim_width / $flow->width; + my $num_loops = sprintf "%.0f", $Slic3r::Config->brim_width / $Slic3r::first_layer_flow->width; for my $i (reverse 1 .. $num_loops) { # JT_SQUARE ensures no vertex is outside the given offset distance push @{$self->brim}, Slic3r::ExtrusionLoop->pack( - polygon => Slic3r::Polygon->new($_), - role => EXTR_ROLE_SKIRT, - ) for @{Math::Clipper::offset(\@islands, $i * $flow->scaled_spacing, 100, JT_SQUARE)}; + polygon => Slic3r::Polygon->new($_), + role => EXTR_ROLE_SKIRT, + flow_spacing => $Slic3r::first_layer_flow->spacing, + ) for @{Math::Clipper::offset(\@islands, $i * $Slic3r::first_layer_flow->scaled_spacing, 100, JT_SQUARE)}; # TODO: we need the offset inwards/offset outwards logic to avoid overlapping extrusions } } From 6b4f038d173b6cfb091cad47b05bdd69bb986451 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 15 Oct 2012 10:59:54 +0200 Subject: [PATCH 07/15] Update copies number when decreasing parts. #747 --- lib/Slic3r/GUI/Plater.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 37dd165fa..cdaa903a6 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -384,6 +384,7 @@ sub decrease { my ($obj_idx, $object) = $self->selected_object; if ($object->instances_count >= 2) { pop @{$object->instances}; + $self->{list}->SetItem($obj_idx, 1, $object->instances_count); } else { $self->remove; } From 4f1b56f00457451286dbfc11a89d8c5365388e33 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 21 Oct 2012 20:56:19 +0200 Subject: [PATCH 08/15] Fix regression causing the plater to merge all materials into a single one, thus not producing multi-extrusion prints --- lib/Slic3r/GUI/Plater.pm | 41 +++++++++++++++++++++++++--------------- lib/Slic3r/Model.pm | 17 +++++++++++++++++ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index f7f9e7389..25a940e3f 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -455,7 +455,14 @@ sub split_object { my ($obj_idx, $current_object) = $self->selected_object; my $current_copies_num = $current_object->instances_count; - my $mesh = $current_object->get_mesh; + my $model_object = $current_object->get_model_object; + + if (@{$model_object->volumes} > 1) { + Slic3r::GUI::warning_catcher($self)->("The selected object couldn't be splitted because it contains more than one volume/material."); + return; + } + + my $mesh = $model_object->mesh; $mesh->align_to_origin; my @new_meshes = $mesh->split_mesh; @@ -669,20 +676,24 @@ sub make_model { my $self = shift; my $model = Slic3r::Model->new; - foreach my $object (@{$self->{objects}}) { - my $mesh = $object->get_mesh; - $mesh->scale($object->scale); - my $model_object = $model->add_object( - vertices => $mesh->vertices, - input_file => $object->input_file, + foreach my $plater_object (@{$self->{objects}}) { + my $model_object = $plater_object->get_model_object; + my $new_model_object = $model->add_object( + vertices => $model_object->vertices, + input_file => $plater_object->input_file, ); - $model_object->add_volume( - facets => $mesh->facets, - ); - $model_object->add_instance( - rotation => $object->rotate, + foreach my $volume (@{$model_object->volumes}) { + $new_model_object->add_volume( + material_id => $volume->material_id, + facets => $volume->facets, + ); + $model->materials->{$volume->material_id || 0} ||= {}; + } + $new_model_object->scale($plater_object->scale); + $new_model_object->add_instance( + rotation => $plater_object->rotate, offset => [ @$_ ], - ) for @{$object->instances}; + ) for @{$plater_object->instances}; } return $model; @@ -1027,12 +1038,12 @@ sub free_mesh { $self->mesh(undef); } -sub get_mesh { +sub get_model_object { my $self = shift; return $self->mesh->clone if $self->mesh; my $model = Slic3r::Model->read_from_file($self->input_file); - return $model->objects->[$self->input_file_object_id]->mesh; + return $model->objects->[$self->input_file_object_id]; } sub instances_count { diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 1e2a6b2ba..ffc5ab901 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -37,6 +37,12 @@ sub set_material { ); } +sub scale { + my $self = shift; + + $_->scale(@_) for @{$self->objects}; +} + # flattens everything to a single mesh sub mesh { my $self = shift; @@ -112,6 +118,17 @@ sub mesh { ); } +sub scale { + my $self = shift; + my ($factor) = @_; + return if $factor == 1; + + # transform vertex coordinates + foreach my $vertex (@{$self->vertices}) { + $vertex->[$_] *= $factor for X,Y,Z; + } +} + package Slic3r::Model::Volume; use Moo; From 76f75db05518adafee9a871ac6801a2bb26d7260 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 21 Oct 2012 21:44:06 +0200 Subject: [PATCH 09/15] Always specify tool number in M104/M109 when printing with multiple extruders --- lib/Slic3r/GCode.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index a135be271..7653e4c32 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -421,7 +421,7 @@ sub set_temperature { : ('M104', 'set temperature'); my $gcode = sprintf "$code %s%d %s; $comment\n", ($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature, - (defined $tool && $tool != $self->extruder->id) ? "T$tool " : ""; + (defined $tool && $self->multiple_extruders) ? "T$tool " : ""; $gcode .= "M116 ; wait for temperature to be reached\n" if $Slic3r::Config->gcode_flavor eq 'teacup' && $wait; From 3c7785aaf38cec58c9a1f14b04931cf5f00c1648 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 22 Oct 2012 13:11:43 +0200 Subject: [PATCH 10/15] Useless extra perimeters were generated sometimes. #444 #732 --- lib/Slic3r/Print/Object.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index ccb9723ff..3d7066a34 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -2,7 +2,7 @@ package Slic3r::Print::Object; use Moo; use Slic3r::ExtrusionPath ':roles'; -use Slic3r::Geometry qw(scale unscale deg2rad); +use Slic3r::Geometry qw(scale unscale deg2rad scaled_epsilon); use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex); use Slic3r::Surface ':types'; @@ -211,7 +211,7 @@ sub make_perimeters { # of our slice my $hypothetical_perimeter; { - my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * $perimeter_flow->scaled_spacing) ]; + my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * $perimeter_flow->scaled_spacing - scaled_epsilon) ]; last CYCLE if !@$outer; my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * $perimeter_flow->scaled_spacing) ]; last CYCLE if !@$inner; From 0990a9418c7e7c5abf68689a92c97b606cd2739d Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 22 Oct 2012 12:30:11 +0200 Subject: [PATCH 11/15] Bugfix: honeycomb infill was overlapping too much with perimeters. #732 --- lib/Slic3r/Fill/Concentric.pm | 2 +- lib/Slic3r/Fill/Honeycomb.pm | 2 +- lib/Slic3r/Fill/Rectilinear.pm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index 699b526d9..2a7c7823b 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -63,7 +63,7 @@ sub fill_surface { my $path = $loop->split_at_index($index); # clip the path to avoid the extruder to get exactly on the first point of the loop - $path->clip_end($self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width * 0.15); + $path->clip_end(($self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width) * 0.15); push @paths, $path->points if @{$path->points}; } diff --git a/lib/Slic3r/Fill/Honeycomb.pm b/lib/Slic3r/Fill/Honeycomb.pm index 70dd1e2ad..66fbd7ebb 100644 --- a/lib/Slic3r/Fill/Honeycomb.pm +++ b/lib/Slic3r/Fill/Honeycomb.pm @@ -21,7 +21,7 @@ sub fill_surface { # infill math my $min_spacing = scale $params{flow_spacing}; my $distance = $min_spacing / $params{density}; - my $overlap_distance = $self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width * 0.4; + my $overlap_distance = ($self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width) * 0.4; my $cache_id = sprintf "d%s_s%s_a%s", $params{density}, $params{flow_spacing}, $rotate_vector->[0][0]; diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index b4569dbc8..d13321015 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -31,7 +31,7 @@ sub fill_surface { $flow_spacing = unscale $distance_between_lines; } - my $overlap_distance = $self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width * 0.4; + my $overlap_distance = ($self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width) * 0.4; my $x = $bounding_box->[X1]; my $is_line_pattern = $self->isa('Slic3r::Fill::Line'); From 33b1970b958cc100f89840acc9b971471ae0c09f Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 22 Oct 2012 14:02:58 +0200 Subject: [PATCH 12/15] Incomplete commit broke the plater on threaded perls --- lib/Slic3r/GUI/Plater.pm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 25a940e3f..b5196ec1e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -301,7 +301,7 @@ sub load_file { name => basename($input_file), input_file => $input_file, input_file_object_id => $i, - mesh => $model->objects->[$i]->mesh, + model_object => $model->objects->[$i], instances => [ $model->objects->[$i]->instances ? (map $_->offset, @{$model->objects->[$i]->instances}) @@ -722,7 +722,7 @@ sub on_thumbnail_made { my $self = shift; my ($obj_idx) = @_; - $self->{objects}[$obj_idx]->free_mesh; + $self->{objects}[$obj_idx]->free_model_object; $self->recenter; $self->{canvas}->Refresh; } @@ -1017,31 +1017,31 @@ use Slic3r::Geometry qw(X Y remove_coinciding_points); has 'name' => (is => 'rw', required => 1); has 'input_file' => (is => 'rw', required => 1); -has 'input_file_object_id' => (is => 'rw'); # undef means keep mesh -has 'mesh' => (is => 'rw', required => 1, trigger => 1); +has 'input_file_object_id' => (is => 'rw'); # undef means keep model object +has 'model_object' => (is => 'rw', required => 1, trigger => 1); has 'size' => (is => 'rw'); has 'scale' => (is => 'rw', default => sub { 1 }); has 'rotate' => (is => 'rw', default => sub { 0 }); has 'instances' => (is => 'rw', default => sub { [] }); # upward Y axis has 'thumbnail' => (is => 'rw'); -sub _trigger_mesh { +sub _trigger_model_object { my $self = shift; - $self->size([$self->mesh->size]) if $self->mesh; + $self->size([$self->model_object->mesh->size]) if $self->model_object; } -sub free_mesh { +sub free_model_object { my $self = shift; # only delete mesh from memory if we can retrieve it from the original file return unless $self->input_file && $self->input_file_object_id; - $self->mesh(undef); + $self->model_object(undef); } sub get_model_object { my $self = shift; - return $self->mesh->clone if $self->mesh; + return $self->model_object if $self->model_object; my $model = Slic3r::Model->read_from_file($self->input_file); return $model->objects->[$self->input_file_object_id]; } @@ -1055,7 +1055,7 @@ sub make_thumbnail { my $self = shift; my %params = @_; - my @points = map [ @$_[X,Y] ], @{$self->mesh->vertices}; + my @points = map [ @$_[X,Y] ], @{$self->model_object->mesh->vertices}; remove_coinciding_points(\@points); my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points)); for (@$convex_hull) { @@ -1067,7 +1067,7 @@ sub make_thumbnail { $convex_hull->align_to_origin; $self->thumbnail($convex_hull); # ignored in multi-threaded environments - $self->mesh(undef) if defined $self->input_file_object_id; + $self->free_model_object; return $convex_hull; } From 68c3a0dd619ad5c1f76cbe7bf636578df9a83c62 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 22 Oct 2012 14:08:27 +0200 Subject: [PATCH 13/15] Make arcs.t happy. #721 --- lib/Slic3r/ExtrusionPath.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/ExtrusionPath.pm b/lib/Slic3r/ExtrusionPath.pm index a006d8712..c5466bcf7 100644 --- a/lib/Slic3r/ExtrusionPath.pm +++ b/lib/Slic3r/ExtrusionPath.pm @@ -160,6 +160,7 @@ sub detect_arcs { $max_angle = deg2rad($max_angle || 15); $len_epsilon ||= 10 / &Slic3r::SCALING_FACTOR; + my $parallel_degrees_limit = abs(Slic3r::Geometry::deg2rad(3)); my @points = @{$self->points}; my @paths = (); @@ -191,8 +192,8 @@ sub detect_arcs { $s3_angle += 2*PI if $s3_angle < 0; my $s1s2_angle = $s2_angle - $s1_angle; my $s2s3_angle = $s3_angle - $s2_angle; - next if abs($s1s2_angle - $s2s3_angle) > $Slic3r::Geometry::parallel_degrees_limit; - next if abs($s1s2_angle) < $Slic3r::Geometry::parallel_degrees_limit; # ignore parallel lines + next if abs($s1s2_angle - $s2s3_angle) > $parallel_degrees_limit; + next if abs($s1s2_angle) < $parallel_degrees_limit; # ignore parallel lines next if $s1s2_angle > $max_angle; # ignore too sharp vertices my @arc_points = ($points[$i], $points[$i+3]), # first and last points @@ -205,7 +206,7 @@ sub detect_arcs { my $line_angle = $line->atan; $line_angle += 2*PI if $line_angle < 0; my $anglediff = $line_angle - $last_line_angle; - last if abs($s1s2_angle - $anglediff) > $Slic3r::Geometry::parallel_degrees_limit; + last if abs($s1s2_angle - $anglediff) > $parallel_degrees_limit; # point $j+1 belongs to the arc $arc_points[-1] = $points[$j+1]; From c793a2657f0f900dd8fd06b13dd61ead7f3178fa Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 22 Oct 2012 15:29:54 +0200 Subject: [PATCH 14/15] Replace Math::ConvexHull with Math::ConvexHull::MonotoneChain. #722 --- Build.PL | 2 +- lib/Slic3r/GUI/Plater.pm | 7 +++---- lib/Slic3r/Print.pm | 6 ++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Build.PL b/Build.PL index 513a26955..4ad56e18e 100644 --- a/Build.PL +++ b/Build.PL @@ -12,7 +12,7 @@ my $build = Module::Build->new( 'File::Spec' => '0', 'Getopt::Long' => '0', 'Math::Clipper' => '1.09', - 'Math::ConvexHull' => '1.0.4', + 'Math::ConvexHull::MonotoneChain' => '0.01', 'Math::Geometry::Voronoi' => '1.3', 'Math::PlanePath' => '53', 'Moo' => '0.091009', diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index b5196ec1e..6d1f093c3 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -5,7 +5,7 @@ use utf8; use File::Basename qw(basename dirname); use List::Util qw(max sum); -use Math::ConvexHull qw(convex_hull); +use Math::ConvexHull::MonotoneChain qw(convex_hull); use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN MAX); use Slic3r::Geometry::Clipper qw(JT_ROUND); use threads::shared qw(shared_clone); @@ -1012,8 +1012,8 @@ sub OnDropFiles { package Slic3r::GUI::Plater::Object; use Moo; -use Math::ConvexHull qw(convex_hull); -use Slic3r::Geometry qw(X Y remove_coinciding_points); +use Math::ConvexHull::MonotoneChain qw(convex_hull); +use Slic3r::Geometry qw(X Y); has 'name' => (is => 'rw', required => 1); has 'input_file' => (is => 'rw', required => 1); @@ -1056,7 +1056,6 @@ sub make_thumbnail { my %params = @_; my @points = map [ @$_[X,Y] ], @{$self->model_object->mesh->vertices}; - remove_coinciding_points(\@points); my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points)); for (@$convex_hull) { @$_ = map $_ * $params{scaling_factor}, @$_; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index c82bd30d7..3669187b2 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -4,9 +4,9 @@ use Moo; use File::Basename qw(basename fileparse); use File::Spec; use List::Util qw(max); -use Math::ConvexHull 1.0.4 qw(convex_hull); +use Math::ConvexHull::MonotoneChain qw(convex_hull); use Slic3r::ExtrusionPath ':roles'; -use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point remove_coinciding_points); +use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point); use Slic3r::Geometry::Clipper qw(diff_ex union_ex intersection_ex offset JT_ROUND JT_SQUARE); use Time::HiRes qw(gettimeofday tv_interval); @@ -139,7 +139,6 @@ sub validate { my $clearance; { my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes}; - remove_coinciding_points(\@points); my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points)); $clearance = +($convex_hull->offset(scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND))[0]; } @@ -565,7 +564,6 @@ sub make_skirt { return if @points < 3; # at least three points required for a convex hull # find out convex hull - remove_coinciding_points(\@points); my $convex_hull = convex_hull(\@points); # draw outlines from outside to inside From 28b56ae840a4946b853323110f6113ee13d076fb Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 22 Oct 2012 16:03:08 +0200 Subject: [PATCH 15/15] Force unfocusing of all input fields when saving a preset, otherwise the currently focused one might be ignored. #750 #624 --- lib/Slic3r/GUI/Tab.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index 69eab8820..0a6eacab8 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -85,6 +85,12 @@ sub new { }); EVT_BUTTON($self, $self->{btn_save_preset}, sub { + + # since buttons (and choices too) don't get focus on Mac, we set focus manually + # to the treectrl so that the EVT_* events are fired for the input field having + # focus currently. is there anything better than this? + $self->{treectrl}->SetFocus; + my $preset = $self->current_preset; my $default_name = $preset->{default} ? 'Untitled' : basename($preset->{name}); $default_name =~ s/\.ini$//i;