Optimization: cache model bounding box

This commit is contained in:
Alessandro Ranellucci 2013-06-22 19:36:50 +02:00
parent c88d8a5842
commit 82fbdb603f
2 changed files with 51 additions and 13 deletions

View File

@ -62,6 +62,18 @@ sub scale {
$self; $self;
} }
sub translate {
my $self = shift;
my @shift = @_;
for my $axis (X .. $#{$self->extents}) {
$self->extents->[$axis][MIN] += $shift[$axis];
$self->extents->[$axis][MAX] += $shift[$axis];
}
$self;
}
sub size { sub size {
my $self = shift; my $self = shift;

View File

@ -6,6 +6,7 @@ use Slic3r::Geometry qw(X Y Z MIN move_points);
has 'materials' => (is => 'ro', default => sub { {} }); has 'materials' => (is => 'ro', default => sub { {} });
has 'objects' => (is => 'ro', default => sub { [] }); has 'objects' => (is => 'ro', default => sub { [] });
has '_bounding_box' => (is => 'rw');
sub read_from_file { sub read_from_file {
my $class = shift; my $class = shift;
@ -57,6 +58,7 @@ sub add_object {
my $object = Slic3r::Model::Object->new(model => $self, @_); my $object = Slic3r::Model::Object->new(model => $self, @_);
push @{$self->objects}, $object; push @{$self->objects}, $object;
$self->_bounding_box(undef);
return $object; return $object;
} }
@ -70,11 +72,6 @@ sub set_material {
); );
} }
sub scale {
my $self = shift;
$_->scale(@_) for @{$self->objects};
}
sub arrange_objects { sub arrange_objects {
my $self = shift; my $self = shift;
my ($config) = @_; my ($config) = @_;
@ -151,8 +148,9 @@ sub _arrange {
return ($config->duplicate_grid->[X] * $config->duplicate_grid->[Y]), @positions; return ($config->duplicate_grid->[X] * $config->duplicate_grid->[Y]), @positions;
} else { } else {
my $total_parts = $config->duplicate * @items; my $total_parts = $config->duplicate * @items;
my $partx = max(map $_->size->[X], @items); my @sizes = map $_->size, @items;
my $party = max(map $_->size->[Y], @items); my $partx = max(map $_->[X], @sizes);
my $party = max(map $_->[Y], @sizes);
return $config->duplicate, return $config->duplicate,
Slic3r::Geometry::arrange Slic3r::Geometry::arrange
($total_parts, $partx, $party, (map $_, @{$config->bed_size}), ($total_parts, $partx, $party, (map $_, @{$config->bed_size}),
@ -172,12 +170,16 @@ sub used_vertices {
sub size { sub size {
my $self = shift; my $self = shift;
return [ Slic3r::Geometry::size_3D($self->used_vertices) ]; return $self->bounding_box->size;
} }
sub bounding_box { sub bounding_box {
my $self = shift; my $self = shift;
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
if (!defined $self->_bounding_box) {
$self->_bounding_box(Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices));
}
return $self->_bounding_box;
} }
sub align_to_origin { sub align_to_origin {
@ -198,9 +200,18 @@ sub align_to_origin {
} }
} }
sub scale {
my $self = shift;
$_->scale(@_) for @{$self->objects};
$self->_bounding_box->scale(@_) if defined $self->_bounding_box;
}
sub move { sub move {
my $self = shift; my $self = shift;
$_->move(@_) for @{$self->objects}; my @shift = @_;
$_->move(@shift) for @{$self->objects};
$self->_bounding_box->translate(@shift) if defined $self->_bounding_box;
} }
# flattens everything to a single mesh # flattens everything to a single mesh
@ -286,6 +297,7 @@ has 'vertices' => (is => 'ro', default => sub { [] });
has 'volumes' => (is => 'ro', default => sub { [] }); has 'volumes' => (is => 'ro', default => sub { [] });
has 'instances' => (is => 'rw'); has 'instances' => (is => 'rw');
has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ] has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ]
has '_bounding_box' => (is => 'rw');
sub add_volume { sub add_volume {
my $self = shift; my $self = shift;
@ -304,6 +316,8 @@ sub add_volume {
my $volume = Slic3r::Model::Volume->new(object => $self, %args); my $volume = Slic3r::Model::Volume->new(object => $self, %args);
push @{$self->volumes}, $volume; push @{$self->volumes}, $volume;
$self->_bounding_box(undef);
$self->model->_bounding_box(undef);
return $volume; return $volume;
} }
@ -312,6 +326,7 @@ sub add_instance {
$self->instances([]) if !defined $self->instances; $self->instances([]) if !defined $self->instances;
push @{$self->instances}, Slic3r::Model::Instance->new(object => $self, @_); push @{$self->instances}, Slic3r::Model::Instance->new(object => $self, @_);
$self->model->_bounding_box(undef);
return $self->instances->[-1]; return $self->instances->[-1];
} }
@ -333,7 +348,7 @@ sub used_vertices {
sub size { sub size {
my $self = shift; my $self = shift;
return [ Slic3r::Geometry::size_3D($self->used_vertices) ]; return $self->bounding_box->size;
} }
sub center { sub center {
@ -343,7 +358,11 @@ sub center {
sub bounding_box { sub bounding_box {
my $self = shift; my $self = shift;
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
if (!defined $self->_bounding_box) {
$self->_bounding_box(Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices));
}
return $self->_bounding_box;
} }
sub align_to_origin { sub align_to_origin {
@ -359,7 +378,10 @@ sub align_to_origin {
sub move { sub move {
my $self = shift; my $self = shift;
@{$self->vertices} = move_points_3D([ @_ ], @{$self->vertices}); my @shift = @_;
@{$self->vertices} = move_points_3D([ @shift ], @{$self->vertices});
$self->_bounding_box->translate(@shift) if defined $self->_bounding_box;
} }
sub scale { sub scale {
@ -371,6 +393,8 @@ sub scale {
foreach my $vertex (@{$self->vertices}) { foreach my $vertex (@{$self->vertices}) {
$vertex->[$_] *= $factor for X,Y,Z; $vertex->[$_] *= $factor for X,Y,Z;
} }
$self->_bounding_box->scale($factor) if defined $self->_bounding_box;
} }
sub rotate { sub rotate {
@ -384,6 +408,8 @@ sub rotate {
foreach my $vertex (@{$self->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]);
} }
$self->_bounding_box(undef);
} }
sub materials_count { sub materials_count {