Refactored Line objects to arrayrefs

This commit is contained in:
Alessandro Ranellucci 2011-10-12 16:27:40 +02:00
parent e410410dc7
commit c97a89c07c
10 changed files with 47 additions and 44 deletions

View file

@ -104,7 +104,6 @@ sub add_line {
my $self = shift;
my ($line) = @_;
$line = Slic3r::Line->cast($line);
return if $line->a->coincides_with($line->b);
push @{ $self->lines }, $line;
@ -135,7 +134,7 @@ sub make_surfaces {
# so a simple head-to-tail algorithm would work
my @lines = ();
push @lines, map $_->p, @{$self->lines};
push @lines, @{$self->lines};
#@lines = grep line_length($_) > xx, @lines;
#use Slic3r::SVG;

View file

@ -1,26 +1,25 @@
package Slic3r::Line;
use Moo;
use strict;
use warnings;
# arrayref of points
has 'points' => (
is => 'rw',
default => sub { [] },
required => 1,
);
sub cast {
sub new {
my $class = shift;
my ($line, %args) = @_;
if (ref $line eq 'ARRAY') {
@$line == 2 or die "Line needs two points!";
return $class->new(points => [ map Slic3r::Point->new($_), @$line ], %args);
my $self;
if (@_ == 2) {
$self = [ map Slic3r::Point->new($_), @_ ];
} elsif (ref $_[0] eq 'ARRAY') {
$self = [ map Slic3r::Point->new($_), @{$_[0]} ];
} elsif ($_[0]->isa(__PACKAGE__)) {
return $_[0];
} else {
return $line;
die "Invalid argument for $class->new";
}
bless $self, $class;
return $self;
}
sub a { return $_[0]->points->[0] }
sub b { return $_[0]->points->[1] }
sub a { $_[0][0] }
sub b { $_[0][1] }
sub id {
my $self = shift;
@ -29,7 +28,7 @@ sub id {
sub ordered_id {
my $self = shift;
return join('-', sort map $_->id, @{$self->points});
return join('-', sort map $_->id, @$self);
}
sub coordinates {
@ -37,11 +36,6 @@ sub coordinates {
return ($self->a->coordinates, $self->b->coordinates);
}
sub p {
my $self = shift;
return [ $self->a, $self->b ];
}
sub coincides_with {
my $self = shift;
my ($line) = @_;
@ -60,17 +54,15 @@ sub has_segment {
my $self = shift;
my ($line) = @_;
$line = $line->p if $line->isa('Slic3r::Line');
# a segment belongs to another segment if its points belong to it
return Slic3r::Geometry::point_in_segment($line->[0], $self->p)
&& Slic3r::Geometry::point_in_segment($line->[1], $self->p);
return Slic3r::Geometry::point_in_segment($line->[0], $self)
&& Slic3r::Geometry::point_in_segment($line->[1], $self);
}
sub parallel_to {
my $self = shift;
my ($line) = @_;
return Slic3r::Geometry::lines_parallel($self->p, $line->p);
return Slic3r::Geometry::lines_parallel($self, $line);
}
1;

View file

@ -3,6 +3,7 @@ use Moo;
extends 'Slic3r::Line';
has 'edge_type' => (is => 'ro'); # top/bottom
use Slic3r::Line::FacetEdge::Bottom;
use Slic3r::Line::FacetEdge::Top;
1;

View file

@ -0,0 +1,6 @@
package Slic3r::Line::FacetEdge::Bottom;
use Moo;
extends 'Slic3r::Line::FacetEdge';
1;

View file

@ -0,0 +1,6 @@
package Slic3r::Line::FacetEdge::Top;
use Moo;
extends 'Slic3r::Line::FacetEdge';
1;

View file

@ -12,6 +12,8 @@ sub new {
} elsif ($_[0]->isa(__PACKAGE__)) {
return $_[0];
} else {
use XXX;
ZZZ "test";
die "Invalid arguments for ${class}->new";
}
bless $self, $class;

View file

@ -34,7 +34,7 @@ sub lines {
my $previous_point;
foreach my $point (@{ $self->points }) {
if ($previous_point) {
push @lines, Slic3r::Line->new(points => [ $previous_point, $point ]);
push @lines, Slic3r::Line->new($previous_point, $point);
}
$previous_point = $point;
}

View file

@ -11,7 +11,7 @@ sub lines {
# since this is a closed polyline, we just add a line at the end,
# connecting the last and the first point
push @lines, Slic3r::Line->new(points => [$self->points->[-1], $self->points->[0]]);
push @lines, Slic3r::Line->new($self->points->[-1], $self->points->[0]);
return @lines;
}

View file

@ -150,11 +150,10 @@ sub intersect_facet {
if ($a->[Z] == $b->[Z] && $a->[Z] == $z) {
# edge is horizontal and belongs to the current layer
my $edge_type = (grep $_->[Z] > $z, @$vertices) ? 'bottom' : 'top';
($a, $b) = ($b, $a) if $edge_type eq 'bottom';
push @lines, Slic3r::Line::FacetEdge->cast(
[ [$a->[X], $a->[Y]], [$b->[X], $b->[Y]] ],
edge_type => $edge_type,
my $edge_type = (grep $_->[Z] > $z, @$vertices) ? 'Bottom' : 'Top';
($a, $b) = ($b, $a) if $edge_type eq 'Bottom';
push @lines, "Slic3r::Line::FacetEdge::$edge_type"->new(
[$a->[X], $a->[Y]], [$b->[X], $b->[Y]],
);
#print "Horizontal edge at $z!\n";
@ -192,7 +191,7 @@ sub intersect_facet {
#}
# connect points:
push @lines, Slic3r::Line->cast([ @intersection_points ]);
push @lines, Slic3r::Line->new(@intersection_points);
#printf " intersection points = %f,%f - %f,%f\n", map @$_, @intersection_points;
}

10
t/stl.t
View file

@ -2,7 +2,7 @@ use Test::More;
use strict;
use warnings;
plan tests => 11;
plan tests => 9;
BEGIN {
use FindBin;
@ -32,15 +32,13 @@ is_deeply lines(24, 10, 20), [ [ [4, 4], [1, 9] ] ], 'one vertex on plan
my @lower = $stl->intersect_facet(vertices(22, 20, 20), $z);
my @upper = $stl->intersect_facet(vertices(20, 20, 10), $z);
isa_ok $lower[0], 'Slic3r::Line::FacetEdge', 'bottom edge on layer';
isa_ok $upper[0], 'Slic3r::Line::FacetEdge', 'upper edge on layer';
is $lower[0]->edge_type, 'bottom', 'lower edge is detected as bottom';
is $upper[0]->edge_type, 'top', 'upper edge is detected as top';
isa_ok $lower[0], 'Slic3r::Line::FacetEdge::Bottom', 'bottom edge on layer';
isa_ok $upper[0], 'Slic3r::Line::FacetEdge::Top', 'upper edge on layer';
sub vertices {
[ map [ @{$points[$_]}, $_[$_] ], 0..2 ]
}
sub lines {
[ map [ map ref $_ eq 'Slic3r::Point' ? $_->p : [ map sprintf('%.0f', $_), @$_ ], @$_ ], map $_->p, $stl->intersect_facet(vertices(@_), $z) ];
[ map [ map [ map sprintf('%.0f', $_), @$_ ], @$_ ], $stl->intersect_facet(vertices(@_), $z) ];
}