Memory optimization and code cleanup. Don't keep deserialized paths
This commit is contained in:
parent
52fb02f29d
commit
1697cb24a6
@ -13,15 +13,24 @@ has 'flow_spacing' => (is => 'rw');
|
||||
# see EXTR_ROLE_* constants in ExtrusionPath.pm
|
||||
has 'role' => (is => 'rw', required => 1);
|
||||
|
||||
sub BUILD {
|
||||
my $self = shift;
|
||||
bless $self->polygon, 'Slic3r::Polygon';
|
||||
$self->polygon($self->polygon->serialize);
|
||||
}
|
||||
use constant PACK_FMT => 'fca*';
|
||||
|
||||
sub deserialize {
|
||||
# class or object method
|
||||
sub pack {
|
||||
my $self = shift;
|
||||
$self->polygon($self->polygon->deserialize);
|
||||
my %args = @_;
|
||||
|
||||
if (ref $self) {
|
||||
%args = map { $_ => $self->$_ } qw(flow_spacing role polygon);
|
||||
}
|
||||
|
||||
my $o = \ pack PACK_FMT,
|
||||
$args{flow_spacing} || -1,
|
||||
$args{role} // (die "Missing mandatory attribute 'role'"), #/
|
||||
$args{polygon}->serialize;
|
||||
|
||||
bless $o, 'Slic3r::ExtrusionLoop::Packed';
|
||||
return $o;
|
||||
}
|
||||
|
||||
sub shortest_path {
|
||||
@ -33,8 +42,6 @@ sub split_at_index {
|
||||
my $self = shift;
|
||||
my ($index) = @_;
|
||||
|
||||
$self->deserialize;
|
||||
|
||||
my @new_points = ();
|
||||
push @new_points, @{$self->polygon}[$index .. $#{$self->polygon}];
|
||||
push @new_points, @{$self->polygon}[0 .. $index];
|
||||
@ -52,8 +59,6 @@ sub split_at {
|
||||
|
||||
$point = Slic3r::Point->new($point);
|
||||
|
||||
$self->deserialize;
|
||||
|
||||
# find index of point
|
||||
my $i = -1;
|
||||
for (my $n = 0; $n <= $#{$self->polygon}; $n++) {
|
||||
@ -86,4 +91,18 @@ sub points {
|
||||
return $self->polygon;
|
||||
}
|
||||
|
||||
package Slic3r::ExtrusionLoop::Packed;
|
||||
sub unpack {
|
||||
my $self = shift;
|
||||
|
||||
my ($flow_spacing, $role, $polygon_s)
|
||||
= unpack Slic3r::ExtrusionLoop::PACK_FMT, $$self;
|
||||
|
||||
return Slic3r::ExtrusionLoop->new(
|
||||
flow_spacing => ($flow_spacing == -1) ? undef : $flow_spacing,
|
||||
role => $role,
|
||||
polygon => Slic3r::Polygon->deserialize($polygon_s),
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -18,13 +18,11 @@ has 'polyline' => (
|
||||
handles => [qw(merge_continuous_lines lines length reverse)],
|
||||
);
|
||||
|
||||
# this integer represents the vertical thickness of the extrusion
|
||||
# expressed in layers
|
||||
# depth_layers is the vertical thickness of the extrusion expressed in layers
|
||||
has 'depth_layers' => (is => 'ro', default => sub {1});
|
||||
|
||||
has 'flow_spacing' => (is => 'rw');
|
||||
|
||||
has 'role' => (is => 'rw', required => 1);
|
||||
|
||||
use constant EXTR_ROLE_PERIMETER => 0;
|
||||
use constant EXTR_ROLE_SMALLPERIMETER => 1;
|
||||
use constant EXTR_ROLE_EXTERNAL_PERIMETER => 2;
|
||||
@ -36,16 +34,29 @@ use constant EXTR_ROLE_BRIDGE => 7;
|
||||
use constant EXTR_ROLE_SKIRT => 8;
|
||||
use constant EXTR_ROLE_SUPPORTMATERIAL => 9;
|
||||
|
||||
sub BUILD {
|
||||
use constant PACK_FMT => 'cfca*';
|
||||
|
||||
# class or object method
|
||||
sub pack {
|
||||
my $self = shift;
|
||||
bless $self->polyline, 'Slic3r::Polyline';
|
||||
$self->polyline($self->polyline->serialize);
|
||||
my %args = @_;
|
||||
|
||||
if (ref $self) {
|
||||
%args = map { $_ => $self->$_ } qw(depth_layers flow_spacing role polyline);
|
||||
}
|
||||
|
||||
my $o = \ pack PACK_FMT,
|
||||
$args{depth_layers} || 1,
|
||||
$args{flow_spacing} || -1,
|
||||
$args{role} // (die "Missing mandatory attribute 'role'"), #/
|
||||
$args{polyline}->serialize;
|
||||
|
||||
bless $o, 'Slic3r::ExtrusionPath::Packed';
|
||||
return $o;
|
||||
}
|
||||
|
||||
sub deserialize {
|
||||
my $self = shift;
|
||||
$self->polyline($self->polyline->deserialize);
|
||||
}
|
||||
# no-op, this allows to use both packed and non-packed objects in Collections
|
||||
sub unpack { $_[0] }
|
||||
|
||||
sub shortest_path {
|
||||
my $self = shift;
|
||||
@ -152,7 +163,6 @@ sub detect_arcs {
|
||||
my $self = shift;
|
||||
my ($max_angle, $len_epsilon) = @_;
|
||||
|
||||
$self->deserialize;
|
||||
$max_angle = deg2rad($max_angle || 15);
|
||||
$len_epsilon ||= 10 / $Slic3r::scaling_factor;
|
||||
|
||||
@ -265,4 +275,19 @@ sub detect_arcs {
|
||||
return @paths;
|
||||
}
|
||||
|
||||
package Slic3r::ExtrusionPath::Packed;
|
||||
sub unpack {
|
||||
my $self = shift;
|
||||
|
||||
my ($depth_layers, $flow_spacing, $role, $polyline_s)
|
||||
= unpack Slic3r::ExtrusionPath::PACK_FMT, $$self;
|
||||
|
||||
return Slic3r::ExtrusionPath->new(
|
||||
depth_layers => $depth_layers,
|
||||
flow_spacing => ($flow_spacing == -1) ? undef : $flow_spacing,
|
||||
role => $role,
|
||||
polyline => Slic3r::Polyline->deserialize($polyline_s),
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -1,19 +1,7 @@
|
||||
package Slic3r::ExtrusionPath::Collection;
|
||||
use Moo;
|
||||
|
||||
|
||||
has 'paths' => (
|
||||
is => 'rw',
|
||||
#isa => 'ArrayRef[Slic3r::ExtrusionPath]',
|
||||
default => sub { [] },
|
||||
);
|
||||
|
||||
sub add {
|
||||
my $self = shift;
|
||||
my ($path) = @_;
|
||||
|
||||
push @{$self->paths}, $path;
|
||||
}
|
||||
has 'paths' => (is => 'rw', default => sub { [] });
|
||||
|
||||
sub endpoints {
|
||||
my $self = shift;
|
||||
@ -24,8 +12,8 @@ sub shortest_path {
|
||||
my $self = shift;
|
||||
my ($start_near) = @_;
|
||||
|
||||
my @my_paths = @{$self->paths};
|
||||
$_->deserialize for @my_paths;
|
||||
my @my_paths = map $_->unpack, @{$self->paths};
|
||||
|
||||
my @paths = ();
|
||||
my $start_at;
|
||||
my $endpoints = [ map $_->endpoints, @my_paths ];
|
||||
|
@ -162,7 +162,7 @@ sub make_fill {
|
||||
next unless @paths;
|
||||
push @fills, Slic3r::ExtrusionPath::Collection->new(
|
||||
paths => [
|
||||
map Slic3r::ExtrusionPath->new(
|
||||
map Slic3r::ExtrusionPath->pack(
|
||||
polyline => Slic3r::Polyline->new(@$_),
|
||||
role => ($is_bridge
|
||||
? EXTR_ROLE_BRIDGE
|
||||
@ -185,8 +185,8 @@ sub make_fill {
|
||||
);
|
||||
push @fills, map {
|
||||
$_->isa('Slic3r::Polygon')
|
||||
? Slic3r::ExtrusionLoop->new(polygon => $_, %args)->split_at_first_point
|
||||
: Slic3r::ExtrusionPath->new(polyline => $_, %args),
|
||||
? Slic3r::ExtrusionLoop->pack(polygon => $_, %args)->split_at_first_point
|
||||
: Slic3r::ExtrusionPath->pack(polyline => $_, %args),
|
||||
} @{$layer->thin_fills};
|
||||
}
|
||||
push @fills_ordering_points, map $_->[0], @{$layer->thin_fills};
|
||||
|
@ -53,7 +53,6 @@ sub fill_surface {
|
||||
);
|
||||
foreach my $loop (map Slic3r::ExtrusionLoop->new(polygon => $_, role => EXTR_ROLE_FILL), @loops) {
|
||||
# extrude all loops ccw
|
||||
$loop->deserialize;
|
||||
$loop->polygon->make_counter_clockwise;
|
||||
|
||||
# find the point of the loop that is closest to the current extruder position
|
||||
@ -62,7 +61,6 @@ sub fill_surface {
|
||||
|
||||
# split the loop at the starting point and make a path
|
||||
my $path = $loop->split_at_index($index);
|
||||
$path->deserialize;
|
||||
|
||||
# clip the path to avoid the extruder to get exactly on the first point of the loop
|
||||
$path->clip_end(scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.15);
|
||||
|
@ -88,7 +88,7 @@ sub fill_surface {
|
||||
[ map @$_, $expolygon->offset_ex($overlap_distance) ],
|
||||
)};
|
||||
my $collection = Slic3r::ExtrusionPath::Collection->new(
|
||||
paths => [ map Slic3r::ExtrusionPath->new(polyline => $_, role => -1), @paths ],
|
||||
paths => [ map Slic3r::ExtrusionPath->pack(polyline => $_, role => -1), @paths ],
|
||||
);
|
||||
|
||||
return {}, map $_->polyline, $collection->shortest_path;
|
||||
|
@ -79,12 +79,9 @@ sub change_layer {
|
||||
sub extrude {
|
||||
my $self = shift;
|
||||
|
||||
if ($_[0]->isa('Slic3r::ExtrusionLoop')) {
|
||||
$self->extrude_loop(@_);
|
||||
} else {
|
||||
$_[0]->deserialize;
|
||||
$self->extrude_path(@_);
|
||||
}
|
||||
$_[0]->isa('Slic3r::ExtrusionLoop::Packed')
|
||||
? $self->extrude_loop(@_)
|
||||
: $self->extrude_path(@_);
|
||||
}
|
||||
|
||||
sub extrude_loop {
|
||||
@ -92,7 +89,7 @@ sub extrude_loop {
|
||||
my ($loop, $description) = @_;
|
||||
|
||||
# extrude all loops ccw
|
||||
$loop->deserialize;
|
||||
$loop = $loop->unpack;
|
||||
$loop->polygon->make_counter_clockwise;
|
||||
|
||||
# find the point of the loop that is closest to the current extruder position
|
||||
@ -107,7 +104,6 @@ sub extrude_loop {
|
||||
|
||||
# split the loop at the starting point and make a path
|
||||
my $extrusion_path = $loop->split_at_index($start_index);
|
||||
$extrusion_path->deserialize;
|
||||
|
||||
# clip the path to avoid the extruder to get exactly on the first point of the loop;
|
||||
# if polyline was shorter than the clipping distance we'd get a null polyline, so
|
||||
@ -123,13 +119,13 @@ sub extrude_path {
|
||||
my $self = shift;
|
||||
my ($path, $description, $recursive) = @_;
|
||||
|
||||
$path = $path->unpack if $path->isa('Slic3r::ExtrusionPath::Packed');
|
||||
$path->merge_continuous_lines;
|
||||
|
||||
# detect arcs
|
||||
if ($Slic3r::gcode_arcs && !$recursive) {
|
||||
my $gcode = "";
|
||||
foreach my $arc_path ($path->detect_arcs) {
|
||||
$arc_path->deserialize;
|
||||
$gcode .= $self->extrude_path($arc_path, $description, 1);
|
||||
}
|
||||
return $gcode;
|
||||
|
@ -351,9 +351,9 @@ sub make_perimeters {
|
||||
my @thin_paths = ();
|
||||
for (@{ $self->thin_walls }) {
|
||||
if ($_->isa('Slic3r::Polygon')) {
|
||||
push @thin_paths, Slic3r::ExtrusionLoop->new(polygon => $_, role => EXTR_ROLE_PERIMETER);
|
||||
push @thin_paths, Slic3r::ExtrusionLoop->pack(polygon => $_, role => EXTR_ROLE_PERIMETER);
|
||||
} else {
|
||||
push @thin_paths, Slic3r::ExtrusionPath->new(polyline => $_, role => EXTR_ROLE_PERIMETER);
|
||||
push @thin_paths, Slic3r::ExtrusionPath->pack(polyline => $_, role => EXTR_ROLE_PERIMETER);
|
||||
}
|
||||
$thin_paths[-1]->flow_spacing($self->perimeters_flow->spacing);
|
||||
}
|
||||
@ -367,7 +367,7 @@ sub add_perimeter {
|
||||
my ($polygon, $role) = @_;
|
||||
|
||||
return unless $polygon->is_printable($self->perimeters_flow->width);
|
||||
push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(
|
||||
push @{ $self->perimeters }, Slic3r::ExtrusionLoop->pack(
|
||||
polygon => $polygon,
|
||||
role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/
|
||||
flow_spacing => $self->perimeters_flow->spacing,
|
||||
|
@ -17,7 +17,7 @@ sub new {
|
||||
$self = [ @_ ];
|
||||
}
|
||||
|
||||
bless $self, $class;
|
||||
bless $self, $class;use XXX; ZZZ $self if !defined $self->[0];
|
||||
bless $_, 'Slic3r::Point' for @$self;
|
||||
$self;
|
||||
}
|
||||
@ -29,19 +29,20 @@ sub clone {
|
||||
|
||||
sub serialize {
|
||||
my $self = shift;
|
||||
my $s = \ pack 'l*', map @$_, @$self;
|
||||
bless $s, ref $self;
|
||||
return $s;
|
||||
return pack 'l*', map @$_, @$self;
|
||||
}
|
||||
|
||||
sub deserialize {
|
||||
my $class = shift;
|
||||
my ($s) = @_;
|
||||
|
||||
my @v = unpack '(l2)*', $s;
|
||||
return $class->new(map [ $v[2*$_], $v[2*$_+1] ], 0 .. int($#v/2));
|
||||
}
|
||||
|
||||
sub is_serialized {
|
||||
my $self = shift;
|
||||
return $self if reftype $self ne 'SCALAR';
|
||||
my @v = unpack '(l2)*', $$self;
|
||||
my $o = [ map [ $v[2*$_], $v[2*$_+1] ], 0 .. int($#v/2) ];
|
||||
bless $_, 'Slic3r::Point' for @$o;
|
||||
bless $o, ref $self;
|
||||
return $o;
|
||||
return (reftype $self) eq 'SCALAR' ? 1 : 0;
|
||||
}
|
||||
|
||||
sub id {
|
||||
|
@ -436,7 +436,7 @@ sub make_skirt {
|
||||
my @layer_points = (
|
||||
(map @$_, map @{$_->expolygon}, map @{$_->slices}, @layers),
|
||||
(map @$_, map @{$_->thin_walls}, @layers),
|
||||
(map @{$_->polyline->deserialize}, map @{$_->support_fills->paths}, grep $_->support_fills, @layers),
|
||||
(map @{$_->unpack->polyline}, map @{$_->support_fills->paths}, grep $_->support_fills, @layers),
|
||||
);
|
||||
push @points, map move_points($_, @layer_points), @{$self->copies->[$obj_idx]};
|
||||
}
|
||||
@ -451,7 +451,7 @@ sub make_skirt {
|
||||
for (my $i = $Slic3r::skirts; $i > 0; $i--) {
|
||||
my $distance = scale ($Slic3r::skirt_distance + ($flow->spacing * $i));
|
||||
my $outline = offset([$convex_hull], $distance, $Slic3r::scaling_factor * 100, JT_ROUND);
|
||||
push @skirt, Slic3r::ExtrusionLoop->new(
|
||||
push @skirt, Slic3r::ExtrusionLoop->pack(
|
||||
polygon => Slic3r::Polygon->new(@{$outline->[0]}),
|
||||
role => EXTR_ROLE_SKIRT,
|
||||
);
|
||||
@ -474,7 +474,7 @@ sub make_brim {
|
||||
my $flow = $Slic3r::first_layer_flow || $Slic3r::flow;
|
||||
my $num_loops = sprintf "%.0f", $Slic3r::brim_width / $flow->width;
|
||||
for my $i (reverse 1 .. $num_loops) {
|
||||
push @{$self->brim}, Slic3r::ExtrusionLoop->new(
|
||||
push @{$self->brim}, Slic3r::ExtrusionLoop->pack(
|
||||
polygon => Slic3r::Polygon->new($_),
|
||||
role => EXTR_ROLE_SKIRT,
|
||||
) for @{Math::Clipper::offset(\@islands, $i * scale $flow->spacing)};
|
||||
|
@ -560,7 +560,6 @@ sub generate_support_material {
|
||||
flow_spacing => $params->{flow_spacing},
|
||||
), @paths;
|
||||
}
|
||||
$_->deserialize for @patterns;
|
||||
push @$support_patterns, [@patterns];
|
||||
}
|
||||
|
||||
@ -580,7 +579,9 @@ sub generate_support_material {
|
||||
my ($layer_id, $expolygons) = @_;
|
||||
my @paths = ();
|
||||
foreach my $expolygon (@$expolygons) {
|
||||
push @paths, map { $_->deserialize; $_->clip_with_expolygon($expolygon) }
|
||||
push @paths,
|
||||
map $_->pack,
|
||||
map $_->clip_with_expolygon($expolygon),
|
||||
map $_->clip_with_polygon($expolygon->bounding_box_polygon),
|
||||
@{$support_patterns->[ $layer_id % @$support_patterns ]};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user