Skip to content

Commit

Permalink
Refactoring to Model API for making it stricter and safer
Browse files Browse the repository at this point in the history
  • Loading branch information
alranel committed May 9, 2014
1 parent bc023c2 commit 7ba08c9
Showing 17 changed files with 314 additions and 315 deletions.
2 changes: 1 addition & 1 deletion lib/Slic3r/Format/AMF/Parser.pm
Original file line number Diff line number Diff line change
@@ -126,7 +126,7 @@ sub end_document {
foreach my $instance (@{ $self->{_instances}{$object_id} }) {
$self->{_model}->objects->[$new_object_id]->add_instance(
rotation => $instance->{rz} || 0,
offset => [ $instance->{deltax} || 0, $instance->{deltay} || 0 ],
offset => Slic3r::Pointf->new($instance->{deltax} || 0, $instance->{deltay} || 0),
);
}
}
8 changes: 4 additions & 4 deletions lib/Slic3r/GUI/Plater.pm
Original file line number Diff line number Diff line change
@@ -409,7 +409,7 @@ sub load_model_objects {

# add a default instance and center object around origin
$o->center_around_origin;
$o->add_instance(offset => [ @{$self->{config}->print_center} ]);
$o->add_instance(offset => Slic3r::Pointf->new(@{$self->{config}->print_center}));
}

$self->{print}->auto_assign_extruders($o);
@@ -487,7 +487,7 @@ sub increase {
my $model_object = $self->{model}->objects->[$obj_idx];
my $last_instance = $model_object->instances->[-1];
my $i = $model_object->add_instance(
offset => [ map 10+$_, @{$last_instance->offset} ],
offset => Slic3r::Pointf->new(map 10+$_, @{$last_instance->offset}),
scaling_factor => $last_instance->scaling_factor,
rotation => $last_instance->rotation,
);
@@ -654,10 +654,10 @@ sub split_object {
for my $instance_idx (0..$#{ $current_model_object->instances }) {
my $current_instance = $current_model_object->instances->[$instance_idx];
$model_object->add_instance(
offset => [
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,
);
142 changes: 64 additions & 78 deletions lib/Slic3r/Model.pm
Original file line number Diff line number Diff line change
@@ -31,48 +31,34 @@ sub merge {
sub add_object {
my $self = shift;

my $new_object;
if (@_ == 1) {
# we have a Model::Object
my ($object) = @_;

$new_object = $self->add_object(
input_file => $object->input_file,
config => $object->config,
layer_height_ranges => $object->layer_height_ranges, # TODO: clone!
origin_translation => $object->origin_translation,
);

foreach my $volume (@{$object->volumes}) {
$new_object->add_volume($volume);
}

$new_object->add_instance(
offset => [ @{$_->offset} ],
rotation => $_->rotation,
scaling_factor => $_->scaling_factor,
) for @{ $object->instances // [] };
return $self->_add_object_clone($object);
} else {
my (%args) = @_;
$new_object = $self->_add_object(
$args{input_file},
$args{config} // Slic3r::Config->new,
$args{layer_height_ranges} // [],
$args{origin_translation} // Slic3r::Pointf->new,
);

my $new_object = $self->_add_object;

$new_object->set_input_file($args{input_file})
if defined $args{input_file};
$new_object->config->apply($args{config})
if defined $args{config};
$new_object->set_layer_height_ranges($args{layer_height_ranges})
if defined $args{layer_height_ranges};
$new_object->set_origin_translation($args{origin_translation})
if defined $args{origin_translation};

return $new_object;
}

return $new_object;
}

sub set_material {
my $self = shift;
my ($material_id, $attributes) = @_;

$attributes //= {};

my $material = $self->_set_material($material_id);
$material->set_attribute($_, $attributes->{$_}) for keys %$attributes;
my $material = $self->add_material($material_id);
$material->apply($attributes // {});
return $material;
}

@@ -89,10 +75,10 @@ sub duplicate_objects_grid {
for my $x_copy (1..$grid->[X]) {
for my $y_copy (1..$grid->[Y]) {
$object->add_instance(
offset => [
offset => Slic3r::Pointf->new(
($size->[X] + $distance) * ($x_copy-1),
($size->[Y] + $distance) * ($y_copy-1),
],
),
);
}
}
@@ -106,12 +92,7 @@ sub duplicate_objects {
foreach my $object (@{$self->objects}) {
my @instances = @{$object->instances};
foreach my $instance (@instances) {
### $object->add_instance($instance->clone); if we had clone()
$object->add_instance(
offset => [ @{$instance->offset} ],
rotation => $instance->rotation,
scaling_factor => $instance->scaling_factor,
) for 2..$copies_num;
$object->add_instance($instance) for 2..$copies_num;
}
}

@@ -151,9 +132,8 @@ sub duplicate {
my @instances = @{$object->instances}; # store separately to avoid recursion from add_instance() below
foreach my $instance (@instances) {
foreach my $pos (@positions) {
### $object->add_instance($instance->clone); if we had clone()
$object->add_instance(
offset => [ $instance->offset->[X] + $pos->[X], $instance->offset->[Y] + $pos->[Y] ],
offset => Slic3r::Pointf->new($instance->offset->[X] + $pos->[X], $instance->offset->[Y] + $pos->[Y]),
rotation => $instance->rotation,
scaling_factor => $instance->scaling_factor,
);
@@ -187,8 +167,8 @@ sub add_default_instances {
# apply a default position to all objects not having one
my $added = 0;
foreach my $object (@{$self->objects}) {
if (!defined $object->instances) {
$object->add_instance(offset => [0,0]);
if ($object->instances_count == 0) {
$object->add_instance(offset => Slic3r::Pointf->new(0,0));
$added = 1;
}
}
@@ -286,7 +266,7 @@ sub split_meshes {

# add one instance per original instance
$new_object->add_instance(
offset => [ @{$_->offset} ],
offset => Slic3r::Pointf->new(@{$_->offset}),
rotation => $_->rotation,
scaling_factor => $_->scaling_factor,
) for @{ $object->instances // [] };
@@ -314,6 +294,11 @@ sub get_material_name {

package Slic3r::Model::Material;

sub apply {
my ($self, $attributes) = @_;
$self->set_attribute($_, $attributes{$_}) for keys %$attributes;
}

package Slic3r::Model::Object;

use File::Basename qw(basename);
@@ -328,8 +313,7 @@ sub add_volume {
# we have a Model::Volume
my ($volume) = @_;

$new_volume = $self->_add_volume(
$volume->material_id, $volume->mesh->clone, $volume->modifier);
$new_volume = $self->_add_volume_clone($volume);

# TODO: material_id can't be undef.
if (defined $volume->material_id) {
@@ -345,35 +329,47 @@ sub add_volume {
}
} else {
my %args = @_;
$new_volume = $self->_add_volume(
$args{material_id},
$args{mesh},
$args{modifier} // 0);

$new_volume = $self->_add_volume($args{mesh});

$new_volume->set_material_id($args{material_id})
if defined $args{material_id};
$new_volume->set_modifier($args{modifier})
if defined $args{modifier};
}

if (defined $new_volume->material_id && !defined $self->model->get_material($new_volume->material_id)) {
# TODO: this should be a trigger on Volume::material_id
$self->model->set_material($new_volume->material_id);
}

$self->invalidate_bounding_box();
$self->invalidate_bounding_box;

return $new_volume;
}

sub add_instance {
my $self = shift;
my %params = @_;

return $self->_add_instance(
$params{rotation} // 0,
$params{scaling_factor} // 1,
$params{offset} // []);
}

sub instances_count {
my $self = shift;
return scalar(@{ $self->instances // [] });

if (@_ == 1) {
# we have a Model::Instance
my ($instance) = @_;
return $self->_add_instance_clone($instance);
} else {
my (%args) = @_;

my $new_instance = $self->_add_instance;

$new_instance->set_rotation($args{rotation})
if defined $args{rotation};
$new_instance->set_scaling_factor($args{scaling_factor})
if defined $args{scaling_factor};
$new_instance->set_offset($args{offset})
if defined $args{offset};

return $new_instance;
}
}

sub raw_mesh {
@@ -446,11 +442,12 @@ sub center_around_origin {
$self->translate(@shift);
$self->origin_translation->translate(@shift[X,Y]);

if (defined $self->instances) {
if ($self->instances_count > 0) {
foreach my $instance (@{ $self->instances }) {
$instance->set_offset(Slic3r::Pointf->new(
$instance->offset->x - $shift[X],
$instance->offset->y - $shift[Y]));
$instance->offset->y - $shift[Y], #--
));
}
$self->update_bounding_box;
}
@@ -538,23 +535,12 @@ sub cut {
my ($self, $z) = @_;

# clone this one
my $upper = Slic3r::Model::Object->new(
$self->model,
$self->input_file,
$self->config, # config is cloned by new()
$self->layer_height_ranges,
$self->origin_translation,
);
my $lower = Slic3r::Model::Object->new(
$self->model,
$self->input_file,
$self->config, # config is cloned by new()
$self->layer_height_ranges,
$self->origin_translation,
);
my $upper = $self->model->add_object($self);
my $lower = $self->model->add_object($self);

foreach my $instance (@{$self->instances}) {
$upper->add_instance(offset => [ @{$instance->offset} ]);
$lower->add_instance(offset => [ @{$instance->offset} ]);
$upper->add_instance(offset => Slic3r::Pointf->new(@{$instance->offset}));
$lower->add_instance(offset => Slic3r::Pointf->new(@{$instance->offset}));
}

foreach my $volume (@{$self->volumes}) {
23 changes: 18 additions & 5 deletions lib/Slic3r/Test.pm
Original file line number Diff line number Diff line change
@@ -124,9 +124,9 @@ sub model {
$model->set_material($model_name);
$object->add_volume(mesh => mesh($model_name, %params), material_id => $model_name);
$object->add_instance(
offset => [0,0],
rotation => $params{rotation} // 0,
scaling_factor => $params{scale} // 1,
offset => Slic3r::Pointf->new(0,0),
rotation => $params{rotation} // 0,
scaling_factor => $params{scale} // 1,
);
return $model;
}
@@ -142,7 +142,8 @@ sub init_print {
$print->apply_config($config);

$models = [$models] if ref($models) ne 'ARRAY';
for my $model (map { ref($_) ? $_ : model($_, %params) } @$models) {
$models = [ map { ref($_) ? $_ : model($_, %params) } @$models ];
for my $model (@$models) {
die "Unknown model in test" if !defined $model;
if (defined $params{duplicate} && $params{duplicate} > 1) {
$model->duplicate($params{duplicate} // 1, $print->config->min_object_distance);
@@ -156,12 +157,18 @@ sub init_print {
}
$print->validate;

return $print;
# We return a proxy object in order to keep $models alive as required by the Print API.
return Slic3r::Test::Print->new(
print => $print,
models => $models,
);
}

sub gcode {
my ($print) = @_;

$print = $print->print if $print->isa('Slic3r::Test::Print');

my $fh = IO::Scalar->new(\my $gcode);
$print->process;
$print->export_gcode(output_fh => $fh, quiet => 1);
@@ -189,4 +196,10 @@ sub add_facet {
}
}

package Slic3r::Test::Print;
use Moo;

has 'print' => (is => 'ro', required => 1);
has 'models' => (is => 'ro', required => 1);

1;
2 changes: 1 addition & 1 deletion t/custom_gcode.t
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ use Slic3r::Test;
$config->set('start_gcode', "TRAVEL:[travel_speed] HEIGHT:[layer_height]\n");
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);

my $output_file = $print->expanded_output_filepath;
my $output_file = $print->print->expanded_output_filepath;
ok $output_file !~ /\[travel_speed\]/, 'print config options are replaced in output filename';
ok $output_file !~ /\[layer_height\]/, 'region config options are replaced in output filename';

2 changes: 1 addition & 1 deletion t/gcode.t
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ use Slic3r::Test;


});
ok $print->total_used_filament > 0, 'final retraction is not considered in total used filament';
ok $print->print->total_used_filament > 0, 'final retraction is not considered in total used filament';
}

{
2 changes: 1 addition & 1 deletion t/multi.t
Original file line number Diff line number Diff line change
@@ -173,7 +173,7 @@ sub stacked_cubes {
my $object = $model->add_object;
$object->add_volume(mesh => Slic3r::Test::mesh('20mm_cube'), material_id => 'lower');
$object->add_volume(mesh => Slic3r::Test::mesh('20mm_cube', translate => [0,0,20]), material_id => 'upper');
$object->add_instance(offset => [0,0]);
$object->add_instance(offset => Slic3r::Pointf->new(0,0));

return $model;
}
4 changes: 2 additions & 2 deletions t/perimeters.t
Original file line number Diff line number Diff line change
@@ -192,11 +192,11 @@ use Slic3r::Test;

# we just need a pre-filled Print object
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
$print->init_extruders;
$print->print->init_extruders;

# override a layer's slices
my $expolygon = Slic3r::ExPolygon->new([[-71974463,-139999376],[-71731792,-139987456],[-71706544,-139985616],[-71682119,-139982639],[-71441248,-139946912],[-71417487,-139942895],[-71379384,-139933984],[-71141800,-139874480],[-71105247,-139862895],[-70873544,-139779984],[-70838592,-139765856],[-70614943,-139660064],[-70581783,-139643567],[-70368368,-139515680],[-70323751,-139487872],[-70122160,-139338352],[-70082399,-139306639],[-69894800,-139136624],[-69878679,-139121327],[-69707992,-138933008],[-69668575,-138887343],[-69518775,-138685359],[-69484336,-138631632],[-69356423,-138418207],[-69250040,-138193296],[-69220920,-138128976],[-69137992,-137897168],[-69126095,-137860255],[-69066568,-137622608],[-69057104,-137582511],[-69053079,-137558751],[-69017352,-137317872],[-69014392,-137293456],[-69012543,-137268207],[-68999369,-137000000],[-63999999,-137000000],[-63705947,-136985551],[-63654984,-136977984],[-63414731,-136942351],[-63364756,-136929840],[-63129151,-136870815],[-62851950,-136771631],[-62585807,-136645743],[-62377483,-136520895],[-62333291,-136494415],[-62291908,-136463728],[-62096819,-136319023],[-62058644,-136284432],[-61878676,-136121328],[-61680968,-135903184],[-61650275,-135861807],[-61505591,-135666719],[-61354239,-135414191],[-61332211,-135367615],[-61228359,-135148063],[-61129179,-134870847],[-61057639,-134585262],[-61014451,-134294047],[-61000000,-134000000],[-61000000,-107999999],[-61014451,-107705944],[-61057639,-107414736],[-61129179,-107129152],[-61228359,-106851953],[-61354239,-106585808],[-61505591,-106333288],[-61680967,-106096816],[-61878675,-105878680],[-62096820,-105680967],[-62138204,-105650279],[-62333292,-105505591],[-62585808,-105354239],[-62632384,-105332207],[-62851951,-105228360],[-62900463,-105211008],[-63129152,-105129183],[-63414731,-105057640],[-63705947,-105014448],[-63999999,-105000000],[-68999369,-105000000],[-69012543,-104731792],[-69014392,-104706544],[-69017352,-104682119],[-69053079,-104441248],[-69057104,-104417487],[-69066008,-104379383],[-69125528,-104141799],[-69137111,-104105248],[-69220007,-103873544],[-69234136,-103838591],[-69339920,-103614943],[-69356415,-103581784],[-69484328,-103368367],[-69512143,-103323752],[-69661647,-103122160],[-69693352,-103082399],[-69863383,-102894800],[-69878680,-102878679],[-70066999,-102707992],[-70112656,-102668576],[-70314648,-102518775],[-70368367,-102484336],[-70581783,-102356424],[-70806711,-102250040],[-70871040,-102220919],[-71102823,-102137992],[-71139752,-102126095],[-71377383,-102066568],[-71417487,-102057104],[-71441248,-102053079],[-71682119,-102017352],[-71706535,-102014392],[-71731784,-102012543],[-71974456,-102000624],[-71999999,-102000000],[-104000000,-102000000],[-104025536,-102000624],[-104268207,-102012543],[-104293455,-102014392],[-104317880,-102017352],[-104558751,-102053079],[-104582512,-102057104],[-104620616,-102066008],[-104858200,-102125528],[-104894751,-102137111],[-105126455,-102220007],[-105161408,-102234136],[-105385056,-102339920],[-105418215,-102356415],[-105631632,-102484328],[-105676247,-102512143],[-105877839,-102661647],[-105917600,-102693352],[-106105199,-102863383],[-106121320,-102878680],[-106292007,-103066999],[-106331424,-103112656],[-106481224,-103314648],[-106515663,-103368367],[-106643575,-103581783],[-106749959,-103806711],[-106779080,-103871040],[-106862007,-104102823],[-106873904,-104139752],[-106933431,-104377383],[-106942896,-104417487],[-106946920,-104441248],[-106982648,-104682119],[-106985607,-104706535],[-106987456,-104731784],[-107000630,-105000000],[-112000000,-105000000],[-112294056,-105014448],[-112585264,-105057640],[-112870848,-105129184],[-112919359,-105146535],[-113148048,-105228360],[-113194624,-105250392],[-113414191,-105354239],[-113666711,-105505591],[-113708095,-105536279],[-113903183,-105680967],[-114121320,-105878679],[-114319032,-106096816],[-114349720,-106138200],[-114494408,-106333288],[-114645760,-106585808],[-114667792,-106632384],[-114771640,-106851952],[-114788991,-106900463],[-114870815,-107129151],[-114942359,-107414735],[-114985551,-107705943],[-115000000,-107999999],[-115000000,-134000000],[-114985551,-134294048],[-114942359,-134585263],[-114870816,-134870847],[-114853464,-134919359],[-114771639,-135148064],[-114645759,-135414192],[-114494407,-135666720],[-114319031,-135903184],[-114121320,-136121327],[-114083144,-136155919],[-113903184,-136319023],[-113861799,-136349712],[-113666711,-136494416],[-113458383,-136619264],[-113414192,-136645743],[-113148049,-136771631],[-112870848,-136870815],[-112820872,-136883327],[-112585264,-136942351],[-112534303,-136949920],[-112294056,-136985551],[-112000000,-137000000],[-107000630,-137000000],[-106987456,-137268207],[-106985608,-137293440],[-106982647,-137317872],[-106946920,-137558751],[-106942896,-137582511],[-106933991,-137620624],[-106874471,-137858208],[-106862888,-137894751],[-106779992,-138126463],[-106765863,-138161424],[-106660080,-138385055],[-106643584,-138418223],[-106515671,-138631648],[-106487855,-138676256],[-106338352,-138877839],[-106306647,-138917600],[-106136616,-139105199],[-106121320,-139121328],[-105933000,-139291999],[-105887344,-139331407],[-105685351,-139481232],[-105631632,-139515663],[-105418216,-139643567],[-105193288,-139749951],[-105128959,-139779072],[-104897175,-139862016],[-104860247,-139873904],[-104622616,-139933423],[-104582511,-139942896],[-104558751,-139946912],[-104317880,-139982656],[-104293463,-139985616],[-104268216,-139987456],[-104025544,-139999376],[-104000000,-140000000],[-71999999,-140000000]],[[-105000000,-138000000],[-105000000,-104000000],[-71000000,-104000000],[-71000000,-138000000]],[[-69000000,-132000000],[-69000000,-110000000],[-64991180,-110000000],[-64991180,-132000000]],[[-111008824,-132000000],[-111008824,-110000000],[-107000000,-110000000],[-107000000,-132000000]]);
my $object = $print->objects->[0];
my $object = $print->print->objects->[0];
$object->slice;
my $layer = $object->layers->[1];
my $layerm = $layer->regions->[0];
Loading

0 comments on commit 7ba08c9

Please sign in to comment.