From 9a4e8f39af4c1f71295751c8f2bf8c9e7e96762e Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 12 Nov 2014 22:36:03 +0100 Subject: [PATCH] Refactoring: move split logic in a single place (ModelObject class) --- lib/Slic3r/GUI/Plater.pm | 45 +++++------------------ lib/Slic3r/Model.pm | 79 ++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 75 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 836b3f69b..a6944d318 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -751,49 +751,24 @@ sub split_object { my $current_model_object = $self->{model}->objects->[$obj_idx]; if (@{$current_model_object->volumes} > 1) { - Slic3r::GUI::warning_catcher($self)->("The selected object couldn't be split because it contains more than one volume/material."); - return; - } - - my @new_meshes = @{$current_model_object->volumes->[0]->mesh->split}; - if (@new_meshes == 1) { - Slic3r::GUI::warning_catcher($self)->("The selected object couldn't be split because it already contains a single part."); + Slic3r::GUI::warning_catcher($self)->("The selected object can't be split because it contains more than one volume/material."); return; } $self->stop_background_process; - # create a bogus Model object, we only need to instantiate the new Model::Object objects - my $new_model = Slic3r::Model->new; + my @model_objects = @{$current_model_object->split_object}; + if (@model_objects == 1) { + Slic3r::GUI::warning_catcher($self)->("The selected object couldn't be split because it already contains a single part."); + return; + } - my @model_objects = (); - foreach my $mesh (@new_meshes) { - $mesh->repair; + foreach my $object (@model_objects) { + $object->instances->[$_]->offset->translate($_ * 10, $_ * 10) + for 1..$#{ $object->instances }; - my $model_object = $new_model->add_object( - input_file => $current_model_object->input_file, - config => $current_model_object->config->clone, - layer_height_ranges => $current_model_object->layer_height_ranges, # TODO: clone this - ); - $model_object->add_volume( - mesh => $mesh, - material_id => $current_model_object->volumes->[0]->material_id, - ); - - for my $instance_idx (0..$#{ $current_model_object->instances }) { - my $current_instance = $current_model_object->instances->[$instance_idx]; - $model_object->add_instance( - offset => Slic3r::Pointf->new( - $current_instance->offset->[X] + ($instance_idx * 10), - $current_instance->offset->[Y] + ($instance_idx * 10), - ), - rotation => $current_instance->rotation, - scaling_factor => $current_instance->scaling_factor, - ); - } # we need to center this single object around origin - $model_object->center_around_origin; - push @model_objects, $model_object; + $object->center_around_origin; } # remove the original object before spawning the object_loaded event, otherwise diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 1216a724c..1949a83a0 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -158,46 +158,6 @@ sub _arrange { ); } -# this method splits objects into multiple distinct objects by walking their meshes -sub split_meshes { - my $self = shift; - - my @objects = @{$self->objects}; - @{$self->objects} = (); - - foreach my $object (@objects) { - if (@{$object->volumes} > 1) { - # We can't split meshes if there's more than one material, because - # we can't group the resulting meshes by object afterwards - $self->_add_object($object); - next; - } - - my $volume = $object->volumes->[0]; - foreach my $mesh (@{$volume->mesh->split}) { - my $new_object = $self->add_object( - input_file => $object->input_file, - config => $object->config->clone, - layer_height_ranges => $object->layer_height_ranges, # TODO: this needs to be cloned - origin_translation => $object->origin_translation, - ); - $new_object->add_volume( - mesh => $mesh, - name => $volume->name, - material_id => $volume->material_id, - config => $volume->config, - ); - - # add one instance per original instance - $new_object->add_instance( - offset => Slic3r::Pointf->new(@{$_->offset}), - rotation => $_->rotation, - scaling_factor => $_->scaling_factor, - ) for @{ $object->instances // [] }; - } - } -} - sub print_info { my $self = shift; $_->print_info for @{$self->objects}; @@ -299,6 +259,45 @@ sub add_instance { } } +sub split_object { + my ($self) = @_; + + if (@{$self->volumes} > 1) { + # We can't split meshes if there's more than one volume, because + # we can't group the resulting meshes by object afterwards + my $o = $self->model->_add_object($self); + return [$o]; + } + + my @new_objects = (); + my $volume = $self->volumes->[0]; + foreach my $mesh (@{$volume->mesh->split}) { + $mesh->repair; + + push @new_objects, my $new_object = $self->model->add_object( + input_file => $self->input_file, + config => $self->config->clone, + layer_height_ranges => $self->layer_height_ranges, # TODO: this needs to be cloned + origin_translation => $self->origin_translation, + ); + $new_object->add_volume( + mesh => $mesh, + name => $volume->name, + material_id => $volume->material_id, + config => $volume->config, + ); + + # add one instance per original instance + $new_object->add_instance( + offset => Slic3r::Pointf->new(@{$_->offset}), + rotation => $_->rotation, + scaling_factor => $_->scaling_factor, + ) for @{ $self->instances }; + } + + return [@new_objects]; +} + sub rotate { my ($self, $angle, $axis) = @_;