More work for step-based slicing

This commit is contained in:
Alessandro Ranellucci 2013-12-19 15:23:10 +01:00
parent 5280b05ebb
commit 685e8e4dfa
2 changed files with 74 additions and 64 deletions

View file

@ -398,108 +398,99 @@ sub process {
# skein the STL into layers
# each layer has surfaces with holes
$status_cb->(10, "Processing triangulated mesh");
$print_step->(STEP_INIT_EXTRUDERS, sub {
my $object = $self->objects->[$_[0]];
$object->slice;
if ($self->config->resolution) {
}
$object_step->(STEP_SLICE, sub {
$self->objects->[$_[0]]->slice;
});
die "No layers were detected. You might want to repair your STL file(s) or check their size and retry.\n"
if !grep @{$_->layers}, @{$self->objects};
if ($self->config->resolution) {
$status_cb->(15, "Simplifying input");
$self->_simplify_slices(scale $Slic3r::Config->resolution);
$print_step->(STEP_INIT_EXTRUDERS, sub {
$self->objects->[$_[0]]->slice;
});
}
# make perimeters
# this will add a set of extrusion loops to each layer
# as well as generate infill boundaries
$status_cb->(20, "Generating perimeters");
$_->make_perimeters for @{$self->objects};
$object_step->(STEP_PERIMETERS, sub {
$self->objects->[$_[0]]->make_perimeters;
});
# simplify slices (both layer and region slices),
# we only need the max resolution for perimeters
$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION);
$status_cb->(30, "Preparing infill");
$object_step->(STEP_PREPARE_INFILL, sub {
my $object = $self->objects->[$_[0]];
# this will assign a type (top/bottom/internal) to $layerm->slices
# and transform $layerm->fill_surfaces from expolygon
# to typed top/bottom/internal surfaces;
$object->detect_surfaces_type;
# this will assign a type (top/bottom/internal) to $layerm->slices
# and transform $layerm->fill_surfaces from expolygon
# to typed top/bottom/internal surfaces;
$status_cb->(30, "Detecting solid surfaces");
$_->detect_surfaces_type for @{$self->objects};
# decide what surfaces are to be filled
$_->prepare_fill_surfaces for map @{$_->regions}, @{$object->layers};
# decide what surfaces are to be filled
$status_cb->(35, "Preparing infill surfaces");
$_->prepare_fill_surfaces for map @{$_->regions}, map @{$_->layers}, @{$self->objects};
# this will detect bridges and reverse bridges
# and rearrange top/bottom/internal surfaces
$object->process_external_surfaces;
# this will detect bridges and reverse bridges
# and rearrange top/bottom/internal surfaces
$status_cb->(45, "Detect bridges");
$_->process_external_surfaces for @{$self->objects};
# detect which fill surfaces are near external layers
# they will be split in internal and internal-solid surfaces
$object->discover_horizontal_shells;
$object->clip_fill_surfaces;
# the following step needs to be done before combination because it may need
# to remove only half of the combined infill
$object->bridge_over_infill;
# detect which fill surfaces are near external layers
# they will be split in internal and internal-solid surfaces
$status_cb->(60, "Generating horizontal shells");
$_->discover_horizontal_shells for @{$self->objects};
$_->clip_fill_surfaces for @{$self->objects};
# the following step needs to be done before combination because it may need
# to remove only half of the combined infill
$_->bridge_over_infill for @{$self->objects};
# combine fill surfaces to honor the "infill every N layers" option
$status_cb->(70, "Combining infill");
$_->combine_infill for @{$self->objects};
# combine fill surfaces to honor the "infill every N layers" option
$object->combine_infill;
});
# this will generate extrusion paths for each layer
$status_cb->(80, "Infilling layers");
{
$status_cb->(70, "Infilling layers");
$object_step->(STEP_INFILL, sub {
my $object = $self->objects->[$_[0]];
Slic3r::parallelize(
items => sub {
my @items = (); # [obj_idx, layer_id]
for my $obj_idx (0 .. $#{$self->objects}) {
for my $region_id (0 .. ($self->regions_count-1)) {
push @items, map [$obj_idx, $_, $region_id], 0..($self->objects->[$obj_idx]->layer_count-1);
}
my @items = (); # [layer_id, region_id]
for my $region_id (0 .. ($self->regions_count-1)) {
push @items, map [$_, $region_id], 0..($object->layer_count-1);
}
@items;
},
thread_cb => sub {
my $q = shift;
while (defined (my $obj_layer = $q->dequeue)) {
my ($obj_idx, $layer_id, $region_id) = @$obj_layer;
my $object = $self->objects->[$obj_idx];
my ($layer_id, $region_id) = @$obj_layer;
my $layerm = $object->layers->[$layer_id]->regions->[$region_id];
$layerm->fills->append( $object->fill_maker->make_fill($layerm) );
}
},
collect_cb => sub {},
no_threads_cb => sub {
foreach my $layerm (map @{$_->regions}, map @{$_->layers}, @{$self->objects}) {
$layerm->fills->append($layerm->layer->object->fill_maker->make_fill($layerm));
foreach my $layerm (map @{$_->regions}, @{$object->layers}) {
$layerm->fills->append($object->fill_maker->make_fill($layerm));
}
},
);
}
### we could free memory now, but this would make this step not idempotent
$_->fill_surfaces->clear for map @{$_->regions}, @{$object->layers};
});
# generate support material
if ($self->has_support_material) {
$status_cb->(85, "Generating support material");
$_->generate_support_material for @{$self->objects};
}
# free memory (note that support material needs fill_surfaces)
$_->fill_surfaces->clear for map @{$_->regions}, map @{$_->layers}, @{$self->objects};
$status_cb->(85, "Generating support material") if $self->has_support_material;
$object_step->(STEP_SUPPORTMATERIAL, sub {
$self->objects->[$_[0]]->generate_support_material;
});
# make skirt
$status_cb->(88, "Generating skirt");
$self->make_skirt;
$self->make_brim; # must come after make_skirt
$print_step->(STEP_SKIRT, sub {
$self->make_skirt;
});
$status_cb->(88, "Generating skirt");
$print_step->(STEP_BRIM, sub {
$self->make_brim; # must come after make_skirt
});
# time to make some statistics
if (0) {

View file

@ -273,6 +273,11 @@ sub slice {
$self->layers->[$i]->id($i);
}
}
# simplify slices if required
if ($self->config->resolution) {
$self->_simplify_slices(scale($self->config->resolution));
}
}
sub make_perimeters {
@ -348,6 +353,11 @@ sub make_perimeters {
$_->make_perimeters for @{$self->layers};
},
);
# simplify slices (both layer and region slices),
# we only need the max resolution for perimeters
### This makes this method not-idempotent, so we keep it disabled for now.
###$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION);
}
sub detect_surfaces_type {
@ -850,4 +860,13 @@ sub generate_support_material {
->generate($self);
}
sub _simplify_slices {
my ($self, $distance) = @_;
foreach my $layer (@{$self->layers}) {
$layer->slices->simplify($distance);
$_->slices->simplify($distance) for @{$layer->regions};
}
}
1;