diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index f015416de..e701bd1c4 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -477,7 +477,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 @{$_->expolygon}, map @{$_->slices}, @layers), (map @$_, map @{$_->thin_walls}, @layers), diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 696d72ca3..d8f2c531b 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -2,39 +2,42 @@ package Slic3r::Print::Object; use Moo; use Slic3r::ExtrusionPath ':roles'; -use Slic3r::Geometry qw(scale unscale deg2rad); +use Slic3r::Geometry qw(Z scale unscale deg2rad); use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex); use Slic3r::Surface ':types'; has 'input_file' => (is => 'rw', required => 0); has 'mesh' => (is => 'rw', required => 0); has 'size' => (is => 'rw', required => 1); +has 'layers' => (is => 'rw', default => sub { [] } ); -has 'layers' => ( - traits => ['Array'], - is => 'rw', - #isa => 'ArrayRef[Slic3r::Layer]', - 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(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 - - if ($self->layer_count < $layer_id + 1) { - for (my $i = $self->layer_count; $i <= $layer_id; $i++) { - push @{ $self->layers }, Slic3r::Layer->new(id => $i); + 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 { @@ -46,7 +49,7 @@ sub slice { my $apply_lines = sub { my $lines = shift; foreach my $layer_id (keys %$lines) { - my $layer = $self->layer($layer_id); + my $layer = $self->layers->[$layer_id]; push @{$layer->lines}, @{$lines->{$layer_id}}; } }; @@ -399,7 +402,7 @@ sub combine_infill { # start from bottom, skip first layer for (my $i = 1; $i < $self->layer_count; $i++) { - my $layer = $self->layer($i); + my $layer = $self->layers->[$i]; # skip layer if no internal fill surfaces next if !grep $_->surface_type == S_TYPE_INTERNAL, @{$layer->fill_surfaces}; @@ -408,7 +411,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; - my $lower_layer = $self->layer($i - 1); + my $lower_layer = $self->layers->[$i - 1]; # 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 6f6589450..b48f91981 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -401,14 +401,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); }