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 # 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 # 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 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))) { && ($Slic3r::fill_density == 0 || $distance_from_last_pos >= $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2))) {
$gcode .= $self->retract; $gcode .= $self->retract;
@ -135,7 +135,7 @@ sub G1 {
$gcode .= sprintf " X%.${dec}f Y%.${dec}f", $gcode .= sprintf " X%.${dec}f Y%.${dec}f",
($point->x * $Slic3r::resolution) + $self->shift_x, ($point->x * $Slic3r::resolution) + $self->shift_x,
($point->y * $Slic3r::resolution) + $self->shift_y; #** ($point->y * $Slic3r::resolution) + $self->shift_y; #**
$self->last_pos($point->p); $self->last_pos($point);
} }
if (defined $z && $z != $self->z) { if (defined $z && $z != $self->z) {
$self->z($z); $self->z($z);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,7 +24,7 @@ sub cast {
my $class = shift; my $class = shift;
my ($points) = @_; 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); return $class->new(points => $points);
} }
@ -43,7 +43,7 @@ sub lines {
sub p { sub p {
my $self = shift; my $self = shift;
return [ map $_->p, @{$self->points} ]; return [ @{$self->points} ];
} }
sub merge_continuous_lines { sub merge_continuous_lines {
@ -54,7 +54,7 @@ sub merge_continuous_lines {
} else { } else {
polyline_remove_parallel_continuous_edges($points); polyline_remove_parallel_continuous_edges($points);
} }
@{$self->points} = map Slic3r::Point->cast($_), @$points; @{$self->points} = map Slic3r::Point->new($_), @$points;
} }
sub remove_acute_vertices { sub remove_acute_vertices {
@ -65,7 +65,7 @@ sub remove_acute_vertices {
} else { } else {
polyline_remove_acute_vertices($points); polyline_remove_acute_vertices($points);
} }
@{$self->points} = map Slic3r::Point->cast($_), @$points; @{$self->points} = map Slic3r::Point->new($_), @$points;
} }
sub cleanup { sub cleanup {
@ -74,7 +74,7 @@ sub cleanup {
my $points = $self->p; my $points = $self->p;
push @$points, $points->[0] if $self->isa('Slic3r::Polyline::Closed'); 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); Slic3r::Geometry::Douglas_Peucker($self->p, $tolerance);
pop @clean_points if $self->isa('Slic3r::Polyline::Closed'); pop @clean_points if $self->isa('Slic3r::Polyline::Closed');
@{$self->points} = @clean_points; @{$self->points} = @clean_points;
@ -104,11 +104,8 @@ sub nearest_point_to {
my $self = shift; my $self = shift;
my ($point) = @_; my ($point) = @_;
# get point as arrayref
$point = ref $point eq 'ARRAY' ? $point : $point->p;
$point = Slic3r::Geometry::nearest_point($point, $self->p); $point = Slic3r::Geometry::nearest_point($point, $self->p);
return Slic3r::Point->cast($point); return Slic3r::Point->new($point);
} }
sub has_segment { 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 # okay, this is an Ugly Hack(tm) to avoid floating point math problems
# with diagonal bridges. will find a nicer solution, promised. # with diagonal bridges. will find a nicer solution, promised.
my $offset = offset([$_->contour->p], 100, 100, JT_MITER, 2); 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", #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 { sub _read_binary {