Refactoring to Model API for making it stricter and safer
This commit is contained in:
parent
bc023c2d51
commit
7ba08c90cf
@ -126,7 +126,7 @@ sub end_document {
|
|||||||
foreach my $instance (@{ $self->{_instances}{$object_id} }) {
|
foreach my $instance (@{ $self->{_instances}{$object_id} }) {
|
||||||
$self->{_model}->objects->[$new_object_id]->add_instance(
|
$self->{_model}->objects->[$new_object_id]->add_instance(
|
||||||
rotation => $instance->{rz} || 0,
|
rotation => $instance->{rz} || 0,
|
||||||
offset => [ $instance->{deltax} || 0, $instance->{deltay} || 0 ],
|
offset => Slic3r::Pointf->new($instance->{deltax} || 0, $instance->{deltay} || 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ sub load_model_objects {
|
|||||||
|
|
||||||
# add a default instance and center object around origin
|
# add a default instance and center object around origin
|
||||||
$o->center_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);
|
$self->{print}->auto_assign_extruders($o);
|
||||||
@ -487,7 +487,7 @@ sub increase {
|
|||||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||||
my $last_instance = $model_object->instances->[-1];
|
my $last_instance = $model_object->instances->[-1];
|
||||||
my $i = $model_object->add_instance(
|
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,
|
scaling_factor => $last_instance->scaling_factor,
|
||||||
rotation => $last_instance->rotation,
|
rotation => $last_instance->rotation,
|
||||||
);
|
);
|
||||||
@ -654,10 +654,10 @@ sub split_object {
|
|||||||
for my $instance_idx (0..$#{ $current_model_object->instances }) {
|
for my $instance_idx (0..$#{ $current_model_object->instances }) {
|
||||||
my $current_instance = $current_model_object->instances->[$instance_idx];
|
my $current_instance = $current_model_object->instances->[$instance_idx];
|
||||||
$model_object->add_instance(
|
$model_object->add_instance(
|
||||||
offset => [
|
offset => Slic3r::Pointf->new(
|
||||||
$current_instance->offset->[X] + ($instance_idx * 10),
|
$current_instance->offset->[X] + ($instance_idx * 10),
|
||||||
$current_instance->offset->[Y] + ($instance_idx * 10),
|
$current_instance->offset->[Y] + ($instance_idx * 10),
|
||||||
],
|
),
|
||||||
rotation => $current_instance->rotation,
|
rotation => $current_instance->rotation,
|
||||||
scaling_factor => $current_instance->scaling_factor,
|
scaling_factor => $current_instance->scaling_factor,
|
||||||
);
|
);
|
||||||
|
@ -31,48 +31,34 @@ sub merge {
|
|||||||
sub add_object {
|
sub add_object {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my $new_object;
|
|
||||||
if (@_ == 1) {
|
if (@_ == 1) {
|
||||||
# we have a Model::Object
|
# we have a Model::Object
|
||||||
my ($object) = @_;
|
my ($object) = @_;
|
||||||
|
return $self->_add_object_clone($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 // [] };
|
|
||||||
} else {
|
} else {
|
||||||
my (%args) = @_;
|
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $new_object;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub set_material {
|
sub set_material {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($material_id, $attributes) = @_;
|
my ($material_id, $attributes) = @_;
|
||||||
|
|
||||||
$attributes //= {};
|
my $material = $self->add_material($material_id);
|
||||||
|
$material->apply($attributes // {});
|
||||||
my $material = $self->_set_material($material_id);
|
|
||||||
$material->set_attribute($_, $attributes->{$_}) for keys %$attributes;
|
|
||||||
return $material;
|
return $material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,10 +75,10 @@ sub duplicate_objects_grid {
|
|||||||
for my $x_copy (1..$grid->[X]) {
|
for my $x_copy (1..$grid->[X]) {
|
||||||
for my $y_copy (1..$grid->[Y]) {
|
for my $y_copy (1..$grid->[Y]) {
|
||||||
$object->add_instance(
|
$object->add_instance(
|
||||||
offset => [
|
offset => Slic3r::Pointf->new(
|
||||||
($size->[X] + $distance) * ($x_copy-1),
|
($size->[X] + $distance) * ($x_copy-1),
|
||||||
($size->[Y] + $distance) * ($y_copy-1),
|
($size->[Y] + $distance) * ($y_copy-1),
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,12 +92,7 @@ sub duplicate_objects {
|
|||||||
foreach my $object (@{$self->objects}) {
|
foreach my $object (@{$self->objects}) {
|
||||||
my @instances = @{$object->instances};
|
my @instances = @{$object->instances};
|
||||||
foreach my $instance (@instances) {
|
foreach my $instance (@instances) {
|
||||||
### $object->add_instance($instance->clone); if we had clone()
|
$object->add_instance($instance) for 2..$copies_num;
|
||||||
$object->add_instance(
|
|
||||||
offset => [ @{$instance->offset} ],
|
|
||||||
rotation => $instance->rotation,
|
|
||||||
scaling_factor => $instance->scaling_factor,
|
|
||||||
) for 2..$copies_num;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,9 +132,8 @@ sub duplicate {
|
|||||||
my @instances = @{$object->instances}; # store separately to avoid recursion from add_instance() below
|
my @instances = @{$object->instances}; # store separately to avoid recursion from add_instance() below
|
||||||
foreach my $instance (@instances) {
|
foreach my $instance (@instances) {
|
||||||
foreach my $pos (@positions) {
|
foreach my $pos (@positions) {
|
||||||
### $object->add_instance($instance->clone); if we had clone()
|
|
||||||
$object->add_instance(
|
$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,
|
rotation => $instance->rotation,
|
||||||
scaling_factor => $instance->scaling_factor,
|
scaling_factor => $instance->scaling_factor,
|
||||||
);
|
);
|
||||||
@ -187,8 +167,8 @@ sub add_default_instances {
|
|||||||
# apply a default position to all objects not having one
|
# apply a default position to all objects not having one
|
||||||
my $added = 0;
|
my $added = 0;
|
||||||
foreach my $object (@{$self->objects}) {
|
foreach my $object (@{$self->objects}) {
|
||||||
if (!defined $object->instances) {
|
if ($object->instances_count == 0) {
|
||||||
$object->add_instance(offset => [0,0]);
|
$object->add_instance(offset => Slic3r::Pointf->new(0,0));
|
||||||
$added = 1;
|
$added = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +266,7 @@ sub split_meshes {
|
|||||||
|
|
||||||
# add one instance per original instance
|
# add one instance per original instance
|
||||||
$new_object->add_instance(
|
$new_object->add_instance(
|
||||||
offset => [ @{$_->offset} ],
|
offset => Slic3r::Pointf->new(@{$_->offset}),
|
||||||
rotation => $_->rotation,
|
rotation => $_->rotation,
|
||||||
scaling_factor => $_->scaling_factor,
|
scaling_factor => $_->scaling_factor,
|
||||||
) for @{ $object->instances // [] };
|
) for @{ $object->instances // [] };
|
||||||
@ -314,6 +294,11 @@ sub get_material_name {
|
|||||||
|
|
||||||
package Slic3r::Model::Material;
|
package Slic3r::Model::Material;
|
||||||
|
|
||||||
|
sub apply {
|
||||||
|
my ($self, $attributes) = @_;
|
||||||
|
$self->set_attribute($_, $attributes{$_}) for keys %$attributes;
|
||||||
|
}
|
||||||
|
|
||||||
package Slic3r::Model::Object;
|
package Slic3r::Model::Object;
|
||||||
|
|
||||||
use File::Basename qw(basename);
|
use File::Basename qw(basename);
|
||||||
@ -328,8 +313,7 @@ sub add_volume {
|
|||||||
# we have a Model::Volume
|
# we have a Model::Volume
|
||||||
my ($volume) = @_;
|
my ($volume) = @_;
|
||||||
|
|
||||||
$new_volume = $self->_add_volume(
|
$new_volume = $self->_add_volume_clone($volume);
|
||||||
$volume->material_id, $volume->mesh->clone, $volume->modifier);
|
|
||||||
|
|
||||||
# TODO: material_id can't be undef.
|
# TODO: material_id can't be undef.
|
||||||
if (defined $volume->material_id) {
|
if (defined $volume->material_id) {
|
||||||
@ -345,10 +329,13 @@ sub add_volume {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
my %args = @_;
|
my %args = @_;
|
||||||
$new_volume = $self->_add_volume(
|
|
||||||
$args{material_id},
|
$new_volume = $self->_add_volume($args{mesh});
|
||||||
$args{mesh},
|
|
||||||
$args{modifier} // 0);
|
$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)) {
|
if (defined $new_volume->material_id && !defined $self->model->get_material($new_volume->material_id)) {
|
||||||
@ -356,7 +343,7 @@ sub add_volume {
|
|||||||
$self->model->set_material($new_volume->material_id);
|
$self->model->set_material($new_volume->material_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->invalidate_bounding_box();
|
$self->invalidate_bounding_box;
|
||||||
|
|
||||||
return $new_volume;
|
return $new_volume;
|
||||||
}
|
}
|
||||||
@ -365,15 +352,24 @@ sub add_instance {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
return $self->_add_instance(
|
if (@_ == 1) {
|
||||||
$params{rotation} // 0,
|
# we have a Model::Instance
|
||||||
$params{scaling_factor} // 1,
|
my ($instance) = @_;
|
||||||
$params{offset} // []);
|
return $self->_add_instance_clone($instance);
|
||||||
}
|
} else {
|
||||||
|
my (%args) = @_;
|
||||||
|
|
||||||
sub instances_count {
|
my $new_instance = $self->_add_instance;
|
||||||
my $self = shift;
|
|
||||||
return scalar(@{ $self->instances // [] });
|
$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 {
|
sub raw_mesh {
|
||||||
@ -446,11 +442,12 @@ sub center_around_origin {
|
|||||||
$self->translate(@shift);
|
$self->translate(@shift);
|
||||||
$self->origin_translation->translate(@shift[X,Y]);
|
$self->origin_translation->translate(@shift[X,Y]);
|
||||||
|
|
||||||
if (defined $self->instances) {
|
if ($self->instances_count > 0) {
|
||||||
foreach my $instance (@{ $self->instances }) {
|
foreach my $instance (@{ $self->instances }) {
|
||||||
$instance->set_offset(Slic3r::Pointf->new(
|
$instance->set_offset(Slic3r::Pointf->new(
|
||||||
$instance->offset->x - $shift[X],
|
$instance->offset->x - $shift[X],
|
||||||
$instance->offset->y - $shift[Y]));
|
$instance->offset->y - $shift[Y], #--
|
||||||
|
));
|
||||||
}
|
}
|
||||||
$self->update_bounding_box;
|
$self->update_bounding_box;
|
||||||
}
|
}
|
||||||
@ -538,23 +535,12 @@ sub cut {
|
|||||||
my ($self, $z) = @_;
|
my ($self, $z) = @_;
|
||||||
|
|
||||||
# clone this one
|
# clone this one
|
||||||
my $upper = Slic3r::Model::Object->new(
|
my $upper = $self->model->add_object($self);
|
||||||
$self->model,
|
my $lower = $self->model->add_object($self);
|
||||||
$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,
|
|
||||||
);
|
|
||||||
foreach my $instance (@{$self->instances}) {
|
foreach my $instance (@{$self->instances}) {
|
||||||
$upper->add_instance(offset => [ @{$instance->offset} ]);
|
$upper->add_instance(offset => Slic3r::Pointf->new(@{$instance->offset}));
|
||||||
$lower->add_instance(offset => [ @{$instance->offset} ]);
|
$lower->add_instance(offset => Slic3r::Pointf->new(@{$instance->offset}));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $volume (@{$self->volumes}) {
|
foreach my $volume (@{$self->volumes}) {
|
||||||
|
@ -124,9 +124,9 @@ sub model {
|
|||||||
$model->set_material($model_name);
|
$model->set_material($model_name);
|
||||||
$object->add_volume(mesh => mesh($model_name, %params), material_id => $model_name);
|
$object->add_volume(mesh => mesh($model_name, %params), material_id => $model_name);
|
||||||
$object->add_instance(
|
$object->add_instance(
|
||||||
offset => [0,0],
|
offset => Slic3r::Pointf->new(0,0),
|
||||||
rotation => $params{rotation} // 0,
|
rotation => $params{rotation} // 0,
|
||||||
scaling_factor => $params{scale} // 1,
|
scaling_factor => $params{scale} // 1,
|
||||||
);
|
);
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
@ -142,7 +142,8 @@ sub init_print {
|
|||||||
$print->apply_config($config);
|
$print->apply_config($config);
|
||||||
|
|
||||||
$models = [$models] if ref($models) ne 'ARRAY';
|
$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;
|
die "Unknown model in test" if !defined $model;
|
||||||
if (defined $params{duplicate} && $params{duplicate} > 1) {
|
if (defined $params{duplicate} && $params{duplicate} > 1) {
|
||||||
$model->duplicate($params{duplicate} // 1, $print->config->min_object_distance);
|
$model->duplicate($params{duplicate} // 1, $print->config->min_object_distance);
|
||||||
@ -156,12 +157,18 @@ sub init_print {
|
|||||||
}
|
}
|
||||||
$print->validate;
|
$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 {
|
sub gcode {
|
||||||
my ($print) = @_;
|
my ($print) = @_;
|
||||||
|
|
||||||
|
$print = $print->print if $print->isa('Slic3r::Test::Print');
|
||||||
|
|
||||||
my $fh = IO::Scalar->new(\my $gcode);
|
my $fh = IO::Scalar->new(\my $gcode);
|
||||||
$print->process;
|
$print->process;
|
||||||
$print->export_gcode(output_fh => $fh, quiet => 1);
|
$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;
|
1;
|
||||||
|
@ -57,7 +57,7 @@ use Slic3r::Test;
|
|||||||
$config->set('start_gcode', "TRAVEL:[travel_speed] HEIGHT:[layer_height]\n");
|
$config->set('start_gcode', "TRAVEL:[travel_speed] HEIGHT:[layer_height]\n");
|
||||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
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 !~ /\[travel_speed\]/, 'print config options are replaced in output filename';
|
||||||
ok $output_file !~ /\[layer_height\]/, 'region config options are replaced in output filename';
|
ok $output_file !~ /\[layer_height\]/, 'region config options are replaced in output filename';
|
||||||
|
|
||||||
|
@ -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';
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -173,7 +173,7 @@ sub stacked_cubes {
|
|||||||
my $object = $model->add_object;
|
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'), material_id => 'lower');
|
||||||
$object->add_volume(mesh => Slic3r::Test::mesh('20mm_cube', translate => [0,0,20]), material_id => 'upper');
|
$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;
|
return $model;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
18
t/print.t
18
t/print.t
@ -38,21 +38,21 @@ use Slic3r::Test;
|
|||||||
my $print = Slic3r::Test::init_print(my $model = Slic3r::Test::model('20mm_cube'), config => $config);
|
my $print = Slic3r::Test::init_print(my $model = Slic3r::Test::model('20mm_cube'), config => $config);
|
||||||
|
|
||||||
# user sets a per-region option
|
# user sets a per-region option
|
||||||
$print->objects->[0]->model_object->config->set('fill_density', 100);
|
$print->print->objects->[0]->model_object->config->set('fill_density', 100);
|
||||||
$print->reload_object(0);
|
$print->print->reload_object(0);
|
||||||
|
|
||||||
# user exports G-code, thus the default config is reapplied
|
# user exports G-code, thus the default config is reapplied
|
||||||
$print->apply_config($config);
|
$print->print->apply_config($config);
|
||||||
|
|
||||||
is $print->regions->[0]->config->fill_density, 100, 'apply_config() does not override per-object settings';
|
is $print->print->regions->[0]->config->fill_density, 100, 'apply_config() does not override per-object settings';
|
||||||
|
|
||||||
# user assigns object extruders
|
# user assigns object extruders
|
||||||
$print->objects->[0]->model_object->config->set('extruder', 3);
|
$print->print->objects->[0]->model_object->config->set('extruder', 3);
|
||||||
$print->objects->[0]->model_object->config->set('perimeter_extruder', 2);
|
$print->print->objects->[0]->model_object->config->set('perimeter_extruder', 2);
|
||||||
$print->reload_object(0);
|
$print->print->reload_object(0);
|
||||||
|
|
||||||
is $print->regions->[0]->config->infill_extruder, 3, 'extruder setting is correctly expanded';
|
is $print->print->regions->[0]->config->infill_extruder, 3, 'extruder setting is correctly expanded';
|
||||||
is $print->regions->[0]->config->perimeter_extruder, 2, 'extruder setting does not override explicitely specified extruders';
|
is $print->print->regions->[0]->config->perimeter_extruder, 2, 'extruder setting does not override explicitely specified extruders';
|
||||||
}
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
@ -42,8 +42,8 @@ use Slic3r::Test qw(_eq);
|
|||||||
|
|
||||||
if ($info->{dist_Z}) {
|
if ($info->{dist_Z}) {
|
||||||
# lift move or lift + change layer
|
# lift move or lift + change layer
|
||||||
if (_eq($info->{dist_Z}, $print->config->get_at('retract_lift', $tool))
|
if (_eq($info->{dist_Z}, $print->print->config->get_at('retract_lift', $tool))
|
||||||
|| (_eq($info->{dist_Z}, $conf->layer_height + $print->config->get_at('retract_lift', $tool)) && $print->config->get_at('retract_lift', $tool) > 0)) {
|
|| (_eq($info->{dist_Z}, $conf->layer_height + $print->print->config->get_at('retract_lift', $tool)) && $print->print->config->get_at('retract_lift', $tool) > 0)) {
|
||||||
fail 'only lifting while retracted' if !$retracted[$tool] && !($conf->g0 && $info->{retracting});
|
fail 'only lifting while retracted' if !$retracted[$tool] && !($conf->g0 && $info->{retracting});
|
||||||
fail 'double lift' if $lifted;
|
fail 'double lift' if $lifted;
|
||||||
$lifted = 1;
|
$lifted = 1;
|
||||||
@ -51,8 +51,8 @@ use Slic3r::Test qw(_eq);
|
|||||||
if ($info->{dist_Z} < 0) {
|
if ($info->{dist_Z} < 0) {
|
||||||
fail 'going down only after lifting' if !$lifted;
|
fail 'going down only after lifting' if !$lifted;
|
||||||
fail 'going down by the same amount of the lift or by the amount needed to get to next layer'
|
fail 'going down by the same amount of the lift or by the amount needed to get to next layer'
|
||||||
if !_eq($info->{dist_Z}, -$print->config->get_at('retract_lift', $tool))
|
if !_eq($info->{dist_Z}, -$print->print->config->get_at('retract_lift', $tool))
|
||||||
&& !_eq($info->{dist_Z}, -$print->config->get_at('retract_lift', $tool) + $conf->layer_height);
|
&& !_eq($info->{dist_Z}, -$print->print->config->get_at('retract_lift', $tool) + $conf->layer_height);
|
||||||
$lifted = 0;
|
$lifted = 0;
|
||||||
}
|
}
|
||||||
fail 'move Z at travel speed' if ($args->{F} // $self->F) != $conf->travel_speed * 60;
|
fail 'move Z at travel speed' if ($args->{F} // $self->F) != $conf->travel_speed * 60;
|
||||||
@ -60,9 +60,9 @@ use Slic3r::Test qw(_eq);
|
|||||||
if ($info->{retracting}) {
|
if ($info->{retracting}) {
|
||||||
$retracted[$tool] = 1;
|
$retracted[$tool] = 1;
|
||||||
$retracted_length[$tool] += -$info->{dist_E};
|
$retracted_length[$tool] += -$info->{dist_E};
|
||||||
if (_eq($retracted_length[$tool], $print->config->get_at('retract_length', $tool))) {
|
if (_eq($retracted_length[$tool], $print->print->config->get_at('retract_length', $tool))) {
|
||||||
# okay
|
# okay
|
||||||
} elsif (_eq($retracted_length[$tool], $print->config->get_at('retract_length_toolchange', $tool))) {
|
} elsif (_eq($retracted_length[$tool], $print->print->config->get_at('retract_length_toolchange', $tool))) {
|
||||||
$wait_for_toolchange = 1;
|
$wait_for_toolchange = 1;
|
||||||
} else {
|
} else {
|
||||||
fail 'retracted by the correct amount';
|
fail 'retracted by the correct amount';
|
||||||
@ -73,9 +73,9 @@ use Slic3r::Test qw(_eq);
|
|||||||
if ($info->{extruding}) {
|
if ($info->{extruding}) {
|
||||||
fail 'only extruding while not lifted' if $lifted;
|
fail 'only extruding while not lifted' if $lifted;
|
||||||
if ($retracted[$tool]) {
|
if ($retracted[$tool]) {
|
||||||
my $expected_amount = $retracted_length[$tool] + $print->config->get_at('retract_restart_extra', $tool);
|
my $expected_amount = $retracted_length[$tool] + $print->print->config->get_at('retract_restart_extra', $tool);
|
||||||
if ($changed_tool && $toolchange_count[$tool] > 1) {
|
if ($changed_tool && $toolchange_count[$tool] > 1) {
|
||||||
$expected_amount = $print->config->get_at('retract_length_toolchange', $tool) + $print->config->get_at('retract_restart_extra_toolchange', $tool);
|
$expected_amount = $print->print->config->get_at('retract_length_toolchange', $tool) + $print->print->config->get_at('retract_restart_extra_toolchange', $tool);
|
||||||
$changed_tool = 0;
|
$changed_tool = 0;
|
||||||
}
|
}
|
||||||
fail 'unretracted by the correct amount'
|
fail 'unretracted by the correct amount'
|
||||||
@ -84,7 +84,7 @@ use Slic3r::Test qw(_eq);
|
|||||||
$retracted_length[$tool] = 0;
|
$retracted_length[$tool] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($info->{travel} && $info->{dist_XY} >= $print->config->get_at('retract_before_travel', $tool)) {
|
if ($info->{travel} && $info->{dist_XY} >= $print->print->config->get_at('retract_before_travel', $tool)) {
|
||||||
fail 'retracted before long travel move' if !$retracted[$tool];
|
fail 'retracted before long travel move' if !$retracted[$tool];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -20,12 +20,12 @@ use Slic3r::Test;
|
|||||||
|
|
||||||
my $test = sub {
|
my $test = sub {
|
||||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
||||||
$print->init_extruders;
|
$print->print->init_extruders;
|
||||||
my $flow = $print->objects->[0]->support_material_flow;
|
my $flow = $print->print->objects->[0]->support_material_flow;
|
||||||
my $support_z = Slic3r::Print::SupportMaterial
|
my $support_z = Slic3r::Print::SupportMaterial
|
||||||
->new(
|
->new(
|
||||||
object_config => $print->objects->[0]->config,
|
object_config => $print->print->objects->[0]->config,
|
||||||
print_config => $print->config,
|
print_config => $print->print->config,
|
||||||
flow => $flow,
|
flow => $flow,
|
||||||
interface_flow => $flow,
|
interface_flow => $flow,
|
||||||
first_layer_flow => $flow,
|
first_layer_flow => $flow,
|
||||||
|
2
t/svg.t
2
t/svg.t
@ -14,7 +14,7 @@ use Slic3r::Test;
|
|||||||
my $print = Slic3r::Test::init_print('20mm_cube');
|
my $print = Slic3r::Test::init_print('20mm_cube');
|
||||||
eval {
|
eval {
|
||||||
my $fh = IO::Scalar->new(\my $gcode);
|
my $fh = IO::Scalar->new(\my $gcode);
|
||||||
$print->export_svg(output_fh => $fh, quiet => 1);
|
$print->print->export_svg(output_fh => $fh, quiet => 1);
|
||||||
$fh->close;
|
$fh->close;
|
||||||
};
|
};
|
||||||
ok !$@, 'successful SVG export';
|
ok !$@, 'successful SVG export';
|
||||||
|
@ -18,7 +18,7 @@ $ARGV[0] or usage(1);
|
|||||||
|
|
||||||
if (-e $ARGV[0]) {
|
if (-e $ARGV[0]) {
|
||||||
my $model = Slic3r::Format::STL->read_file($ARGV[0]);
|
my $model = Slic3r::Format::STL->read_file($ARGV[0]);
|
||||||
$model->objects->[0]->add_instance(offset => [0,0]);
|
$model->objects->[0]->add_instance(offset => Slic3r::Pointf->new(0,0));
|
||||||
my $mesh = $model->mesh;
|
my $mesh = $model->mesh;
|
||||||
$mesh->repair;
|
$mesh->repair;
|
||||||
printf "VERTICES = %s\n", join ',', map "[$_->[0],$_->[1],$_->[2]]", @{$mesh->vertices};
|
printf "VERTICES = %s\n", join ',', map "[$_->[0],$_->[1],$_->[2]]", @{$mesh->vertices};
|
||||||
|
@ -11,7 +11,8 @@ use Module::Build::WithXSpp;
|
|||||||
# NOGDI : prevents inclusion of wingdi.h which defines functions Polygon() and Polyline() in global namespace
|
# NOGDI : prevents inclusion of wingdi.h which defines functions Polygon() and Polyline() in global namespace
|
||||||
my @cflags = qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI -DSLIC3RXS);
|
my @cflags = qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI -DSLIC3RXS);
|
||||||
if ($ENV{SLIC3R_DEBUG}) {
|
if ($ENV{SLIC3R_DEBUG}) {
|
||||||
push @cflags, qw(-DSLIC3R_DEBUG -g -ftemplate-backtrace-limit=0);
|
# only on newer GCCs: -ftemplate-backtrace-limit=0
|
||||||
|
push @cflags, qw(-DSLIC3R_DEBUG -g);
|
||||||
}
|
}
|
||||||
if (ExtUtils::CppGuess->new->is_gcc) {
|
if (ExtUtils::CppGuess->new->is_gcc) {
|
||||||
# check whether we're dealing with a buggy GCC version
|
# check whether we're dealing with a buggy GCC version
|
||||||
|
188
xs/src/Model.cpp
188
xs/src/Model.cpp
@ -6,24 +6,14 @@ Model::Model() {}
|
|||||||
|
|
||||||
Model::Model(const Model &other)
|
Model::Model(const Model &other)
|
||||||
{
|
{
|
||||||
objects.reserve(other.objects.size());
|
// copy materials
|
||||||
|
for (ModelMaterialMap::const_iterator i = other.materials.begin(); i != other.materials.end(); ++i)
|
||||||
|
this->add_material(i->first, *i->second);
|
||||||
|
|
||||||
for (ModelMaterialMap::const_iterator i = other.materials.begin();
|
// copy objects
|
||||||
i != other.materials.end(); ++i)
|
this->objects.reserve(other.objects.size());
|
||||||
{
|
for (ModelObjectPtrs::const_iterator i = other.objects.begin(); i != other.objects.end(); ++i)
|
||||||
ModelMaterial *copy = new ModelMaterial(*i->second);
|
this->add_object(**i);
|
||||||
copy->model = this;
|
|
||||||
materials[i->first] = copy;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ModelObjectPtrs::const_iterator i = other.objects.begin();
|
|
||||||
i != other.objects.end(); ++i)
|
|
||||||
{
|
|
||||||
ModelObject *copy = new ModelObject(**i);
|
|
||||||
copy->model = this;
|
|
||||||
objects.push_back(copy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Model& Model::operator= (Model other)
|
Model& Model::operator= (Model other)
|
||||||
@ -46,13 +36,19 @@ Model::~Model()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ModelObject*
|
ModelObject*
|
||||||
Model::add_object(const std::string &input_file, const DynamicPrintConfig &config,
|
Model::add_object()
|
||||||
const t_layer_height_ranges &layer_height_ranges, const Pointf &origin_translation)
|
|
||||||
{
|
{
|
||||||
ModelObject* object = new ModelObject(this, input_file, config,
|
ModelObject* new_object = new ModelObject(this);
|
||||||
layer_height_ranges, origin_translation);
|
this->objects.push_back(new_object);
|
||||||
this->objects.push_back(object);
|
return new_object;
|
||||||
return object;
|
}
|
||||||
|
|
||||||
|
ModelObject*
|
||||||
|
Model::add_object(const ModelObject &other)
|
||||||
|
{
|
||||||
|
ModelObject* new_object = new ModelObject(this, other);
|
||||||
|
this->objects.push_back(new_object);
|
||||||
|
return new_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -88,19 +84,40 @@ Model::clear_materials()
|
|||||||
this->delete_material( this->materials.begin()->first );
|
this->delete_material( this->materials.begin()->first );
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelMaterial *
|
ModelMaterial*
|
||||||
Model::set_material(t_model_material_id material_id)
|
Model::add_material(t_model_material_id material_id)
|
||||||
{
|
{
|
||||||
ModelMaterialMap::iterator i = this->materials.find(material_id);
|
ModelMaterial* material = this->get_material(material_id);
|
||||||
|
if (material == NULL) {
|
||||||
|
material = this->materials[material_id] = new ModelMaterial(this);
|
||||||
|
}
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
ModelMaterial *mat;
|
ModelMaterial*
|
||||||
if (i == this->materials.end()) {
|
Model::add_material(t_model_material_id material_id, const ModelMaterial &other)
|
||||||
mat = this->materials[material_id] = new ModelMaterial(this);
|
{
|
||||||
} else {
|
// delete existing material if any
|
||||||
mat = i->second;
|
ModelMaterial* material = this->get_material(material_id);
|
||||||
|
if (material != NULL) {
|
||||||
|
delete material;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mat;
|
// set new material
|
||||||
|
material = new ModelMaterial(this, other);
|
||||||
|
this->materials[material_id] = material;
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelMaterial*
|
||||||
|
Model::get_material(t_model_material_id material_id)
|
||||||
|
{
|
||||||
|
ModelMaterialMap::iterator i = this->materials.find(material_id);
|
||||||
|
if (i == this->materials.end()) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -147,6 +164,9 @@ REGISTER_CLASS(Model, "Model");
|
|||||||
|
|
||||||
|
|
||||||
ModelMaterial::ModelMaterial(Model *model) : model(model) {}
|
ModelMaterial::ModelMaterial(Model *model) : model(model) {}
|
||||||
|
ModelMaterial::ModelMaterial(Model *model, const ModelMaterial &other)
|
||||||
|
: model(model), config(other.config), attributes(other.attributes)
|
||||||
|
{}
|
||||||
|
|
||||||
void
|
void
|
||||||
ModelMaterial::apply(const t_model_material_attributes &attributes)
|
ModelMaterial::apply(const t_model_material_attributes &attributes)
|
||||||
@ -160,20 +180,12 @@ REGISTER_CLASS(ModelMaterial, "Model::Material");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ModelObject::ModelObject(Model *model, const std::string &input_file,
|
ModelObject::ModelObject(Model *model)
|
||||||
const DynamicPrintConfig &config, const t_layer_height_ranges &layer_height_ranges,
|
: model(model)
|
||||||
const Pointf &origin_translation)
|
{}
|
||||||
: model(model),
|
|
||||||
input_file(input_file),
|
|
||||||
config(config),
|
|
||||||
layer_height_ranges(layer_height_ranges),
|
|
||||||
origin_translation(origin_translation),
|
|
||||||
_bounding_box_valid(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelObject::ModelObject(const ModelObject &other)
|
ModelObject::ModelObject(Model *model, const ModelObject &other)
|
||||||
: model(other.model),
|
: model(model),
|
||||||
input_file(other.input_file),
|
input_file(other.input_file),
|
||||||
instances(),
|
instances(),
|
||||||
volumes(),
|
volumes(),
|
||||||
@ -183,25 +195,14 @@ ModelObject::ModelObject(const ModelObject &other)
|
|||||||
_bounding_box(other._bounding_box),
|
_bounding_box(other._bounding_box),
|
||||||
_bounding_box_valid(other._bounding_box_valid)
|
_bounding_box_valid(other._bounding_box_valid)
|
||||||
{
|
{
|
||||||
volumes.reserve(other.volumes.size());
|
|
||||||
instances.reserve(other.instances.size());
|
|
||||||
|
|
||||||
for (ModelVolumePtrs::const_iterator i = other.volumes.begin();
|
this->volumes.reserve(other.volumes.size());
|
||||||
i != other.volumes.end(); ++i)
|
for (ModelVolumePtrs::const_iterator i = other.volumes.begin(); i != other.volumes.end(); ++i)
|
||||||
{
|
this->add_volume(**i);
|
||||||
ModelVolume *v = new ModelVolume(**i);
|
|
||||||
v->object = this;
|
|
||||||
volumes.push_back(v);
|
|
||||||
|
|
||||||
}
|
this->instances.reserve(other.instances.size());
|
||||||
|
for (ModelInstancePtrs::const_iterator i = other.instances.begin(); i != other.instances.end(); ++i)
|
||||||
for (ModelInstancePtrs::const_iterator i = other.instances.begin();
|
this->add_instance(**i);
|
||||||
i != other.instances.end(); ++i)
|
|
||||||
{
|
|
||||||
ModelInstance *in = new ModelInstance(**i);
|
|
||||||
in->object = this;
|
|
||||||
instances.push_back(in);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelObject& ModelObject::operator= (ModelObject other)
|
ModelObject& ModelObject::operator= (ModelObject other)
|
||||||
@ -229,11 +230,19 @@ ModelObject::~ModelObject()
|
|||||||
this->clear_instances();
|
this->clear_instances();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume *
|
ModelVolume*
|
||||||
ModelObject::add_volume(const t_model_material_id &material_id,
|
ModelObject::add_volume(const TriangleMesh &mesh)
|
||||||
const TriangleMesh &mesh, bool modifier)
|
|
||||||
{
|
{
|
||||||
ModelVolume *v = new ModelVolume(this, material_id, mesh, modifier);
|
ModelVolume* v = new ModelVolume(this, mesh);
|
||||||
|
this->volumes.push_back(v);
|
||||||
|
this->invalidate_bounding_box();
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelVolume*
|
||||||
|
ModelObject::add_volume(const ModelVolume &other)
|
||||||
|
{
|
||||||
|
ModelVolume* v = new ModelVolume(this, other);
|
||||||
this->volumes.push_back(v);
|
this->volumes.push_back(v);
|
||||||
this->invalidate_bounding_box();
|
this->invalidate_bounding_box();
|
||||||
return v;
|
return v;
|
||||||
@ -256,12 +265,19 @@ ModelObject::clear_volumes()
|
|||||||
this->delete_volume(i);
|
this->delete_volume(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelInstance *
|
ModelInstance*
|
||||||
ModelObject::add_instance(double rotation, double scaling_factor,
|
ModelObject::add_instance()
|
||||||
Pointf offset)
|
|
||||||
{
|
{
|
||||||
ModelInstance *i = new ModelInstance(
|
ModelInstance* i = new ModelInstance(this);
|
||||||
this, rotation, scaling_factor, offset);
|
this->instances.push_back(i);
|
||||||
|
this->invalidate_bounding_box();
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelInstance*
|
||||||
|
ModelObject::add_instance(const ModelInstance &other)
|
||||||
|
{
|
||||||
|
ModelInstance* i = new ModelInstance(this, other);
|
||||||
this->instances.push_back(i);
|
this->instances.push_back(i);
|
||||||
this->invalidate_bounding_box();
|
this->invalidate_bounding_box();
|
||||||
return i;
|
return i;
|
||||||
@ -300,28 +316,26 @@ REGISTER_CLASS(ModelObject, "Model::Object");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ModelVolume::ModelVolume(ModelObject* object, const t_model_material_id &material_id,
|
ModelVolume::ModelVolume(ModelObject* object, const TriangleMesh &mesh)
|
||||||
const TriangleMesh &mesh, bool modifier)
|
: object(object), mesh(mesh), modifier(false)
|
||||||
: object(object),
|
{}
|
||||||
material_id(material_id),
|
|
||||||
mesh(mesh),
|
ModelVolume::ModelVolume(ModelObject* object, const ModelVolume &other)
|
||||||
modifier(modifier)
|
: object(object), material_id(other.material_id), mesh(other.mesh), modifier(other.modifier)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
REGISTER_CLASS(ModelVolume, "Model::Volume");
|
REGISTER_CLASS(ModelVolume, "Model::Volume");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ModelInstance::ModelInstance(ModelObject *object, double rotation,
|
ModelInstance::ModelInstance(ModelObject *object)
|
||||||
double scaling_factor, const Pointf &offset)
|
: object(object), rotation(0), scaling_factor(1)
|
||||||
: object(object),
|
{}
|
||||||
rotation(rotation),
|
|
||||||
scaling_factor(scaling_factor),
|
ModelInstance::ModelInstance(ModelObject *object, const ModelInstance &other)
|
||||||
offset(offset)
|
: object(object), rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
REGISTER_CLASS(ModelInstance, "Model::Instance");
|
REGISTER_CLASS(ModelInstance, "Model::Instance");
|
||||||
|
@ -38,13 +38,16 @@ class Model
|
|||||||
Model& operator= (Model other);
|
Model& operator= (Model other);
|
||||||
void swap(Model &other);
|
void swap(Model &other);
|
||||||
~Model();
|
~Model();
|
||||||
ModelObject* add_object(const std::string &input_file, const DynamicPrintConfig &config,
|
ModelObject* add_object();
|
||||||
const t_layer_height_ranges &layer_height_ranges, const Pointf &origin_translation);
|
ModelObject* add_object(const ModelObject &other);
|
||||||
void delete_object(size_t idx);
|
void delete_object(size_t idx);
|
||||||
void clear_objects();
|
void clear_objects();
|
||||||
|
|
||||||
|
ModelMaterial* add_material(t_model_material_id material_id);
|
||||||
|
ModelMaterial* add_material(t_model_material_id material_id, const ModelMaterial &other);
|
||||||
|
ModelMaterial* get_material(t_model_material_id material_id);
|
||||||
void delete_material(t_model_material_id material_id);
|
void delete_material(t_model_material_id material_id);
|
||||||
void clear_materials();
|
void clear_materials();
|
||||||
ModelMaterial *set_material(t_model_material_id material_id);
|
|
||||||
// void duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance);
|
// void duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance);
|
||||||
// void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBox &bb);
|
// void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBox &bb);
|
||||||
// void arrange_objects(coordf_t distance, const BoundingBox &bb);
|
// void arrange_objects(coordf_t distance, const BoundingBox &bb);
|
||||||
@ -65,19 +68,25 @@ class Model
|
|||||||
|
|
||||||
class ModelMaterial
|
class ModelMaterial
|
||||||
{
|
{
|
||||||
|
friend class Model;
|
||||||
public:
|
public:
|
||||||
Model* model;
|
|
||||||
t_model_material_attributes attributes;
|
t_model_material_attributes attributes;
|
||||||
DynamicPrintConfig config;
|
DynamicPrintConfig config;
|
||||||
|
|
||||||
ModelMaterial(Model *model);
|
Model* get_model() const { return this->model; };
|
||||||
void apply(const t_model_material_attributes &attributes);
|
void apply(const t_model_material_attributes &attributes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Model* model;
|
||||||
|
|
||||||
|
ModelMaterial(Model *model);
|
||||||
|
ModelMaterial(Model *model, const ModelMaterial &other);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelObject
|
class ModelObject
|
||||||
{
|
{
|
||||||
|
friend class Model;
|
||||||
public:
|
public:
|
||||||
Model* model;
|
|
||||||
std::string input_file;
|
std::string input_file;
|
||||||
ModelInstancePtrs instances;
|
ModelInstancePtrs instances;
|
||||||
ModelVolumePtrs volumes;
|
ModelVolumePtrs volumes;
|
||||||
@ -89,65 +98,76 @@ class ModelObject
|
|||||||
BoundingBoxf3 _bounding_box;
|
BoundingBoxf3 _bounding_box;
|
||||||
bool _bounding_box_valid;
|
bool _bounding_box_valid;
|
||||||
|
|
||||||
ModelObject(Model *model, const std::string &input_file, const DynamicPrintConfig &config,
|
Model* get_model() const { return this->model; };
|
||||||
const t_layer_height_ranges &layer_height_ranges, const Pointf &origin_translation);
|
|
||||||
ModelObject(const ModelObject &other);
|
|
||||||
ModelObject& operator= (ModelObject other);
|
|
||||||
void swap(ModelObject &other);
|
|
||||||
~ModelObject();
|
|
||||||
|
|
||||||
ModelVolume* add_volume(const t_model_material_id &material_id,
|
ModelVolume* add_volume(const TriangleMesh &mesh);
|
||||||
const TriangleMesh &mesh, bool modifier);
|
ModelVolume* add_volume(const ModelVolume &volume);
|
||||||
void delete_volume(size_t idx);
|
void delete_volume(size_t idx);
|
||||||
void clear_volumes();
|
void clear_volumes();
|
||||||
|
|
||||||
ModelInstance *add_instance(double rotation=0, double scaling_factor = 1,
|
ModelInstance* add_instance();
|
||||||
Pointf offset = Pointf(0, 0));
|
ModelInstance* add_instance(const ModelInstance &instance);
|
||||||
void delete_instance(size_t idx);
|
void delete_instance(size_t idx);
|
||||||
void delete_last_instance();
|
void delete_last_instance();
|
||||||
void clear_instances();
|
void clear_instances();
|
||||||
|
|
||||||
void invalidate_bounding_box();
|
void invalidate_bounding_box();
|
||||||
|
|
||||||
void raw_mesh(TriangleMesh* mesh) const;
|
//void raw_mesh(TriangleMesh* mesh) const;
|
||||||
void mesh(TriangleMesh* mesh) const;
|
//void mesh(TriangleMesh* mesh) const;
|
||||||
void instance_bounding_box(size_t instance_idx, BoundingBox* bb) const;
|
//void instance_bounding_box(size_t instance_idx, BoundingBox* bb) const;
|
||||||
void center_around_origin();
|
//void center_around_origin();
|
||||||
void translate(coordf_t x, coordf_t y, coordf_t z);
|
//void translate(coordf_t x, coordf_t y, coordf_t z);
|
||||||
size_t materials_count() const;
|
//size_t materials_count() const;
|
||||||
void unique_materials(std::vector<t_model_material_id>* materials) const;
|
//void unique_materials(std::vector<t_model_material_id>* materials) const;
|
||||||
size_t facets_count() const;
|
//size_t facets_count() const;
|
||||||
bool needed_repair() const;
|
//bool needed_repair() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Model* model;
|
||||||
|
|
||||||
|
ModelObject(Model *model);
|
||||||
|
ModelObject(Model *model, const ModelObject &other);
|
||||||
|
ModelObject& operator= (ModelObject other);
|
||||||
|
void swap(ModelObject &other);
|
||||||
|
~ModelObject();
|
||||||
void update_bounding_box();
|
void update_bounding_box();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelVolume
|
class ModelVolume
|
||||||
{
|
{
|
||||||
|
friend class ModelObject;
|
||||||
public:
|
public:
|
||||||
ModelObject* object;
|
|
||||||
t_model_material_id material_id;
|
t_model_material_id material_id;
|
||||||
TriangleMesh mesh;
|
TriangleMesh mesh;
|
||||||
bool modifier;
|
bool modifier;
|
||||||
|
|
||||||
ModelVolume(ModelObject *object, const t_model_material_id &material_id,
|
ModelObject* get_object() const { return this->object; };
|
||||||
const TriangleMesh &mesh, bool modifier);
|
|
||||||
|
private:
|
||||||
|
ModelObject* object;
|
||||||
|
|
||||||
|
ModelVolume(ModelObject *object, const TriangleMesh &mesh);
|
||||||
|
ModelVolume(ModelObject *object, const ModelVolume &other);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelInstance
|
class ModelInstance
|
||||||
{
|
{
|
||||||
|
friend class ModelObject;
|
||||||
public:
|
public:
|
||||||
ModelObject* object;
|
|
||||||
double rotation; // around mesh center point
|
double rotation; // around mesh center point
|
||||||
double scaling_factor;
|
double scaling_factor;
|
||||||
Pointf offset; // in unscaled coordinates
|
Pointf offset; // in unscaled coordinates
|
||||||
|
|
||||||
ModelInstance(ModelObject *object, double rotation, double scaling_factor,
|
ModelObject* get_object() const { return this->object; };
|
||||||
const Pointf &offset);
|
|
||||||
|
|
||||||
void transform_mesh(TriangleMesh* mesh, bool dont_translate) const;
|
void transform_mesh(TriangleMesh* mesh, bool dont_translate) const;
|
||||||
void transform_polygon(Polygon* polygon) const;
|
void transform_polygon(Polygon* polygon) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelObject* object;
|
||||||
|
|
||||||
|
ModelInstance(ModelObject *object);
|
||||||
|
ModelInstance(ModelObject *object, const ModelInstance &other);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
113
xs/xsp/Model.xsp
113
xs/xsp/Model.xsp
@ -13,37 +13,29 @@
|
|||||||
Clone<Model> clone()
|
Clone<Model> clone()
|
||||||
%code%{ RETVAL = THIS; %};
|
%code%{ RETVAL = THIS; %};
|
||||||
|
|
||||||
Ref<ModelObject> _add_object(std::string input_file,
|
%name{_add_object} Ref<ModelObject> add_object();
|
||||||
DynamicPrintConfig* config,
|
Ref<ModelObject> _add_object_clone(ModelObject* other)
|
||||||
t_layer_height_ranges layer_height_ranges,
|
%code%{ RETVAL = THIS->add_object(*other); %};
|
||||||
Pointf* origin_translation)
|
|
||||||
%code%{
|
|
||||||
RETVAL = THIS->add_object(input_file, *config, layer_height_ranges,
|
|
||||||
*origin_translation);
|
|
||||||
%};
|
|
||||||
|
|
||||||
void delete_object(size_t idx);
|
void delete_object(size_t idx);
|
||||||
void clear_objects();
|
void clear_objects();
|
||||||
void delete_material(t_model_material_id material_id);
|
|
||||||
void clear_materials();
|
|
||||||
|
|
||||||
%name{_set_material} Ref<ModelMaterial> set_material(t_model_material_id material_id)
|
|
||||||
%code%{ RETVAL = THIS->set_material(material_id); %};
|
|
||||||
|
|
||||||
Ref<ModelMaterial> get_material(t_model_material_id material_id)
|
Ref<ModelMaterial> get_material(t_model_material_id material_id)
|
||||||
%code%{
|
%code%{
|
||||||
ModelMaterialMap::iterator i = THIS->materials.find(material_id);
|
RETVAL = THIS->get_material(material_id);
|
||||||
if (i == THIS->materials.end()) {
|
if (RETVAL == NULL) {
|
||||||
XSRETURN_UNDEF;
|
XSRETURN_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETVAL = i->second;
|
|
||||||
%};
|
%};
|
||||||
|
|
||||||
|
%name{add_material} Ref<ModelMaterial> add_material(t_model_material_id material_id);
|
||||||
|
Ref<ModelMaterial> add_material_clone(t_model_material_id material_id, ModelMaterial* other)
|
||||||
|
%code%{ RETVAL = THIS->add_material(material_id, *other); %};
|
||||||
bool has_material(t_model_material_id material_id) const
|
bool has_material(t_model_material_id material_id) const
|
||||||
%code%{
|
%code%{
|
||||||
RETVAL = (THIS->materials.find(material_id) != THIS->materials.end());
|
RETVAL = (THIS->get_material(material_id) != NULL);
|
||||||
%};
|
%};
|
||||||
|
void delete_material(t_model_material_id material_id);
|
||||||
|
void clear_materials();
|
||||||
|
|
||||||
std::vector<std::string> material_names() const
|
std::vector<std::string> material_names() const
|
||||||
%code%{
|
%code%{
|
||||||
@ -70,22 +62,14 @@
|
|||||||
// void split_meshes();
|
// void split_meshes();
|
||||||
// std::string get_material_name(t_model_material_id material_id);
|
// std::string get_material_name(t_model_material_id material_id);
|
||||||
|
|
||||||
ModelObjectPtrs *objects()
|
ModelObjectPtrs* objects()
|
||||||
%code%{
|
%code%{ RETVAL = &THIS->objects; %};
|
||||||
if (THIS->objects.empty()) {
|
|
||||||
XSRETURN_UNDEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
RETVAL = &THIS->objects;
|
|
||||||
%};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
%name{Slic3r::Model::Material} class ModelMaterial {
|
%name{Slic3r::Model::Material} class ModelMaterial {
|
||||||
~ModelMaterial();
|
|
||||||
|
|
||||||
Ref<Model> model()
|
Ref<Model> model()
|
||||||
%code%{ RETVAL = THIS->model; %};
|
%code%{ RETVAL = THIS->get_model(); %};
|
||||||
|
|
||||||
Ref<DynamicPrintConfig> config()
|
Ref<DynamicPrintConfig> config()
|
||||||
%code%{ RETVAL = &THIS->config; %};
|
%code%{ RETVAL = &THIS->config; %};
|
||||||
@ -114,38 +98,15 @@ ModelMaterial::attributes()
|
|||||||
|
|
||||||
|
|
||||||
%name{Slic3r::Model::Object} class ModelObject {
|
%name{Slic3r::Model::Object} class ModelObject {
|
||||||
ModelObject(Model* model, std::string input_file,
|
ModelVolumePtrs* volumes()
|
||||||
DynamicPrintConfig* config, t_layer_height_ranges layer_height_ranges,
|
%code%{ RETVAL = &THIS->volumes; %};
|
||||||
Pointf* origin_translation)
|
|
||||||
%code%{
|
|
||||||
RETVAL = new ModelObject(model, input_file, *config,
|
|
||||||
layer_height_ranges, *origin_translation);
|
|
||||||
%};
|
|
||||||
|
|
||||||
~ModelObject();
|
|
||||||
|
|
||||||
ModelVolumePtrs *volumes()
|
|
||||||
%code%{
|
|
||||||
if (THIS->volumes.empty()) {
|
|
||||||
XSRETURN_UNDEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
RETVAL = &THIS->volumes;
|
|
||||||
%};
|
|
||||||
|
|
||||||
ModelInstancePtrs *instances()
|
|
||||||
%code%{
|
|
||||||
if (THIS->instances.empty()) {
|
|
||||||
XSRETURN_UNDEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
RETVAL = &THIS->instances;
|
|
||||||
%};
|
|
||||||
|
|
||||||
|
ModelInstancePtrs* instances()
|
||||||
|
%code%{ RETVAL = &THIS->instances; %};
|
||||||
|
|
||||||
void invalidate_bounding_box();
|
void invalidate_bounding_box();
|
||||||
|
|
||||||
Ref<BoundingBoxf3> _bounding_box(BoundingBoxf3 *new_bbox = NULL)
|
Ref<BoundingBoxf3> _bounding_box(BoundingBoxf3* new_bbox = NULL)
|
||||||
%code{%
|
%code{%
|
||||||
if (NULL != new_bbox) {
|
if (NULL != new_bbox) {
|
||||||
THIS->_bounding_box = *new_bbox;
|
THIS->_bounding_box = *new_bbox;
|
||||||
@ -159,21 +120,21 @@ ModelMaterial::attributes()
|
|||||||
RETVAL = &THIS->_bounding_box;
|
RETVAL = &THIS->_bounding_box;
|
||||||
%};
|
%};
|
||||||
|
|
||||||
%name{_add_volume} Ref<ModelVolume> add_volume(
|
%name{_add_volume} Ref<ModelVolume> add_volume(TriangleMesh* mesh)
|
||||||
t_model_material_id material_id, TriangleMesh* mesh, bool modifier)
|
%code%{ RETVAL = THIS->add_volume(*mesh); %};
|
||||||
%code%{ RETVAL = THIS->add_volume(material_id, *mesh, modifier); %};
|
Ref<ModelVolume> _add_volume_clone(ModelVolume* other)
|
||||||
|
%code%{ RETVAL = THIS->add_volume(*other); %};
|
||||||
|
|
||||||
void delete_volume(size_t idx);
|
void delete_volume(size_t idx);
|
||||||
void clear_volumes();
|
void clear_volumes();
|
||||||
|
|
||||||
%name{_add_instance} Ref<ModelInstance> add_instance(
|
%name{_add_instance} Ref<ModelInstance> add_instance();
|
||||||
double rotation, double scaling_factor, std::vector<double> offset)
|
Ref<ModelInstance> _add_instance_clone(ModelInstance* other)
|
||||||
%code%{
|
%code%{ RETVAL = THIS->add_instance(*other); %};
|
||||||
RETVAL = THIS->add_instance(rotation, scaling_factor,
|
|
||||||
Pointf(offset[0], offset[1]));
|
|
||||||
%};
|
|
||||||
void delete_last_instance();
|
void delete_last_instance();
|
||||||
void clear_instances();
|
void clear_instances();
|
||||||
|
int instances_count()
|
||||||
|
%code%{ RETVAL = THIS->instances.size(); %};
|
||||||
|
|
||||||
std::string input_file()
|
std::string input_file()
|
||||||
%code%{ RETVAL = THIS->input_file; %};
|
%code%{ RETVAL = THIS->input_file; %};
|
||||||
@ -183,38 +144,42 @@ ModelMaterial::attributes()
|
|||||||
%code%{ RETVAL = &THIS->config; %};
|
%code%{ RETVAL = &THIS->config; %};
|
||||||
|
|
||||||
Ref<Model> model()
|
Ref<Model> model()
|
||||||
%code%{ RETVAL = THIS->model; %};
|
%code%{ RETVAL = THIS->get_model(); %};
|
||||||
|
|
||||||
t_layer_height_ranges layer_height_ranges()
|
t_layer_height_ranges layer_height_ranges()
|
||||||
%code%{ RETVAL = THIS->layer_height_ranges; %};
|
%code%{ RETVAL = THIS->layer_height_ranges; %};
|
||||||
|
void set_layer_height_ranges(t_layer_height_ranges ranges)
|
||||||
|
%code%{ THIS->layer_height_ranges = ranges; %};
|
||||||
|
|
||||||
Clone<Pointf> origin_translation()
|
Clone<Pointf> origin_translation()
|
||||||
%code%{ RETVAL = THIS->origin_translation; %};
|
%code%{ RETVAL = THIS->origin_translation; %};
|
||||||
|
void set_origin_translation(Pointf* point)
|
||||||
|
%code%{ THIS->origin_translation = *point; %};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
%name{Slic3r::Model::Volume} class ModelVolume {
|
%name{Slic3r::Model::Volume} class ModelVolume {
|
||||||
~ModelVolume();
|
|
||||||
|
|
||||||
Ref<ModelObject> object()
|
Ref<ModelObject> object()
|
||||||
%code%{ RETVAL = THIS->object; %};
|
%code%{ RETVAL = THIS->get_object(); %};
|
||||||
|
|
||||||
t_model_material_id material_id()
|
t_model_material_id material_id()
|
||||||
%code%{ RETVAL = THIS->material_id; %};
|
%code%{ RETVAL = THIS->material_id; %};
|
||||||
|
void set_material_id(t_model_material_id material_id)
|
||||||
|
%code%{ THIS->material_id = material_id; %};
|
||||||
|
|
||||||
Ref<TriangleMesh> mesh()
|
Ref<TriangleMesh> mesh()
|
||||||
%code%{ RETVAL = &THIS->mesh; %};
|
%code%{ RETVAL = &THIS->mesh; %};
|
||||||
|
|
||||||
bool modifier()
|
bool modifier()
|
||||||
%code%{ RETVAL = THIS->modifier; %};
|
%code%{ RETVAL = THIS->modifier; %};
|
||||||
|
void set_modifier(bool modifier)
|
||||||
|
%code%{ THIS->modifier = modifier; %};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
%name{Slic3r::Model::Instance} class ModelInstance {
|
%name{Slic3r::Model::Instance} class ModelInstance {
|
||||||
~ModelInstance();
|
|
||||||
|
|
||||||
Ref<ModelObject> object()
|
Ref<ModelObject> object()
|
||||||
%code%{ RETVAL = THIS->object; %};
|
%code%{ RETVAL = THIS->get_object(); %};
|
||||||
|
|
||||||
double rotation()
|
double rotation()
|
||||||
%code%{ RETVAL = THIS->rotation; %};
|
%code%{ RETVAL = THIS->rotation; %};
|
||||||
|
Loading…
Reference in New Issue
Block a user