Lazy mesh generation so that we only keep it in model object
This commit is contained in:
parent
e4c9171890
commit
0591eecab7
@ -165,4 +165,14 @@ sub y_max {
|
||||
return $self->extents->[Y][MAX];
|
||||
}
|
||||
|
||||
sub z_min {
|
||||
my $self = shift;
|
||||
return $self->extents->[Z][MIN];
|
||||
}
|
||||
|
||||
sub z_max {
|
||||
my $self = shift;
|
||||
return $self->extents->[Z][MAX];
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -84,8 +84,11 @@ sub add_model_object {
|
||||
my %matmap = %{ $object->material_mapping || {} };
|
||||
$_-- for values %matmap; # extruders in the mapping are 1-indexed but we want 0-indexed
|
||||
|
||||
my %meshes = (); # region_id => TriangleMesh
|
||||
foreach my $volume (@{$object->volumes}) {
|
||||
my %volumes = (); # region_id => [ volume_id, ... ]
|
||||
foreach my $volume_id (0..$#{$object->volumes}) {
|
||||
my $volume = $object->volumes->[$volume_id];
|
||||
|
||||
# determine what region should this volume be mapped to
|
||||
my $region_id;
|
||||
if (defined $volume->material_id) {
|
||||
if (!exists $matmap{ $volume->material_id }) {
|
||||
@ -96,27 +99,19 @@ sub add_model_object {
|
||||
} else {
|
||||
$region_id = 0;
|
||||
}
|
||||
$volumes{$region_id} //= [];
|
||||
push @{ $volumes{$region_id} }, $volume_id;
|
||||
|
||||
# instantiate region if it does not exist
|
||||
$self->regions->[$region_id] //= Slic3r::Print::Region->new;
|
||||
|
||||
# if a mesh is already associated to this region, append this one to it
|
||||
$meshes{$region_id} //= Slic3r::TriangleMesh->new;
|
||||
$meshes{$region_id}->merge($volume->mesh);
|
||||
}
|
||||
|
||||
foreach my $mesh (values %meshes) {
|
||||
# we ignore the per-instance transformations currently and only
|
||||
# consider the first one
|
||||
$object->instances->[0]->transform_mesh($mesh, 1);
|
||||
}
|
||||
|
||||
# initialize print object
|
||||
my $o = Slic3r::Print::Object->new(
|
||||
print => $self,
|
||||
meshes => [ map $meshes{$_}, 0..$#{$self->regions} ],
|
||||
model_object => $object,
|
||||
region_volumes => [ map $volumes{$_}, 0..$#{$self->regions} ],
|
||||
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,
|
||||
);
|
||||
@ -892,7 +887,7 @@ sub expanded_output_filepath {
|
||||
@$extra_variables{qw(input_filename input_filename_base)} = parse_filename($input_file);
|
||||
} else {
|
||||
# if no input file was supplied, take the first one from our objects
|
||||
$input_file = $self->objects->[0]->input_file // return undef;
|
||||
$input_file = $self->objects->[0]->model_object->input_file // return undef;
|
||||
}
|
||||
|
||||
if ($path && -d $path) {
|
||||
|
@ -8,8 +8,8 @@ use Slic3r::Geometry::Clipper qw(diff diff_ex intersection intersection_ex union
|
||||
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 'model_object' => (is => 'ro', required => 1);
|
||||
has 'region_volumes' => (is => 'rw', default => sub { [] }); # by region_id
|
||||
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');
|
||||
@ -30,15 +30,16 @@ sub BUILD {
|
||||
# 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 @meshes = map $self->model_object->volumes->[$_]->mesh,
|
||||
map @$_,
|
||||
grep defined $_,
|
||||
@{$self->region_volumes};
|
||||
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));
|
||||
@ -167,8 +168,26 @@ sub slice {
|
||||
}
|
||||
|
||||
# process facets
|
||||
for my $region_id (0 .. $#{$self->meshes}) {
|
||||
my $mesh = $self->meshes->[$region_id] // next; # ignore undef meshes
|
||||
for my $region_id (0..$#{$self->region_volumes}) {
|
||||
next if !defined $self->region_volumes->[$region_id];
|
||||
|
||||
# compose mesh
|
||||
my $mesh;
|
||||
foreach my $volume_id (@{$self->region_volumes->[$region_id]}) {
|
||||
if (defined $mesh) {
|
||||
$mesh->merge($self->model_object->volumes->[$volume_id]->mesh);
|
||||
} else {
|
||||
$mesh = $self->model_object->volumes->[$volume_id]->mesh->clone;
|
||||
}
|
||||
}
|
||||
|
||||
# transform mesh
|
||||
# we ignore the per-instance transformations currently and only
|
||||
# consider the first one
|
||||
$self->model_object->instances->[0]->transform_mesh($mesh, 1);
|
||||
|
||||
# align mesh to Z = 0 and apply XY shift
|
||||
$mesh->translate((map unscale(-$_), @{$self->_copies_shift}), -$mesh->bounding_box->z_min);
|
||||
|
||||
{
|
||||
my $loops = $mesh->slice([ map $_->slice_z, @{$self->layers} ]);
|
||||
@ -178,15 +197,8 @@ sub slice {
|
||||
}
|
||||
# TODO: read slicing_errors
|
||||
}
|
||||
|
||||
# free memory
|
||||
undef $mesh;
|
||||
undef $self->meshes->[$region_id];
|
||||
}
|
||||
|
||||
# free memory
|
||||
$self->meshes(undef);
|
||||
|
||||
# remove last layer(s) if empty
|
||||
pop @{$self->layers} while @{$self->layers} && (!map @{$_->slices}, @{$self->layers->[-1]->regions});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user