Refactoring. Point objects are now plain arrayrefs. Slicing is 30% faster.

This commit is contained in:
Alessandro Ranellucci 2011-10-12 14:54:49 +02:00
parent 774717c8bb
commit e410410dc7
10 changed files with 44 additions and 55 deletions

View file

@ -73,7 +73,7 @@ sub extrude {
# retract if distance from previous position is greater or equal to the one
# specified by the user *and* to the maximum distance between infill lines
my $distance_from_last_pos = Slic3r::Geometry::distance_between_points($self->last_pos, $path->points->[0]->p) * $Slic3r::resolution;
my $distance_from_last_pos = Slic3r::Geometry::distance_between_points($self->last_pos, $path->points->[0]) * $Slic3r::resolution;
if ($distance_from_last_pos >= $Slic3r::retract_before_travel
&& ($Slic3r::fill_density == 0 || $distance_from_last_pos >= $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2))) {
$gcode .= $self->retract;
@ -135,7 +135,7 @@ sub G1 {
$gcode .= sprintf " X%.${dec}f Y%.${dec}f",
($point->x * $Slic3r::resolution) + $self->shift_x,
($point->y * $Slic3r::resolution) + $self->shift_y; #**
$self->last_pos($point->p);
$self->last_pos($point);
}
if (defined $z && $z != $self->z) {
$self->z($z);

View file

@ -9,7 +9,7 @@ sub split_at {
my $self = shift;
my ($point) = @_;
$point = Slic3r::Point->cast($point);
$point = Slic3r::Point->new($point);
# find index of point
my $i = -1;

View file

@ -18,17 +18,15 @@ sub clip_end {
next;
}
my $new_point = Slic3r::Geometry::point_along_segment($last_point->p, $self->points->[-1]->p, $distance);
push @{$self->points}, Slic3r::Point->cast($new_point);
my $new_point = Slic3r::Geometry::point_along_segment($last_point, $self->points->[-1], $distance);
push @{$self->points}, Slic3r::Point->new($new_point);
$distance = 0;
}
}
sub endpoints {
my $self = shift;
my ($as_arrayref) = @_;
my @points = ($self->points->[0], $self->points->[-1]);
return $as_arrayref ? map($_->p, @points) : @points;
return ($self->points->[0], $self->points->[-1]);
}
sub reverse {

View file

@ -18,22 +18,18 @@ sub add {
sub endpoints {
my $self = shift;
my ($as_arrayref) = @_;
return map $_->endpoints($as_arrayref), @{$self->paths};
return map $_->endpoints, @{$self->paths};
}
sub shortest_path {
my $self = shift;
my ($start_near) = @_;
# get point as arrayref
$start_near = $start_near->p if $start_near && ref $start_near ne 'ARRAY';
my @paths = ();
my $start_at;
CYCLE: while (@{$self->paths}) {
# find nearest point
$start_at = Slic3r::Point->cast(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints(1) ]));
$start_at = Slic3r::Point->new(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints ]));
# loop through paths to find the one that starts or ends at the point found
PATH: for (my $i = 0; $i <= $#{$self->paths}; $i++) {
@ -45,7 +41,7 @@ sub shortest_path {
} else {
next PATH;
}
$start_near = $paths[-1]->points->[-1]->p;
$start_near = $paths[-1]->points->[-1];
next CYCLE;
}
}

View file

@ -87,7 +87,7 @@ sub add_surface {
my (@vertices) = @_;
# convert arrayref points to Point objects
@vertices = map Slic3r::Point->cast($_), @vertices;
@vertices = map Slic3r::Point->new($_), @vertices;
my $surface = Slic3r::Surface->new(
contour => Slic3r::Polyline::Closed->new(points => \@vertices),

View file

@ -13,7 +13,7 @@ sub cast {
my ($line, %args) = @_;
if (ref $line eq 'ARRAY') {
@$line == 2 or die "Line needs two points!";
return $class->new(points => [ map Slic3r::Point->cast($_), @$line ], %args);
return $class->new(points => [ map Slic3r::Point->new($_), @$line ], %args);
} else {
return $line;
}
@ -39,7 +39,7 @@ sub coordinates {
sub p {
my $self = shift;
return [ $self->a->p, $self->b->p ];
return [ $self->a, $self->b ];
}
sub coincides_with {

View file

@ -1,51 +1,46 @@
package Slic3r::Point;
use Moo;
use strict;
use warnings;
has 'x' => (
is => 'ro',
required => 1,
#coerce => sub { sprintf '%.0f', $_[0] },
);
has 'y' => (
is => 'ro',
required => 1,
#coerce => sub { sprintf '%.0f', $_[0] },
);
sub cast {
sub new {
my $class = shift;
my ($point) = @_;
return ref $point eq 'ARRAY'
? Slic3r::Point->new(x => $point->[0], y => $point->[1]) # ==
: $point;
my $self;
if (@_ == 2) {
$self = [@_];
} elsif (ref $_[0] eq 'ARRAY') {
$self = [@{$_[0]}];
} elsif ($_[0]->isa(__PACKAGE__)) {
return $_[0];
} else {
die "Invalid arguments for ${class}->new";
}
bless $self, $class;
return $self;
}
sub id {
my $self = shift;
return $self->x . "," . $self->y; #;;
return join ',', @$self;
}
sub coordinates {
my $self = shift;
return ($self->x, $self->y); #))
}
sub p {
my $self = shift;
return [ $self->coordinates ];
return @$self;
}
sub coincides_with {
my $self = shift;
my ($point) = @_;
return Slic3r::Geometry::points_coincide($self->p, $point->p);
return Slic3r::Geometry::points_coincide($self, $point);
}
sub distance_to {
my $self = shift;
my ($point) = @_;
return Slic3r::Geometry::distance_between_points($self->p, $point->p);
return Slic3r::Geometry::distance_between_points($self, $point);
}
sub x { $_[0]->[0] }
sub y { $_[0]->[1] }
1;

View file

@ -24,7 +24,7 @@ sub cast {
my $class = shift;
my ($points) = @_;
$points = [ map { ref $_ eq 'ARRAY' ? Slic3r::Point->cast($_) : $_ } @$points ];
$points = [ map { ref $_ eq 'ARRAY' ? Slic3r::Point->new($_) : $_ } @$points ];
return $class->new(points => $points);
}
@ -43,7 +43,7 @@ sub lines {
sub p {
my $self = shift;
return [ map $_->p, @{$self->points} ];
return [ @{$self->points} ];
}
sub merge_continuous_lines {
@ -54,7 +54,7 @@ sub merge_continuous_lines {
} else {
polyline_remove_parallel_continuous_edges($points);
}
@{$self->points} = map Slic3r::Point->cast($_), @$points;
@{$self->points} = map Slic3r::Point->new($_), @$points;
}
sub remove_acute_vertices {
@ -65,7 +65,7 @@ sub remove_acute_vertices {
} else {
polyline_remove_acute_vertices($points);
}
@{$self->points} = map Slic3r::Point->cast($_), @$points;
@{$self->points} = map Slic3r::Point->new($_), @$points;
}
sub cleanup {
@ -74,7 +74,7 @@ sub cleanup {
my $points = $self->p;
push @$points, $points->[0] if $self->isa('Slic3r::Polyline::Closed');
my @clean_points = map Slic3r::Point->cast($_),
my @clean_points = map Slic3r::Point->new($_),
Slic3r::Geometry::Douglas_Peucker($self->p, $tolerance);
pop @clean_points if $self->isa('Slic3r::Polyline::Closed');
@{$self->points} = @clean_points;
@ -104,11 +104,8 @@ sub nearest_point_to {
my $self = shift;
my ($point) = @_;
# get point as arrayref
$point = ref $point eq 'ARRAY' ? $point : $point->p;
$point = Slic3r::Geometry::nearest_point($point, $self->p);
return Slic3r::Point->cast($point);
return Slic3r::Point->new($point);
}
sub has_segment {

View file

@ -146,7 +146,7 @@ sub detect_surfaces_type {
# okay, this is an Ugly Hack(tm) to avoid floating point math problems
# with diagonal bridges. will find a nicer solution, promised.
my $offset = offset([$_->contour->p], 100, 100, JT_MITER, 2);
@{$_->contour->points} = map Slic3r::Point->cast($_), @{ $offset->[0] };
@{$_->contour->points} = map Slic3r::Point->new($_), @{ $offset->[0] };
}
#Slic3r::SVG::output(undef, "layer_" . $layer->id . "_diff.svg",

View file

@ -258,6 +258,9 @@ sub _read_ascii {
}
}
}
if ($facet) {
die "STL file seems invalid\n";
}
}
sub _read_binary {