From 8bbaafd830c0eebb3ba0fc6e5da351a43d51b644 Mon Sep 17 00:00:00 2001 From: Christopher Keller Date: Mon, 18 Mar 2013 20:51:30 -0700 Subject: [PATCH 01/11] Added "known" as a valid model file type => 'Known files (*.stl, *.obj, *.amf)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML', When dialog pops up, it can see ALL known file types instead of only stl. --- lib/Slic3r/GUI/SkeinPanel.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index ca28a77d6..ef7403351 100644 --- a/lib/Slic3r/GUI/SkeinPanel.pm +++ b/lib/Slic3r/GUI/SkeinPanel.pm @@ -14,6 +14,7 @@ our $last_output_file; our $last_config; use constant FILE_WILDCARDS => { + known => 'Known files (*.stl, *.obj, *.amf, *.xml)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML', stl => 'STL files (*.stl)|*.stl;*.STL', obj => 'OBJ files (*.obj)|*.obj;*.OBJ', amf => 'AMF files (*.amf)|*.amf;*.AMF;*.xml;*.XML', @@ -21,7 +22,7 @@ use constant FILE_WILDCARDS => { gcode => 'G-code files (*.gcode, *.gco, *.g)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G', svg => 'SVG files *.svg|*.svg;*.SVG', }; -use constant MODEL_WILDCARD => join '|', @{&FILE_WILDCARDS}{qw(stl obj amf)}; +use constant MODEL_WILDCARD => join '|', @{&FILE_WILDCARDS}{qw(known stl obj amf)}; sub new { my $class = shift; From fd2a5e894aac70de3f2883a505b7a89bcf8957d8 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 19 Mar 2013 11:58:03 +0100 Subject: [PATCH 02/11] Respect perimeter/infill order when multiple extruders are configured but only one is used --- lib/Slic3r/Print.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index e374a6cfa..dded13f5e 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -927,9 +927,10 @@ sub write_gcode { } }; - # give priority to infill if we were already using its extruder + # give priority to infill if we were already using its extruder and it wouldn't + # be good for perimeters if ($Slic3r::Config->infill_first - || ($gcodegen->multiple_extruders && $region->extruders->{infill} eq $gcodegen->extruder)) { + || ($gcodegen->multiple_extruders && $region->extruders->{infill} eq $gcodegen->extruder) && $region->extruders->{infill} ne $region->extruders->{perimeter}) { $extrude_fills->(); $extrude_perimeters->(); } else { From 813aa5b3079d112897f6656ea518b8decc994149 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 19 Mar 2013 12:24:39 +0100 Subject: [PATCH 03/11] Allow drag and drop for OBJ files --- lib/Slic3r/GUI/Plater.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 0cdd5d04b..c0e300120 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1052,8 +1052,8 @@ sub OnDropFiles { # https://rt.perl.org/rt3/Public/Bug/Display.html?id=70602 @_ = (); - # only accept STL and AMF files - return 0 if grep !/\.(?:stl|amf(?:\.xml)?)$/i, @$filenames; + # only accept STL, OBJ and AMF files + return 0 if grep !/\.(?:stl|obj|amf(?:\.xml)?)$/i, @$filenames; $self->{window}->load_file($_) for @$filenames; } From 9c122bda5eeb2fa96edae58de7e6092f6d54a721 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 19 Mar 2013 16:02:03 +0100 Subject: [PATCH 04/11] Fix memory leak in avoid_crossing_perimeters. #1044 --- lib/Slic3r/GCode/MotionPlanner.pm | 8 +++++++- lib/Slic3r/Print.pm | 16 ++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/Slic3r/GCode/MotionPlanner.pm b/lib/Slic3r/GCode/MotionPlanner.pm index 3708a65e3..114f6a2be 100644 --- a/lib/Slic3r/GCode/MotionPlanner.pm +++ b/lib/Slic3r/GCode/MotionPlanner.pm @@ -168,11 +168,17 @@ sub BUILD { lines => \@lines, points => [ values %{$self->_pointmap} ], no_arrows => 1, - polygons => [ map @$_, @{$self->islands} ], + expolygons => $self->islands, #red_polygons => [ map $_->holes, map @$_, @{$self->_inner} ], #white_polygons => [ map @$_, @{$self->_outer} ], ); printf "%d islands\n", scalar @{$self->islands}; + + eval "use Devel::Size"; + print "MEMORY USAGE:\n"; + printf " %-19s = %.1fMb\n", $_, Devel::Size::total_size($self->$_)/1024/1024 + for qw(_inner _outer _contours_ex _pointmap _edges _crossing_edges islands last_crossings); + printf " %-19s = %.1fMb\n", 'self', Devel::Size::total_size($self)/1024/1024; } } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index dded13f5e..7fa1db9f4 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -881,24 +881,24 @@ sub write_gcode { if ($Slic3r::Config->avoid_crossing_perimeters) { push @islands, map +{ perimeters => [], fills => [] }, @{$layer->slices}; PERIMETER: foreach my $perimeter (@{$layerm->perimeters}) { - $perimeter = $perimeter->unpack; + my $p = $perimeter->unpack; for my $i (0 .. $#{$layer->slices}-1) { - if ($layer->slices->[$i]->contour->encloses_point($perimeter->first_point)) { - push @{ $islands[$i]{perimeters} }, $perimeter; + if ($layer->slices->[$i]->contour->encloses_point($p->first_point)) { + push @{ $islands[$i]{perimeters} }, $p; next PERIMETER; } } - push @{ $islands[-1]{perimeters} }, $perimeter; # optimization + push @{ $islands[-1]{perimeters} }, $p; # optimization } FILL: foreach my $fill (@{$layerm->fills}) { + my $f = $fill->unpack; for my $i (0 .. $#{$layer->slices}-1) { - $fill = $fill->unpack; - if ($layer->slices->[$i]->contour->encloses_point($fill->first_point)) { - push @{ $islands[$i]{fills} }, $fill; + if ($layer->slices->[$i]->contour->encloses_point($f->first_point)) { + push @{ $islands[$i]{fills} }, $f; next FILL; } } - push @{ $islands[-1]{fills} }, $fill; # optimization + push @{ $islands[-1]{fills} }, $f; # optimization } } else { push @islands, { From 7ec6c6ffba4d1c17714609e71e8c6f438f9ea93e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 19 Mar 2013 16:07:52 +0100 Subject: [PATCH 05/11] Lower 0.5*w to 0.4*w to fill finer gaps. #1057 --- lib/Slic3r/Layer/Region.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index fd9b187eb..c6f10e872 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -290,7 +290,7 @@ sub make_perimeters { )}; my $w = $self->perimeter_flow->width; - my @widths = (1.5 * $w, $w, 0.5 * $w); # worth trying 0.2 too? + my @widths = (1.5 * $w, $w, 0.4 * $w); # worth trying 0.2 too? foreach my $width (@widths) { my $flow = $self->perimeter_flow->clone(width => $width); From b7cd3628209ec11906d77ab9788fd76caba8847d Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 19 Mar 2013 19:15:53 +0100 Subject: [PATCH 06/11] Remove scale from G-code comments --- lib/Slic3r/Print.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 7fa1db9f4..4332fbc6c 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -693,7 +693,7 @@ sub write_gcode { print $fh "; $_\n" foreach split /\R/, $Slic3r::Config->notes; print $fh "\n" if $Slic3r::Config->notes; - for (qw(layer_height perimeters top_solid_layers bottom_solid_layers fill_density perimeter_speed infill_speed travel_speed scale)) { + for (qw(layer_height perimeters top_solid_layers bottom_solid_layers fill_density perimeter_speed infill_speed travel_speed)) { printf $fh "; %s = %s\n", $_, $Slic3r::Config->$_; } for (qw(nozzle_diameter filament_diameter extrusion_multiplier)) { From 6bc5de0b5d50108a98e319de50adaebdf570ac32 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Mar 2013 15:26:55 +0100 Subject: [PATCH 07/11] Allow custom ranges with layer_height = 0 --- lib/Slic3r/GUI/Plater/ObjectDialog.pm | 4 +- lib/Slic3r/Print/Object.pm | 70 ++++++++++++++++++--------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/ObjectDialog.pm b/lib/Slic3r/GUI/Plater/ObjectDialog.pm index 77a34685f..6543d50da 100644 --- a/lib/Slic3r/GUI/Plater/ObjectDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectDialog.pm @@ -98,7 +98,7 @@ sub new { my $sizer = Wx::BoxSizer->new(wxVERTICAL); { - my $label = Wx::StaticText->new($self, -1, "You can use this section to override the default layer height for parts of this object.", + my $label = Wx::StaticText->new($self, -1, "You can use this section to override the default layer height for parts of this object. Set layer height to zero to skip portions of the input file.", wxDefaultPosition, [-1, 25]); $label->SetFont(Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); $sizer->Add($label, 0, wxEXPAND | wxALL, 10); @@ -162,7 +162,7 @@ sub CanClose { Slic3r::GUI::show_error($self, "Invalid Z range $min-$max."); return 0; } - if ($height <= 0) { + if ($height < 0) { Slic3r::GUI::show_error($self, "Invalid layer height $height."); return 0; } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index ffac1e1e1..a14f6202d 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -18,26 +18,50 @@ has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_m sub BUILD { my $self = shift; - # make layers - my $print_z = my $slice_z = my $raft_z = 0; - while (!@{$self->layers} || $self->layers->[-1]->slice_z < $self->size->[Z]) { - my $id = $#{$self->layers} + 1; - my $height = $Slic3r::Config->layer_height; - $height = $Slic3r::Config->get_value('first_layer_height') if $id == 0; - if (my $range = first { $_->[0] <= ($print_z + $_->[2]) && $_->[1] >= ($print_z + $_->[2]) } @{$self->layer_height_ranges}) { - $height = $range->[2]; - } + # make layers taking custom heights into account + my $print_z = my $slice_z = my $height = 0; + + # add raft layers + for my $id (0 .. $Slic3r::Config->raft_layers-1) { + $height = ($id == 0) + ? $Slic3r::Config->get_value('first_layer_height') + : $Slic3r::Config->layer_height; $print_z += $height; - if ($id < $Slic3r::Config->raft_layers) { - # this is a raft layer - $raft_z += $height; - $slice_z = -1; - } else { - $slice_z = $print_z - ($height/2) - $raft_z; + push @{$self->layers}, Slic3r::Layer->new( + object => $self, + id => $id, + height => $height, + print_z => scale $print_z, + slice_z => -1, + ); + } + + # loop until we have at least one layer and the max slice_z reaches the object height + my $max_z = unscale $self->size->[Z]; + while (!@{$self->layers} || ($slice_z - $height) <= $max_z) { + my $id = $#{$self->layers} + 1; + + # assign the default height to the layer according to the general settings + $height = ($id == 0) + ? $Slic3r::Config->get_value('first_layer_height') + : $Slic3r::Config->layer_height; + + # look for an applicable custom range + if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) { + $height = $range->[2]; + + # if user set custom height to zero we should just skip the range and resume slicing over it + if ($height == 0) { + $slice_z += $range->[1] - $range->[0]; + next; + } } + $print_z += $height; + $slice_z += $height/2; + ### Slic3r::debugf "Layer %d: height = %s; slice_z = %s; print_z = %s\n", $id, $height, $slice_z, $print_z; push @{$self->layers}, Slic3r::Layer->new( @@ -47,6 +71,8 @@ sub BUILD { print_z => scale $print_z, slice_z => scale $slice_z, ); + + $slice_z += $height/2; # add the other half layer } } @@ -131,9 +157,8 @@ sub slice { # free memory $self->meshes(undef); - # remove last layer if empty - # (we might have created it because of the $max_layer = ... + 1 code in TriangleMesh) - pop @{$self->layers} if !map @{$_->lines}, @{$self->layers->[-1]->regions}; + # remove last layer(s) if empty + pop @{$self->layers} while !map @{$_->lines}, @{$self->layers->[-1]->regions}; foreach my $layer (@{ $self->layers }) { # make sure all layers contain layer region objects for all regions @@ -806,8 +831,7 @@ sub generate_support_material { [ map @$_, @current_layer_offsetted_slices ], ); $layers_contact_areas{$i} = [ - map $_->simplify($flow->scaled_spacing), - @{collapse_ex([ map @$_, @{$layers_contact_areas{$i}} ], $flow->scaled_width)}, + @{collapse_ex([ map @$_, @{$layers_contact_areas{$i}} ], $flow->scaled_width)}, ]; # to define interface regions of this layer we consider the overhangs of all the upper layers @@ -820,8 +844,7 @@ sub generate_support_material { ], ); $layers_interfaces{$i} = [ - map $_->simplify($flow->scaled_spacing), - @{collapse_ex([ map @$_, @{$layers_interfaces{$i}} ], $flow->scaled_width)}, + @{collapse_ex([ map @$_, @{$layers_interfaces{$i}} ], $flow->scaled_width)}, ]; # generate support material in current layer (for upper layers) @@ -842,8 +865,7 @@ sub generate_support_material { ], ); $layers{$i} = [ - map $_->simplify($flow->scaled_spacing), - @{collapse_ex([ map @$_, @{$layers{$i}} ], $flow->scaled_width)}, + @{collapse_ex([ map @$_, @{$layers{$i}} ], $flow->scaled_width)}, ]; # get layer overhangs and put them into queue for adding support inside lower layers; From 4cb36fcbe2f5688da65006d5ca4f32482ba3996e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Mar 2013 21:28:16 +0100 Subject: [PATCH 08/11] Remove cooling checkbox from simple mode --- lib/Slic3r/GUI/SimpleTab.pm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/Slic3r/GUI/SimpleTab.pm b/lib/Slic3r/GUI/SimpleTab.pm index 29044e4a1..0463a3d4e 100644 --- a/lib/Slic3r/GUI/SimpleTab.pm +++ b/lib/Slic3r/GUI/SimpleTab.pm @@ -172,11 +172,6 @@ sub build { }, ], ); - - $self->append_optgroup( - title => 'Cooling', - options => [qw(cooling)], - ); } package Slic3r::GUI::SimpleTab::Printer; From 4c41f6c4629eb9df09794897e697fa5ca8f988ac Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 26 Mar 2013 13:57:37 +0100 Subject: [PATCH 09/11] Safer safety_offset() for ExPolygons --- lib/Slic3r/ExPolygon.pm | 10 +--------- lib/Slic3r/Geometry/Clipper.pm | 7 ++++++- lib/Slic3r/Polygon.pm | 5 ----- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 558f9fe21..f3742d3c5 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -85,15 +85,7 @@ sub offset_ex { sub safety_offset { my $self = shift; - - # we're offsetting contour and holes separately - # because Clipper doesn't return polygons in the same order as - # we feed them to it - - return (ref $self)->new( - $self->contour->safety_offset, - @{ Slic3r::Geometry::Clipper::safety_offset([$self->holes]) }, - ); + return Slic3r::Geometry::Clipper::safety_offset_ex($self, @_); } sub noncollapsing_offset_ex { diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 0196460fb..68e3d7c0e 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -4,7 +4,7 @@ use warnings; require Exporter; our @ISA = qw(Exporter); -our @EXPORT_OK = qw(safety_offset offset offset_ex collapse_ex +our @EXPORT_OK = qw(safety_offset safety_offset_ex offset offset_ex collapse_ex diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND JT_SQUARE is_counter_clockwise); @@ -17,6 +17,11 @@ sub safety_offset { return Math::Clipper::offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2); } +sub safety_offset_ex { + # offset polygons and then apply holes to the right contours + return @{ union_ex([ safety_offset(@_) ]) }; +} + sub offset { my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_; $scale ||= 100000; diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index e9bfcf81a..07f36d4f1 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -95,11 +95,6 @@ sub area { return Slic3r::Geometry::Clipper::area($self); } -sub safety_offset { - my $self = shift; - return (ref $self)->new(Slic3r::Geometry::Clipper::safety_offset([$self])->[0]); -} - sub offset { my $self = shift; return map Slic3r::Polygon->new($_), Slic3r::Geometry::Clipper::offset([$self], @_); From 2f046799f26fdf923ab25d38f536758437a76316 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 26 Mar 2013 14:03:24 +0100 Subject: [PATCH 10/11] Removed offset() method from Slic3r::Polygon because it only works with ccw polygons --- lib/Slic3r/GCode/MotionPlanner.pm | 5 +++-- lib/Slic3r/GUI/Plater.pm | 6 +++--- lib/Slic3r/Polygon.pm | 7 +------ lib/Slic3r/Polyline.pm | 5 ++++- lib/Slic3r/Print.pm | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/Slic3r/GCode/MotionPlanner.pm b/lib/Slic3r/GCode/MotionPlanner.pm index 114f6a2be..0cde4e1af 100644 --- a/lib/Slic3r/GCode/MotionPlanner.pm +++ b/lib/Slic3r/GCode/MotionPlanner.pm @@ -13,7 +13,7 @@ has '_crossing_edges' => (is => 'rw', default => sub { {} }); # edge_idx => boo use List::Util qw(first); use Slic3r::Geometry qw(A B scale epsilon nearest_point); -use Slic3r::Geometry::Clipper qw(diff_ex JT_MITER); +use Slic3r::Geometry::Clipper qw(diff_ex offset JT_MITER); # clearance (in mm) from the perimeters has '_inner_margin' => (is => 'ro', default => sub { scale 0.5 }); @@ -68,7 +68,8 @@ sub BUILD { : [ $self->islands->[$i]->offset_ex(-$self->_inner_margin) ]; # offset the island outwards to make the boundaries for external movements - $self->_outer->[$i] = [ $self->islands->[$i]->contour->offset($self->_outer_margin) ]; + $self->_outer->[$i] = [ offset([ $self->islands->[$i]->contour], $self->_outer_margin) ]; + bless $_, 'Slic3r::Polygon' for @{ $self->_outer->[$i] }; # if internal motion is enabled, build a set of utility expolygons representing # the outer boundaries (as contours) and the inner boundaries (as holes). whenever diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index c0e300120..ba527324a 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -7,7 +7,7 @@ use File::Basename qw(basename dirname); use List::Util qw(max sum first); 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 Slic3r::Geometry::Clipper qw(offset JT_ROUND); use threads::shared qw(shared_clone); use Wx qw(:bitmap :brush :button :cursor :dialog :filedialog :font :keycode :icon :id :listctrl :misc :panel :pen :sizer :toolbar :window); use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL EVT_CHOICE); @@ -881,7 +881,7 @@ sub repaint { # if sequential printing is enabled and we have more than one object if ($parent->{config}->complete_objects && (map @{$_->instances}, @{$parent->{objects}}) > 1) { my $convex_hull = Slic3r::Polygon->new(convex_hull([ map @{$_->contour}, @{$parent->{object_previews}->[-1][2]->expolygons} ])); - my $clearance = +($convex_hull->offset($parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 1, JT_ROUND))[0]; + my ($clearance) = offset([$convex_hull], $parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 1, JT_ROUND); $dc->SetPen($parent->{clearance_pen}); $dc->SetBrush($parent->{transparent_brush}); $dc->DrawPolygon($parent->_y($clearance), 0, 0); @@ -892,7 +892,7 @@ sub repaint { # draw skirt if (@{$parent->{object_previews}} && $parent->{config}->skirts) { my $convex_hull = Slic3r::Polygon->new(convex_hull([ map @{$_->contour}, map @{$_->[2]->expolygons}, @{$parent->{object_previews}} ])); - $convex_hull = +($convex_hull->offset($parent->{config}->skirt_distance * $parent->{scaling_factor}, 1, JT_ROUND))[0]; + ($convex_hull) = offset([$convex_hull], $parent->{config}->skirt_distance * $parent->{scaling_factor}, 1, JT_ROUND); $dc->SetPen($parent->{skirt_pen}); $dc->SetBrush($parent->{transparent_brush}); $dc->DrawPolygon($parent->_y($convex_hull), 0, 0) if $convex_hull; diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index 07f36d4f1..a89cc0791 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -95,11 +95,6 @@ sub area { return Slic3r::Geometry::Clipper::area($self); } -sub offset { - my $self = shift; - return map Slic3r::Polygon->new($_), Slic3r::Geometry::Clipper::offset([$self], @_); -} - sub grow { my $self = shift; return $self->split_at_first_point->grow(@_); @@ -147,7 +142,7 @@ sub is_printable { # detect them and we would be discarding them. my $p = $self->clone; $p->make_counter_clockwise; - return $p->offset(-$width / 2) ? 1 : 0; + return Slic3r::Geometry::Clipper::offset([$p], -$width / 2) ? 1 : 0; } sub is_valid { diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index 2578e505d..4d7fbe90e 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -86,7 +86,10 @@ sub length { sub grow { my $self = shift; - return Slic3r::Polygon->new(@$self, CORE::reverse @$self[1..($#$self-1)])->offset(@_); + return Slic3r::Geometry::Clipper::offset( + [ Slic3r::Polygon->new(@$self, CORE::reverse @$self[1..($#$self-1)]) ], + @_, + ); } sub nearest_point_to { diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 4332fbc6c..6df75f2fe 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -151,7 +151,7 @@ sub validate { { my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes}; my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points)); - $clearance = +($convex_hull->offset(scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND))[0]; + ($clearance) = offset([$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND); } for my $copy (@{$self->objects->[$obj_idx]->copies}) { my $copy_clearance = $clearance->clone; From aae9625a13eac2e7a1166133b666c6cf2980cc33 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 26 Mar 2013 15:47:40 +0100 Subject: [PATCH 11/11] Bugfix: solid-infill-below-area wasn't ignored when fill_density = 0, causing solid layers here and there. #1049 --- lib/Slic3r/Layer/Region.pm | 2 +- t/fill.t | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index c6f10e872..6aec785ae 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -462,7 +462,7 @@ sub prepare_fill_surfaces { } # turn too small internal regions into solid regions according to the user setting - { + if ($Slic3r::Config->fill_density > 0) { my $min_area = scale scale $Slic3r::Config->solid_infill_below_area; # scaling an area requires two calls! my @small = grep $_->surface_type == S_TYPE_INTERNAL && $_->expolygon->contour->area <= $min_area, @{$self->fill_surfaces}; $_->surface_type(S_TYPE_INTERNALSOLID) for @small; diff --git a/t/fill.t b/t/fill.t index b5ebd5dcf..cbffd7dab 100644 --- a/t/fill.t +++ b/t/fill.t @@ -95,4 +95,22 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } ok Slic3r::Test::gcode($print), 'successful hilbertcurve infill generation'; } +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('skirts', 0); + $config->set('perimeters', 0); + $config->set('fill_density', 0); + $config->set('top_solid_layers', 0); + $config->set('bottom_solid_layers', 0); + $config->set('solid_infill_below_area', 20000000); + + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + Slic3r::Test::GCodeReader->new(gcode => Slic3r::Test::gcode($print))->parse(sub { + my ($self, $cmd, $args, $info) = @_; + + fail "solid_infill_below_area should be ignored when fill_density is 0" + if $info->{extruding}; + }); +} + __END__