Refactoring: use indexed vertices

This commit is contained in:
Alessandro Ranellucci 2012-02-17 13:49:33 +01:00
parent 2e44f60c61
commit f814ccf062
3 changed files with 45 additions and 36 deletions

View File

@ -64,7 +64,7 @@ sub new_from_mesh {
# transform vertex coordinates # transform vertex coordinates
my ($normal, @vertices) = @$facet; my ($normal, @vertices) = @$facet;
$mesh->_facet($print, $i, $normal, @vertices); $mesh->slice_facet($print, $i, $normal, @vertices);
} }
die "Invalid input file\n" if !@{$print->layers}; die "Invalid input file\n" if !@{$print->layers};

View File

@ -10,7 +10,6 @@ sub read_file {
my ($file) = @_; my ($file) = @_;
open my $fh, '<', $file or die "Failed to open $file\n"; open my $fh, '<', $file or die "Failed to open $file\n";
my $facets = [];
# let's detect whether file is ASCII or binary # let's detect whether file is ASCII or binary
my $mode; my $mode;
@ -35,12 +34,28 @@ sub read_file {
$mode = ($size == $expected_size) ? 'binary' : 'ascii'; $mode = ($size == $expected_size) ? 'binary' : 'ascii';
} }
my $facets = [];
$mode eq 'ascii' $mode eq 'ascii'
? _read_ascii($fh, $facets) ? _read_ascii($fh, $facets)
: _read_binary($fh, $facets); : _read_binary($fh, $facets);
close $fh; close $fh;
return Slic3r::TriangleMesh->new(facets => $facets);
my $vertices = [];
{
my %vertices_map = ();
foreach my $facet (@$facets) {
for (1..3) {
if ($vertices_map{$facet->[$_]}) {
$facet->[$_] = $vertices_map{$facet->[$_]};
} else {
push @$vertices, $facet->[$_];
$facet->[$_] = $vertices_map{$facet->[$_]} = $#$vertices;
}
}
}
}
return Slic3r::TriangleMesh->new(vertices => $vertices, facets => $facets);
} }
sub _read_ascii { sub _read_ascii {

View File

@ -5,6 +5,7 @@ use Slic3r::Geometry qw(X Y Z A B PI epsilon same_point points_coincide angle3po
merge_collinear_lines nearest_point polyline_lines); merge_collinear_lines nearest_point polyline_lines);
use XXX; use XXX;
has 'vertices' => (is => 'ro', default => sub { [] });
has 'facets' => (is => 'ro', default => sub { [] }); has 'facets' => (is => 'ro', default => sub { [] });
has 'edges' => (is => 'ro', default => sub { [] }); has 'edges' => (is => 'ro', default => sub { [] });
has 'edge_table' => (is => 'ro', default => sub { {} }); has 'edge_table' => (is => 'ro', default => sub { {} });
@ -234,11 +235,10 @@ sub rotate {
return if $deg == 0; return if $deg == 0;
my $rad = Slic3r::Geometry::deg2rad($deg); my $rad = Slic3r::Geometry::deg2rad($deg);
foreach my $facet (@{$self->facets}) {
my ($normal, @vertices) = @$facet; # transform vertex coordinates
foreach my $vertex (@vertices) { foreach my $vertex (@{$self->vertices}) {
@$vertex = (@{ +(Slic3r::Geometry::rotate_points($rad, undef, [ $vertex->[X], $vertex->[Y] ]))[0] }, $vertex->[Z]); @$vertex = (@{ +(Slic3r::Geometry::rotate_points($rad, undef, [ $vertex->[X], $vertex->[Y] ]))[0] }, $vertex->[Z]);
}
} }
} }
@ -247,12 +247,9 @@ sub scale {
my ($factor) = @_; my ($factor) = @_;
return if $factor == 1; return if $factor == 1;
foreach my $facet (@{$self->facets}) { # transform vertex coordinates
# transform vertex coordinates foreach my $vertex (@{$self->vertices}) {
my ($normal, @vertices) = @$facet; $vertex->[$_] *= $factor for X,Y,Z;
foreach my $vertex (@vertices) {
$vertex->[$_] *= $factor for X,Y,Z;
}
} }
} }
@ -260,12 +257,9 @@ sub move {
my $self = shift; my $self = shift;
my (@shift) = @_; my (@shift) = @_;
foreach my $facet (@{$self->facets}) { # transform vertex coordinates
# transform vertex coordinates foreach my $vertex (@{$self->vertices}) {
my ($normal, @vertices) = @$facet; $vertex->[$_] += $shift[$_] for X,Y,Z;
foreach my $vertex (@vertices) {
$vertex->[$_] += $shift[$_] for X,Y,Z;
}
} }
} }
@ -280,7 +274,8 @@ sub duplicate {
foreach my $shift (@shifts) { foreach my $shift (@shifts) {
push @new_facets, [ $normal ]; push @new_facets, [ $normal ];
foreach my $vertex (@vertices) { foreach my $vertex (@vertices) {
push @{$new_facets[-1]}, [ map $vertex->[$_] + ($shift->[$_] || 0), (X,Y,Z) ]; push @{$self->vertices}, [ map $self->vertices->[$vertex][$_] + ($shift->[$_] || 0), (X,Y,Z) ];
push @{$new_facets[-1]}, $#{$self->vertices};
} }
} }
} }
@ -289,14 +284,11 @@ sub duplicate {
sub bounding_box { sub bounding_box {
my $self = shift; my $self = shift;
my @extents = (map [9999999999999999999999, -9999999999999999999999], X,Y,Z); my @extents = (map [undef, undef], X,Y,Z);
foreach my $facet (@{$self->facets}) { foreach my $vertex (@{$self->vertices}) {
my ($normal, @vertices) = @$facet; for (X,Y,Z) {
foreach my $vertex (@vertices) { $extents[$_][MIN] = $vertex->[$_] if !defined $extents[$_][MIN] || $vertex->[$_] < $extents[$_][MIN];
for (X,Y,Z) { $extents[$_][MAX] = $vertex->[$_] if !defined $extents[$_][MAX] || $vertex->[$_] > $extents[$_][MAX];
$extents[$_][MIN] = $vertex->[$_] if $vertex->[$_] < $extents[$_][MIN];
$extents[$_][MAX] = $vertex->[$_] if $vertex->[$_] > $extents[$_][MAX];
}
} }
} }
return @extents; return @extents;
@ -309,16 +301,18 @@ sub size {
return map $extents[$_][MAX] - $extents[$_][MIN], (X,Y,Z); return map $extents[$_][MAX] - $extents[$_][MIN], (X,Y,Z);
} }
sub _facet { sub slice_facet {
my $self = shift; my $self = shift;
my ($print, $facet_index, $normal, @vertices) = @_; my ($print, $facet_index, $normal, @vertices) = @_;
Slic3r::debugf "\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", Slic3r::debugf "\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n",
$facet_index, map @$_, @vertices $facet_index, map @{$self->vertices->[$_]}, @vertices
if $Slic3r::debug; if $Slic3r::debug;
my @vertices_coordinates = map $self->vertices->[$_], @vertices;
# find the vertical extents of the facet # find the vertical extents of the facet
my ($min_z, $max_z) = (99999999999, -99999999999); my ($min_z, $max_z) = (99999999999, -99999999999);
foreach my $vertex (@vertices) { foreach my $vertex (@vertices_coordinates) {
$min_z = $vertex->[Z] if $vertex->[Z] < $min_z; $min_z = $vertex->[Z] if $vertex->[Z] < $min_z;
$max_z = $vertex->[Z] if $vertex->[Z] > $max_z; $max_z = $vertex->[Z] if $vertex->[Z] > $max_z;
} }
@ -341,7 +335,7 @@ sub _facet {
# this is needed to get all intersection lines in a consistent order # this is needed to get all intersection lines in a consistent order
# (external on the right of the line) # (external on the right of the line)
{ {
my @z_order = sort { $vertices[$a][Z] <=> $vertices[$b][Z] } 0..2; my @z_order = sort { $vertices_coordinates[$a][Z] <=> $vertices_coordinates[$b][Z] } 0..2;
@vertices = (splice(@vertices, $z_order[0]), splice(@vertices, 0, $z_order[0])); @vertices = (splice(@vertices, $z_order[0]), splice(@vertices, 0, $z_order[0]));
} }
@ -367,7 +361,7 @@ sub intersect_facet {
if (abs($a->[Z] - $b->[Z]) < epsilon && abs($a->[Z] - $z) < epsilon) { if (abs($a->[Z] - $b->[Z]) < epsilon && abs($a->[Z] - $z) < epsilon) {
# edge is horizontal and belongs to the current layer # edge is horizontal and belongs to the current layer
my $edge_type = (grep $_->[Z] < $z - epsilon, @$vertices) ? 'top' : 'bottom'; my $edge_type = (grep $self->vertices->[$_][Z] < $z - epsilon, @$vertices) ? 'top' : 'bottom';
($a, $b) = ($b, $a) if $edge_type eq 'top'; ($a, $b) = ($b, $a) if $edge_type eq 'top';
push @lines, Slic3r::TriangleMesh::IntersectionLine->new( push @lines, Slic3r::TriangleMesh::IntersectionLine->new(
a => [$a->[X], $a->[Y]], a => [$a->[X], $a->[Y]],
@ -440,7 +434,7 @@ sub facet_edges {
my ($facet) = @_; my ($facet) = @_;
# ignore the normal if provided # ignore the normal if provided
my @vertices = @$facet[-3..-1]; my @vertices = map $self->vertices->[$_], @$facet[-3..-1];
return ( return (
[ $vertices[0], $vertices[1] ], [ $vertices[0], $vertices[1] ],