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

View file

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

View file

@ -3,6 +3,7 @@ use Moo;
extends 'Slic3r::Line'; extends 'Slic3r::Line';
has 'edge_type' => (is => 'ro'); # top/bottom use Slic3r::Line::FacetEdge::Bottom;
use Slic3r::Line::FacetEdge::Top;
1; 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__)) { } elsif ($_[0]->isa(__PACKAGE__)) {
return $_[0]; return $_[0];
} else { } else {
use XXX;
ZZZ "test";
die "Invalid arguments for ${class}->new"; die "Invalid arguments for ${class}->new";
} }
bless $self, $class; bless $self, $class;

View file

@ -34,7 +34,7 @@ sub lines {
my $previous_point; my $previous_point;
foreach my $point (@{ $self->points }) { foreach my $point (@{ $self->points }) {
if ($previous_point) { if ($previous_point) {
push @lines, Slic3r::Line->new(points => [ $previous_point, $point ]); push @lines, Slic3r::Line->new($previous_point, $point);
} }
$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, # since this is a closed polyline, we just add a line at the end,
# connecting the last and the first point # 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; return @lines;
} }

View file

@ -150,11 +150,10 @@ sub intersect_facet {
if ($a->[Z] == $b->[Z] && $a->[Z] == $z) { if ($a->[Z] == $b->[Z] && $a->[Z] == $z) {
# edge is horizontal and belongs to the current layer # edge is horizontal and belongs to the current layer
my $edge_type = (grep $_->[Z] > $z, @$vertices) ? 'bottom' : 'top'; my $edge_type = (grep $_->[Z] > $z, @$vertices) ? 'Bottom' : 'Top';
($a, $b) = ($b, $a) if $edge_type eq 'bottom'; ($a, $b) = ($b, $a) if $edge_type eq 'Bottom';
push @lines, Slic3r::Line::FacetEdge->cast( push @lines, "Slic3r::Line::FacetEdge::$edge_type"->new(
[ [$a->[X], $a->[Y]], [$b->[X], $b->[Y]] ], [$a->[X], $a->[Y]], [$b->[X], $b->[Y]],
edge_type => $edge_type,
); );
#print "Horizontal edge at $z!\n"; #print "Horizontal edge at $z!\n";
@ -192,7 +191,7 @@ sub intersect_facet {
#} #}
# connect points: # 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; #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 strict;
use warnings; use warnings;
plan tests => 11; plan tests => 9;
BEGIN { BEGIN {
use FindBin; 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 @lower = $stl->intersect_facet(vertices(22, 20, 20), $z);
my @upper = $stl->intersect_facet(vertices(20, 20, 10), $z); my @upper = $stl->intersect_facet(vertices(20, 20, 10), $z);
isa_ok $lower[0], 'Slic3r::Line::FacetEdge', 'bottom edge on layer'; isa_ok $lower[0], 'Slic3r::Line::FacetEdge::Bottom', 'bottom edge on layer';
isa_ok $upper[0], 'Slic3r::Line::FacetEdge', 'upper edge on layer'; isa_ok $upper[0], 'Slic3r::Line::FacetEdge::Top', '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';
sub vertices { sub vertices {
[ map [ @{$points[$_]}, $_[$_] ], 0..2 ] [ map [ @{$points[$_]}, $_[$_] ], 0..2 ]
} }
sub lines { 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) ];
} }