Some cleanup for the plater code

This commit is contained in:
Alessandro Ranellucci 2013-06-13 14:33:10 +02:00
parent def013ba91
commit 962a51cc80
3 changed files with 43 additions and 30 deletions

View File

@ -704,11 +704,6 @@ sub make_model {
foreach my $plater_object (@{$self->{objects}}) {
my $model_object = $plater_object->get_model_object;
# if we need to alter the mesh, clone it first
if ($plater_object->scale != 1) {
$model_object = $model_object->clone;
}
my $new_model_object = $model->add_object(
vertices => $model_object->vertices,
input_file => $plater_object->input_file,
@ -721,10 +716,10 @@ sub make_model {
);
$model->set_material($volume->material_id || 0, {});
}
$new_model_object->scale($plater_object->scale);
$new_model_object->align_to_origin;
$new_model_object->add_instance(
rotation => $plater_object->rotate, # around center point
scaling_factor => $plater_object->scale,
offset => Slic3r::Point->new($_),
) for @{$plater_object->instances};
}
@ -778,9 +773,12 @@ sub recenter {
map Slic3r::Geometry::move_points($_, @points), @{$obj->instances};
} @{$self->{objects}},
]);
# $self->{shift} contains the offset in pixels to add to object instances in order to center them
# it is expressed in upwards Y
$self->{shift} = [
($self->{canvas}->GetSize->GetWidth - $self->to_pixel($print_bb[X2] + $print_bb[X1])) / 2,
($self->{canvas}->GetSize->GetHeight - $self->to_pixel($print_bb[Y2] + $print_bb[Y1])) / 2,
$self->to_pixel(-$print_bb[X1]) + ($self->{canvas}->GetSize->GetWidth - $self->to_pixel($print_bb[X2] - $print_bb[X1])) / 2,
$self->to_pixel(-$print_bb[Y1]) + ($self->{canvas}->GetSize->GetHeight - $self->to_pixel($print_bb[Y2] - $print_bb[Y1])) / 2,
];
}
@ -814,10 +812,8 @@ sub _update_bed_size {
# supposing the preview canvas is square, calculate the scaling factor
# to constrain print bed area inside preview
my $bed_size = $self->{config}->bed_size;
my $canvas_side = CANVAS_SIZE->[X]; # when the canvas is not rendered yet, its GetSize() method returns 0,0
my $bed_largest_side = $bed_size->[X] > $bed_size->[Y] ? $bed_size->[X] : $bed_size->[Y];
$self->{scaling_factor} = $canvas_side / $bed_largest_side;
# when the canvas is not rendered yet, its GetSize() method returns 0,0
$self->{scaling_factor} = CANVAS_SIZE->[X] / max(@{ $self->{config}->bed_size });
$_->change_thumbnail_scaling_factor($self->{scaling_factor}) for @{ $self->{objects} };
$self->recenter;
}
@ -949,7 +945,6 @@ sub mouse_event {
my ($obj_idx, $instance_idx, $thumbnail) = @$preview;
my $instance = $parent->{objects}[$obj_idx]->instances->[$instance_idx];
$instance->[$_] = $parent->to_units($pos->[$_] - $self->{drag_start_pos}[$_] - $parent->{shift}[$_]) for X,Y;
$instance = $parent->_y([$instance])->[0];
$parent->Refresh;
}
} elsif ($event->Moving) {
@ -1098,10 +1093,12 @@ sub _trigger_model_object {
my $self = shift;
if ($self->model_object) {
$self->model_object->align_to_origin;
$self->bounding_box($self->model_object->bounding_box);
my $mesh = $self->model_object->mesh;
$self->bounding_box($mesh->bounding_box);
$self->facets(scalar @{$mesh->facets});
$self->vertices(scalar @{$mesh->vertices});
$self->materials($self->model_object->materials_count);
}
}
@ -1140,8 +1137,7 @@ sub instances_count {
sub make_thumbnail {
my $self = shift;
my $mesh = $self->model_object->mesh;
$mesh->align_to_origin;
my $mesh = $self->model_object->mesh; # $self->model_object is already aligned to origin
my $thumbnail = Slic3r::ExPolygon::Collection->new(
expolygons => (@{$mesh->facets} <= 5000)
? $mesh->horizontal_projection

View File

@ -119,6 +119,7 @@ sub arrange_objects {
$object->add_instance(
offset => $_,
rotation => $instance->rotation,
scaling_factor => $instance->scaling_factor,
) for move_points($instance->offset, @positions);
}
}
@ -213,6 +214,7 @@ sub mesh {
my $mesh = $object->mesh->clone;
if ($instance) {
$mesh->rotate($instance->rotation);
$mesh->scale($instance->scaling_factor);
$mesh->align_to_origin;
$mesh->move(@{$instance->offset});
}
@ -259,6 +261,7 @@ sub split_meshes {
$new_object->add_instance(
offset => [ $_->offset->[X] + $extents[X][MIN], $_->offset->[Y] + $extents[Y][MIN] ],
rotation => $_->rotation,
scaling_factor => $_->scaling_factor,
) for @{ $object->instances // [] };
}
}
@ -274,7 +277,7 @@ package Slic3r::Model::Object;
use Moo;
use List::Util qw(first);
use Slic3r::Geometry qw(X Y Z MIN move_points move_points_3D);
use Slic3r::Geometry qw(X Y Z MIN MAX move_points move_points_3D);
use Storable qw(dclone);
has 'input_file' => (is => 'rw');
@ -338,13 +341,27 @@ sub extents {
return Slic3r::Geometry::bounding_box_3D($self->used_vertices);
}
sub center {
my $self = shift;
my @extents = $self->extents;
return [ map +($extents[$_][MAX] + $extents[$_][MIN])/2, X,Y,Z ];
}
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::BoundingBox->new(extents => [ $self->extents ]);
}
sub align_to_origin {
my $self = shift;
# calculate the displacements needed to
# have lowest value for each axis at coordinate 0
my @extents = $self->extents;
$self->move(map -$extents[$_][MIN], X,Y,Z);
my @shift = map -$extents[$_][MIN], X,Y,Z;
$self->move(@shift);
return @shift;
}
sub move {
@ -410,6 +427,7 @@ use Moo;
has 'object' => (is => 'ro', weak_ref => 1, required => 1);
has 'rotation' => (is => 'rw', default => sub { 0 }); # around mesh center point
has 'scaling_factor' => (is => 'rw', default => sub { 1 });
has 'offset' => (is => 'rw'); # must be Slic3r::Point object
1;

View File

@ -106,6 +106,8 @@ sub add_model {
$model->split_meshes if $Slic3r::Config->avoid_crossing_perimeters && !$Slic3r::Config->complete_objects;
foreach my $object (@{ $model->objects }) {
my @align = $object->align_to_origin;
# extract meshes by material
my @meshes = (); # by region_id
foreach my $volume (@{$object->volumes}) {
@ -123,21 +125,18 @@ sub add_model {
# the order of these transformations must be the same as the one used in plater
# to make the object positioning consistent with the visual preview
# we ignore the per-instance rotation currently and only
# we ignore the per-instance transformations currently and only
# consider the first one
$mesh->rotate($object->instances->[0]->rotation, $mesh->center)
if @{ $object->instances // [] };
if ($object->instances && @{$object->instances}) {
$mesh->rotate($object->instances->[0]->rotation, $object->center);
$mesh->scale($object->instances->[0]->scaling_factor);
}
$mesh->scale(1 / &Slic3r::SCALING_FACTOR);
}
# align the object to origin; not sure this is required by the toolpath generation
# algorithms, but it's good practice to avoid negative coordinates; it probably
# provides also some better performance in infill generation
my @extents = Slic3r::Geometry::bounding_box_3D([ map @{$_->used_vertices}, grep $_, @meshes ]);
foreach my $mesh (grep $_, @meshes) {
$mesh->move(map -$extents[$_][MIN], X,Y,Z);
}
# calculate transformed size
my $size = [ Slic3r::Geometry::size_3D([ map @{$_->used_vertices}, grep $_, @meshes ]) ];
# initialize print object
push @{$self->objects}, Slic3r::Print::Object->new(
@ -145,10 +144,10 @@ sub add_model {
meshes => [ @meshes ],
copies => [
$object->instances
? (map [ (scale $_->offset->[X]) + $extents[X][MIN], (scale $_->offset->[Y]) + $extents[Y][MIN] ], @{$object->instances})
? (map [ scale($_->offset->[X] - $align[X]), scale($_->offset->[Y] - $align[Y]) ], @{$object->instances})
: [0,0],
],
size => [ map $extents[$_][MAX] - $extents[$_][MIN], (X,Y,Z) ],
size => $size,
input_file => $object->input_file,
layer_height_ranges => $object->layer_height_ranges,
);