Move centering outside the Print object
This commit is contained in:
parent
2eff7c238e
commit
250608aa52
@ -6,7 +6,7 @@ use Slic3r::Geometry qw(X Y unscale);
|
||||
|
||||
has 'print' => (is => 'ro', required => 1, handles => [qw(extruders)]);
|
||||
has 'gcodegen' => (is => 'ro', required => 1);
|
||||
has 'shift' => (is => 'ro', required => 1);
|
||||
has 'shift' => (is => 'ro', default => sub { [0,0] });
|
||||
|
||||
has 'spiralvase' => (is => 'lazy');
|
||||
has 'vibration_limit' => (is => 'lazy');
|
||||
|
@ -446,6 +446,7 @@ sub remove {
|
||||
|
||||
splice @{$self->{objects}}, $obj_idx, 1;
|
||||
$self->{model}->delete_object($obj_idx);
|
||||
$self->{print}->delete_object($obj_idx);
|
||||
$self->{list}->DeleteItem($obj_idx);
|
||||
$self->object_list_changed;
|
||||
|
||||
@ -459,6 +460,7 @@ sub reset {
|
||||
|
||||
@{$self->{objects}} = ();
|
||||
$self->{model}->delete_all_objects;
|
||||
$self->{print}->delete_all_objects;
|
||||
$self->{list}->DeleteAllItems;
|
||||
$self->object_list_changed;
|
||||
|
||||
@ -472,12 +474,12 @@ sub increase {
|
||||
my ($obj_idx, $object) = $self->selected_object;
|
||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||
my $last_instance = $model_object->instances->[-1];
|
||||
$model_object->add_instance(
|
||||
my $i = $model_object->add_instance(
|
||||
offset => [ map 10+$_, @{$last_instance->offset} ],
|
||||
scaling_factor => $last_instance->scaling_factor,
|
||||
rotation => $last_instance->rotation,
|
||||
);
|
||||
$self->{print}->objects->[$obj_idx]->copies;
|
||||
$self->{print}->objects->[$obj_idx]->add_copy(@{$i->offset});
|
||||
$self->{list}->SetItem($obj_idx, 1, $model_object->instances_count);
|
||||
$self->arrange;
|
||||
}
|
||||
@ -489,6 +491,7 @@ sub decrease {
|
||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||
if ($model_object->instances_count >= 2) {
|
||||
$model_object->delete_last_instance;
|
||||
$self->{print}->objects->[$obj_idx]->delete_last_copy;
|
||||
$self->{list}->SetItem($obj_idx, 1, $model_object->instances_count);
|
||||
} else {
|
||||
$self->remove;
|
||||
|
@ -143,6 +143,7 @@ sub quick_slice {
|
||||
}
|
||||
$model->arrange_objects($config);
|
||||
}
|
||||
$model->center_instances_around_point($config->print_center);
|
||||
|
||||
$print->add_model_object($_) for @{ $model->objects };
|
||||
$print->validate;
|
||||
|
@ -222,6 +222,23 @@ sub align_to_origin {
|
||||
}
|
||||
}
|
||||
|
||||
# input point is expressed in unscaled coordinates
|
||||
sub center_instances_around_point {
|
||||
my ($self, $point) = @_;
|
||||
|
||||
my $bb = $self->bounding_box;
|
||||
my $size = $bb->size;
|
||||
my @shift = (
|
||||
-$bb->x_min + $point->[X] - $size->[X]/2,
|
||||
-$bb->y_min + $point->[Y] - $size->[Y]/2,
|
||||
);
|
||||
|
||||
foreach my $instance (map @{$_->instances}, @{$self->objects}) {
|
||||
$instance->offset->[X] += $shift[X];
|
||||
$instance->offset->[Y] += $shift[Y];
|
||||
}
|
||||
}
|
||||
|
||||
sub translate {
|
||||
my $self = shift;
|
||||
my @shift = @_;
|
||||
@ -516,11 +533,11 @@ has 'scaling_factor' => (is => 'rw', default => sub { 1 });
|
||||
has 'offset' => (is => 'rw'); # must be arrayref in *unscaled* coordinates
|
||||
|
||||
sub transform_mesh {
|
||||
my ($self, $mesh) = @_;
|
||||
my ($self, $mesh, $dont_translate) = @_;
|
||||
|
||||
$mesh->rotate($self->rotation, Slic3r::Point->new(0,0)); # rotate around mesh origin
|
||||
$mesh->scale($self->scaling_factor); # scale around mesh origin
|
||||
$mesh->translate(@{$self->offset}, 0);
|
||||
$mesh->translate(@{$self->offset}, 0) unless $dont_translate;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -106,41 +106,17 @@ sub add_model_object {
|
||||
$meshes{$region_id}->merge($volume->mesh);
|
||||
}
|
||||
|
||||
# bounding box of the original meshes in original position in unscaled coordinates
|
||||
my $bb1 = Slic3r::Geometry::BoundingBox->merge(map $_->bounding_box, values %meshes);
|
||||
|
||||
foreach my $mesh (values %meshes) {
|
||||
# we ignore the per-instance transformations currently and only
|
||||
# consider the first one
|
||||
$object->instances->[0]->transform_mesh($mesh);
|
||||
}
|
||||
|
||||
# we align object also after transformations so that we only work with positive coordinates
|
||||
# and the assumption that bounding_box === size works
|
||||
my $bb2 = Slic3r::Geometry::BoundingBox->merge(map $_->bounding_box, values %meshes);
|
||||
$_->translate(@{$bb2->vector_to_origin}) for values %meshes;
|
||||
|
||||
# prepare scaled object size
|
||||
my $scaled_bb = $bb2->clone;
|
||||
$scaled_bb->translate(@{$bb2->vector_to_origin}); # not needed for getting size, but who knows
|
||||
$scaled_bb->scale(1 / &Slic3r::SCALING_FACTOR);
|
||||
|
||||
# prepare copies
|
||||
my @copies = ();
|
||||
foreach my $instance (@{ $object->instances }) {
|
||||
push @copies, Slic3r::Point->new(
|
||||
scale($instance->offset->[X] - $bb1->extents->[X][MIN]),
|
||||
scale($instance->offset->[Y] - $bb1->extents->[Y][MIN]),
|
||||
);
|
||||
$object->instances->[0]->transform_mesh($mesh, 1);
|
||||
}
|
||||
|
||||
# initialize print object
|
||||
push @{$self->objects}, Slic3r::Print::Object->new(
|
||||
print => $self,
|
||||
meshes => [ map $meshes{$_}, 0..$#{$self->regions} ],
|
||||
copies => [ @copies ],
|
||||
input_bounding_box => $bb1,
|
||||
size => $scaled_bb->size, # transformed size
|
||||
copies => [ map Slic3r::Point->new_scale(@{ $_->offset }), @{ $object->instances } ],
|
||||
input_file => $object->input_file,
|
||||
config_overrides => $object->config,
|
||||
layer_height_ranges => $object->layer_height_ranges,
|
||||
@ -151,6 +127,19 @@ sub add_model_object {
|
||||
@{$self->extra_variables}{qw(input_filename input_filename_base)} = parse_filename($input_file);
|
||||
}
|
||||
}
|
||||
# TODO: invalidate skirt and brim
|
||||
}
|
||||
|
||||
sub delete_object {
|
||||
my ($self, $obj_idx) = @_;
|
||||
splice @{$self->objects}, $obj_idx, 1;
|
||||
# TODO: invalidate skirt and brim
|
||||
}
|
||||
|
||||
sub delete_all_objects {
|
||||
my ($self) = @_;
|
||||
@{$self->objects} = ();
|
||||
# TODO: invalidate skirt and brim
|
||||
}
|
||||
|
||||
sub validate {
|
||||
@ -163,11 +152,10 @@ sub validate {
|
||||
for my $obj_idx (0 .. $#{$self->objects}) {
|
||||
my $clearance;
|
||||
{
|
||||
my @points = map Slic3r::Point->new(@$_[X,Y]), map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes};
|
||||
my $convex_hull = convex_hull(\@points);
|
||||
($clearance) = @{offset([$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND)};
|
||||
my @convex_hulls = map $_->convex_hull, grep defined $_, @{$self->objects->[$obj_idx]->meshes};
|
||||
($clearance) = @{offset([@convex_hulls], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND)};
|
||||
}
|
||||
for my $copy (@{$self->objects->[$obj_idx]->copies}) {
|
||||
for my $copy (@{$self->objects->[$obj_idx]->_shifted_copies}) {
|
||||
my $copy_clearance = $clearance->clone;
|
||||
$copy_clearance->translate(@$copy);
|
||||
if (@{ intersection(\@a, [$copy_clearance]) }) {
|
||||
@ -287,7 +275,7 @@ sub bounding_box {
|
||||
|
||||
my @points = ();
|
||||
foreach my $object (@{$self->objects}) {
|
||||
foreach my $copy (@{$object->copies}) {
|
||||
foreach my $copy (@{$object->_shifted_copies}) {
|
||||
push @points,
|
||||
[ $copy->[X], $copy->[Y] ],
|
||||
[ $copy->[X] + $object->size->[X], $copy->[Y] + $object->size->[Y] ];
|
||||
@ -511,7 +499,7 @@ EOF
|
||||
|
||||
# sort slices so that the outermost ones come first
|
||||
my @slices = sort { $a->contour->contains_point($b->contour->first_point) ? 0 : 1 } @{$layer->slices};
|
||||
foreach my $copy (@{$self->objects->[$obj_idx]->copies}) {
|
||||
foreach my $copy (@{$self->objects->[$obj_idx]->_shifted_copies}) {
|
||||
foreach my $slice (@slices) {
|
||||
my $expolygon = $slice->clone;
|
||||
$expolygon->translate(@$copy);
|
||||
@ -573,7 +561,7 @@ sub make_skirt {
|
||||
(map @{$_->polyline}, map @{$_->support_fills}, grep $_->support_fills, @support_layers),
|
||||
(map @{$_->polyline}, map @{$_->support_interface_fills}, grep $_->support_interface_fills, @support_layers);
|
||||
}
|
||||
push @points, map move_points($_, @layer_points), @{$object->copies};
|
||||
push @points, map move_points($_, @layer_points), @{$object->_shifted_copies};
|
||||
}
|
||||
return if @points < 3; # at least three points required for a convex hull
|
||||
|
||||
@ -641,7 +629,7 @@ sub make_brim {
|
||||
(map @{$_->polyline->grow($grow_distance)}, @{$support_layer0->support_interface_fills})
|
||||
if $support_layer0->support_interface_fills;
|
||||
}
|
||||
foreach my $copy (@{$object->copies}) {
|
||||
foreach my $copy (@{$object->_shifted_copies}) {
|
||||
push @islands, map { $_->translate(@$copy); $_ } map $_->clone, @object_islands;
|
||||
}
|
||||
}
|
||||
@ -751,14 +739,6 @@ sub write_gcode {
|
||||
# TODO: make sure we select the first *used* extruder
|
||||
print $fh $gcodegen->set_extruder($self->extruders->[0]);
|
||||
|
||||
# calculate X,Y shift to center print around specified origin
|
||||
my $print_bb = $self->bounding_box;
|
||||
my $print_size = $print_bb->size;
|
||||
my @shift = (
|
||||
$Slic3r::Config->print_center->[X] - unscale($print_size->[X]/2 + $print_bb->x_min),
|
||||
$Slic3r::Config->print_center->[Y] - unscale($print_size->[Y]/2 + $print_bb->y_min),
|
||||
);
|
||||
|
||||
# initialize a motion planner for object-to-object travel moves
|
||||
if ($Slic3r::Config->avoid_crossing_perimeters) {
|
||||
my $distance_from_objects = 1;
|
||||
@ -771,9 +751,8 @@ sub write_gcode {
|
||||
# discard layers only containing thin walls (offset would fail on an empty polygon)
|
||||
if (@$convex_hull) {
|
||||
my $expolygon = Slic3r::ExPolygon->new($convex_hull);
|
||||
$expolygon->translate(scale $shift[X], scale $shift[Y]);
|
||||
my @island = @{$expolygon->offset_ex(scale $distance_from_objects, 1, JT_SQUARE)};
|
||||
foreach my $copy (@{ $self->objects->[$obj_idx]->copies }) {
|
||||
foreach my $copy (@{ $self->objects->[$obj_idx]->shifted_copies }) {
|
||||
push @islands, map { my $c = $_->clone; $c->translate(@$copy); $c } @island;
|
||||
}
|
||||
}
|
||||
@ -800,7 +779,6 @@ sub write_gcode {
|
||||
my $layer_gcode = Slic3r::GCode::Layer->new(
|
||||
print => $self,
|
||||
gcodegen => $gcodegen,
|
||||
shift => \@shift,
|
||||
);
|
||||
|
||||
# do all objects for each layer
|
||||
@ -817,7 +795,7 @@ sub write_gcode {
|
||||
# this happens before Z goes down to layer 0 again, so that
|
||||
# no collision happens hopefully.
|
||||
if ($finished_objects > 0) {
|
||||
$gcodegen->set_shift(map $shift[$_] + unscale $copy->[$_], X,Y);
|
||||
$gcodegen->set_shift(map unscale $copy->[$_], X,Y);
|
||||
print $fh $gcodegen->retract;
|
||||
print $fh $gcodegen->G0(Slic3r::Point->new(0,0), undef, 0, 'move to origin position for next object');
|
||||
}
|
||||
@ -851,7 +829,7 @@ sub write_gcode {
|
||||
}
|
||||
} else {
|
||||
# order objects using a nearest neighbor search
|
||||
my @obj_idx = @{chained_path([ map Slic3r::Point->new(@{$_->copies->[0]}), @{$self->objects} ])};
|
||||
my @obj_idx = @{chained_path([ map Slic3r::Point->new(@{$_->_shifted_copies->[0]}), @{$self->objects} ])};
|
||||
|
||||
# sort layers by Z
|
||||
my %layers = (); # print_z => [ [layers], [layers], [layers] ] by obj_idx
|
||||
@ -872,7 +850,7 @@ sub write_gcode {
|
||||
foreach my $obj_idx (@obj_idx) {
|
||||
foreach my $layer (@{ $layers{$print_z}[$obj_idx] // [] }) {
|
||||
print $fh $buffer->append(
|
||||
$layer_gcode->process_layer($layer, $layer->object->copies),
|
||||
$layer_gcode->process_layer($layer, $layer->object->_shifted_copies),
|
||||
$layer->object . ref($layer), # differentiate $obj_id between normal layers and support layers
|
||||
$layer->id,
|
||||
$layer->print_z,
|
||||
|
@ -10,14 +10,16 @@ use Slic3r::Surface ':types';
|
||||
has 'print' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'input_file' => (is => 'rw', required => 0);
|
||||
has 'meshes' => (is => 'rw', default => sub { [] }); # by region_id
|
||||
has 'size' => (is => 'rw', required => 1); # XYZ in scaled coordinates
|
||||
has 'copies' => (is => 'rw', trigger => 1); # in scaled coordinates
|
||||
has 'copies_shift' => (is => 'rw'); # scaled coordinates to add to copies (to compensate for the alignment operated when creating the object but still preserving a coherent API for external callers)
|
||||
has 'layers' => (is => 'rw', default => sub { [] });
|
||||
has 'support_layers' => (is => 'rw', default => sub { [] });
|
||||
has 'copies' => (is => 'ro'); # Slic3r::Point objects in scaled G-code coordinates
|
||||
has 'config_overrides' => (is => 'rw', default => sub { Slic3r::Config->new });
|
||||
has 'config' => (is => 'rw');
|
||||
has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ]
|
||||
|
||||
has 'size' => (is => 'rw'); # XYZ in scaled coordinates
|
||||
has '_copies_shift' => (is => 'rw'); # scaled coordinates to add to copies (to compensate for the alignment operated when creating the object but still preserving a coherent API for external callers)
|
||||
has '_shifted_copies' => (is => 'rw'); # Slic3r::Point objects in scaled G-code coordinates in our coordinates
|
||||
has 'layers' => (is => 'rw', default => sub { [] });
|
||||
has 'support_layers' => (is => 'rw', default => sub { [] });
|
||||
has 'fill_maker' => (is => 'lazy');
|
||||
|
||||
sub BUILD {
|
||||
@ -25,54 +27,28 @@ sub BUILD {
|
||||
|
||||
$self->init_config;
|
||||
|
||||
# make layers taking custom heights into account
|
||||
my $print_z = my $slice_z = my $height = my $id = 0;
|
||||
|
||||
# add raft layers
|
||||
if ($self->config->raft_layers > 0) {
|
||||
$print_z += $Slic3r::Config->get_value('first_layer_height');
|
||||
$print_z += $Slic3r::Config->layer_height * ($self->config->raft_layers - 1);
|
||||
$id += $self->config->raft_layers;
|
||||
}
|
||||
|
||||
# loop until we have at least one layer and the max slice_z reaches the object height
|
||||
my $max_z = unscale $self->size->[Z];
|
||||
while (!@{$self->layers} || ($slice_z - $height) <= $max_z) {
|
||||
# assign the default height to the layer according to the general settings
|
||||
$height = ($id == 0)
|
||||
? $Slic3r::Config->get_value('first_layer_height')
|
||||
: $Slic3r::Config->layer_height;
|
||||
|
||||
# look for an applicable custom range
|
||||
if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) {
|
||||
$height = $range->[2];
|
||||
|
||||
# if user set custom height to zero we should just skip the range and resume slicing over it
|
||||
if ($height == 0) {
|
||||
$slice_z += $range->[1] - $range->[0];
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
$print_z += $height;
|
||||
$slice_z += $height/2;
|
||||
|
||||
### Slic3r::debugf "Layer %d: height = %s; slice_z = %s; print_z = %s\n", $id, $height, $slice_z, $print_z;
|
||||
|
||||
push @{$self->layers}, Slic3r::Layer->new(
|
||||
object => $self,
|
||||
id => $id,
|
||||
height => $height,
|
||||
print_z => $print_z,
|
||||
slice_z => $slice_z,
|
||||
);
|
||||
if (@{$self->layers} >= 2) {
|
||||
$self->layers->[-2]->upper_layer($self->layers->[-1]);
|
||||
}
|
||||
$id++;
|
||||
|
||||
$slice_z += $height/2; # add the other half layer
|
||||
}
|
||||
# translate meshes so that we work with smaller coordinates
|
||||
{
|
||||
# compute the bounding box of the supplied meshes
|
||||
my @meshes = grep defined $_, @{$self->meshes}; # in no particular order
|
||||
my $bb = Slic3r::Geometry::BoundingBox->merge(map $_->bounding_box, @meshes);
|
||||
|
||||
# Translate meshes so that our toolpath generation algorithms work with smaller
|
||||
# XY coordinates; this translation is an optimization and not strictly required.
|
||||
# However, this also aligns object to Z = 0, which on the contrary is required
|
||||
# since we don't assume input is already aligned.
|
||||
$_->translate(@{$bb->vector_to_origin}) for @meshes;
|
||||
|
||||
# We store the XY translation so that we can place copies correctly in the output G-code
|
||||
# (copies are expressed in G-code coordinates and this translation is not publicly exposed).
|
||||
$self->_copies_shift(Slic3r::Point->new_scale($bb->x_min, $bb->y_min));
|
||||
$self->_trigger_copies;
|
||||
|
||||
# Scale the object size and store it
|
||||
my $scaled_bb = $bb->clone;
|
||||
$scaled_bb->scale(1 / &Slic3r::SCALING_FACTOR);
|
||||
$self->size($scaled_bb->size);
|
||||
}
|
||||
}
|
||||
|
||||
sub _build_fill_maker {
|
||||
@ -80,13 +56,32 @@ sub _build_fill_maker {
|
||||
return Slic3r::Fill->new(bounding_box => $self->bounding_box);
|
||||
}
|
||||
|
||||
# This should be probably moved in Print.pm at the point where we sort Layer objects
|
||||
sub _trigger_copies {
|
||||
my $self = shift;
|
||||
return unless @{$self->copies} > 1;
|
||||
|
||||
# order copies with a nearest neighbor search
|
||||
@{$self->copies} = @{$self->copies}[@{chained_path($self->copies)}];
|
||||
return if !defined $self->_copies_shift;
|
||||
|
||||
# order copies with a nearest neighbor search and translate them by _copies_shift
|
||||
$self->_shifted_copies([
|
||||
map {
|
||||
my $c = $_->clone;
|
||||
$c->translate(@{ $self->_copies_shift });
|
||||
$c;
|
||||
} @{$self->copies}[@{chained_path($self->copies)}]
|
||||
]);
|
||||
}
|
||||
|
||||
# in unscaled coordinates
|
||||
sub add_copy {
|
||||
my ($self, $x, $y) = @_;
|
||||
push @{$self->copies}, Slic3r::Point->new_scale($x, $y);
|
||||
$self->_trigger_copies;
|
||||
}
|
||||
|
||||
sub delete_last_copy {
|
||||
my ($self) = @_;
|
||||
pop @{$self->copies};
|
||||
$self->_trigger_copies;
|
||||
}
|
||||
|
||||
sub init_config {
|
||||
@ -106,10 +101,65 @@ sub bounding_box {
|
||||
return Slic3r::Geometry::BoundingBox->new_from_points([ map Slic3r::Point->new(@$_[X,Y]), [0,0], $self->size ]);
|
||||
}
|
||||
|
||||
# this should be idempotent
|
||||
sub slice {
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
# init layers
|
||||
{
|
||||
@{$self->layers} = ();
|
||||
|
||||
# make layers taking custom heights into account
|
||||
my $print_z = my $slice_z = my $height = my $id = 0;
|
||||
|
||||
# add raft layers
|
||||
if ($self->config->raft_layers > 0) {
|
||||
$print_z += $Slic3r::Config->get_value('first_layer_height');
|
||||
$print_z += $Slic3r::Config->layer_height * ($self->config->raft_layers - 1);
|
||||
$id += $self->config->raft_layers;
|
||||
}
|
||||
|
||||
# loop until we have at least one layer and the max slice_z reaches the object height
|
||||
my $max_z = unscale $self->size->[Z];
|
||||
while (!@{$self->layers} || ($slice_z - $height) <= $max_z) {
|
||||
# assign the default height to the layer according to the general settings
|
||||
$height = ($id == 0)
|
||||
? $Slic3r::Config->get_value('first_layer_height')
|
||||
: $Slic3r::Config->layer_height;
|
||||
|
||||
# look for an applicable custom range
|
||||
if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) {
|
||||
$height = $range->[2];
|
||||
|
||||
# if user set custom height to zero we should just skip the range and resume slicing over it
|
||||
if ($height == 0) {
|
||||
$slice_z += $range->[1] - $range->[0];
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
$print_z += $height;
|
||||
$slice_z += $height/2;
|
||||
|
||||
### Slic3r::debugf "Layer %d: height = %s; slice_z = %s; print_z = %s\n", $id, $height, $slice_z, $print_z;
|
||||
|
||||
push @{$self->layers}, Slic3r::Layer->new(
|
||||
object => $self,
|
||||
id => $id,
|
||||
height => $height,
|
||||
print_z => $print_z,
|
||||
slice_z => $slice_z,
|
||||
);
|
||||
if (@{$self->layers} >= 2) {
|
||||
$self->layers->[-2]->upper_layer($self->layers->[-1]);
|
||||
}
|
||||
$id++;
|
||||
|
||||
$slice_z += $height/2; # add the other half layer
|
||||
}
|
||||
}
|
||||
|
||||
# make sure all layers contain layer region objects for all regions
|
||||
my $regions_count = $self->print->regions_count;
|
||||
foreach my $layer (@{ $self->layers }) {
|
||||
|
@ -79,7 +79,7 @@ sub _plot {
|
||||
my (@rectangles, @circles) = ();
|
||||
|
||||
foreach my $object (@{$self->print->objects}) {
|
||||
foreach my $copy (@{$object->copies}) {
|
||||
foreach my $copy (@{$object->shifted_copies}) {
|
||||
foreach my $layer (@{$object->layers}, @{$object->support_layers}) {
|
||||
# get all ExtrusionPath objects
|
||||
my @paths =
|
||||
|
@ -144,6 +144,7 @@ if (@ARGV) { # slicing from command line
|
||||
# if all input objects have defined position(s) apply duplication to the whole model
|
||||
$model->duplicate($config, $config->duplicate);
|
||||
}
|
||||
$model->center_instances_around_point($config->print_center);
|
||||
|
||||
if ($opt{info}) {
|
||||
$model->print_info;
|
||||
@ -152,6 +153,7 @@ if (@ARGV) { # slicing from command line
|
||||
|
||||
my $print = Slic3r::Print->new(config => $config);
|
||||
$print->add_model_object($_) for @{$model->objects};
|
||||
undef $model; # free memory
|
||||
$print->validate;
|
||||
my %params = (
|
||||
output_file => $opt{output},
|
||||
|
@ -191,10 +191,8 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||
FUTURE: parallelize slice_facet() and make_loops()
|
||||
*/
|
||||
|
||||
if (!this->repaired) this->repair();
|
||||
|
||||
// build a table to map a facet_idx to its three edge indices
|
||||
if (this->stl.v_shared == NULL) stl_generate_shared_vertices(&(this->stl));
|
||||
this->require_shared_vertices();
|
||||
typedef std::pair<int,int> t_edge;
|
||||
typedef std::vector<t_edge> t_edges; // edge_idx => a_id,b_id
|
||||
typedef std::map<t_edge,int> t_edges_map; // a_id,b_id => edge_idx
|
||||
@ -607,7 +605,7 @@ TriangleMesh::horizontal_projection(ExPolygons &retval) const
|
||||
void
|
||||
TriangleMesh::convex_hull(Polygon* hull)
|
||||
{
|
||||
if (this->stl.v_shared == NULL) stl_generate_shared_vertices(&(this->stl));
|
||||
this->require_shared_vertices();
|
||||
Points pp;
|
||||
pp.reserve(this->stl.stats.shared_vertices);
|
||||
for (int i = 0; i < this->stl.stats.shared_vertices; i++) {
|
||||
@ -617,6 +615,13 @@ TriangleMesh::convex_hull(Polygon* hull)
|
||||
Slic3r::Geometry::convex_hull(pp, hull);
|
||||
}
|
||||
|
||||
void
|
||||
TriangleMesh::require_shared_vertices()
|
||||
{
|
||||
if (!this->repaired) this->repair();
|
||||
if (this->stl.v_shared == NULL) stl_generate_shared_vertices(&(this->stl));
|
||||
}
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
SV*
|
||||
TriangleMesh::to_SV() {
|
||||
|
@ -37,6 +37,9 @@ class TriangleMesh
|
||||
stl_file stl;
|
||||
bool repaired;
|
||||
|
||||
private:
|
||||
void require_shared_vertices();
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
SV* to_SV();
|
||||
void ReadFromPerl(SV* vertices, SV* facets);
|
||||
|
Loading…
Reference in New Issue
Block a user