diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index 80b712a642..d22188ab5d 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -12,7 +12,7 @@ has 'slicing_errors' => (is => 'rw'); has 'slice_z' => (is => 'lazy'); has 'print_z' => (is => 'lazy'); has 'height' => (is => 'lazy'); -has 'flow' => (is => 'ro', default => sub { $Slic3r::flow }); +has 'flow' => (is => 'lazy'); # collection of expolygons generated by slicing the original geometry; # also known as 'islands' (all regions are merged here) @@ -51,6 +51,8 @@ sub _build_height { return $self->id == 0 ? $Slic3r::Config->get_value('first_layer_height') : $Slic3r::Config->layer_height; } +sub _build_flow { $Slic3r::flow } + # layer height of interface paths in unscaled coordinates sub support_material_interface_height { my $self = shift; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index fcbfd580b9..fe9f164b7d 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -554,7 +554,7 @@ sub make_skirt { $skirt_height = $self->layer_count if $skirt_height > $self->layer_count; my @points = (); foreach my $obj_idx (0 .. $#{$self->objects}) { - my @layers = map $self->objects->[$obj_idx]->layer($_), 0..($skirt_height-1); + my @layers = map $self->objects->[$obj_idx]->layers->[$_], 0..($skirt_height-1); my @layer_points = ( (map @$_, map @$_, map @{$_->slices}, @layers), (map @$_, map @{$_->thin_walls}, map @{$_->regions}, @layers), diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 78c637aacc..86cebb675d 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 scaled_epsilon); +use Slic3r::Geometry qw(Z scale unscale deg2rad scaled_epsilon); use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex); use Slic3r::Surface ':types'; @@ -13,21 +13,36 @@ has 'size' => (is => 'rw', required => 1); has 'copies' => (is => 'rw', default => sub {[ [0,0] ]}); has 'layers' => (is => 'rw', default => sub { [] }); +sub BUILD { + my $self = shift; + + # make layers + while (!@{$self->layers} || $self->layers->[-1]->slice_z < $self->size->[Z]) { + push @{$self->layers}, Slic3r::Layer->new( + object => $self, + id => $#{$self->layers} + 1, + ); + } +} + sub layer_count { my $self = shift; return scalar @{ $self->layers }; } -sub layer { +sub get_layer_range { my $self = shift; - my ($layer_id) = @_; + my ($min_z, $max_z) = @_; - # extend our print by creating all necessary layers - for (my $i = $self->layer_count; $i <= $layer_id; $i++) { - push @{ $self->layers }, Slic3r::Layer->new(id => $i, object => $self); + my ($min_layer, $max_layer) = (0, undef); + for my $layer (@{$self->layers}) { + $min_layer = $layer->id if $layer->slice_z <= $min_z; + if ($layer->slice_z >= $max_z) { + $max_layer = $layer->id; + last; + } } - - return $self->layers->[$layer_id]; + return ($min_layer, $max_layer); } sub slice { @@ -41,7 +56,7 @@ sub slice { my $apply_lines = sub { my $lines = shift; foreach my $layer_id (keys %$lines) { - my $layerm = $self->layer($layer_id)->region($region_id); + my $layerm = $self->layers->[$layer_id]->region($region_id); push @{$layerm->lines}, @{$lines->{$layer_id}}; } }; @@ -441,7 +456,7 @@ sub combine_infill { # we do this from the greater depth to the smaller for (my $d = $Slic3r::Config->infill_every_layers - 1; $d >= 1; $d--) { next if ($i - $d) <= 0; # do not combine infill for bottom layer - my $lower_layerm = $self->layer($i - 1)->regions->[$region_id]; + my $lower_layerm = $self->layers->[$i - 1]->regions->[$region_id]; # select surfaces of the lower layer having the depth we're looking for my @lower_surfaces = grep $_->depth_layers == $d && $_->surface_type == S_TYPE_INTERNAL, diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index 599445967a..d830ba54c9 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -415,14 +415,12 @@ sub slice_facet { } # calculate the layer extents - my $min_layer = int((unscale($min_z) - ($Slic3r::Config->get_value('first_layer_height') + $Slic3r::Config->layer_height / 2)) / $Slic3r::Config->layer_height) - 2; - $min_layer = 0 if $min_layer < 0; - my $max_layer = int((unscale($max_z) - ($Slic3r::Config->get_value('first_layer_height') + $Slic3r::Config->layer_height / 2)) / $Slic3r::Config->layer_height) + 2; + my ($min_layer, $max_layer) = $print_object->get_layer_range($min_z, $max_z); Slic3r::debugf "layers: min = %s, max = %s\n", $min_layer, $max_layer; my $lines = {}; # layer_id => [ lines ] for (my $layer_id = $min_layer; $layer_id <= $max_layer; $layer_id++) { - my $layer = $print_object->layer($layer_id); + my $layer = $print_object->layers->[$layer_id]; $lines->{$layer_id} ||= []; push @{ $lines->{$layer_id} }, $self->intersect_facet($facet_id, $layer->slice_z); }