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 # skein the STL into layers
# each layer has surfaces with holes # each layer has surfaces with holes
$status_cb->(10, "Processing triangulated mesh"); $status_cb->(10, "Processing triangulated mesh");
$print_step->(STEP_INIT_EXTRUDERS, sub { $object_step->(STEP_SLICE, sub {
my $object = $self->objects->[$_[0]]; $self->objects->[$_[0]]->slice;
$object->slice;
if ($self->config->resolution) {
}
}); });
die "No layers were detected. You might want to repair your STL file(s) or check their size and retry.\n" 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 !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 # make perimeters
# this will add a set of extrusion loops to each layer # this will add a set of extrusion loops to each layer
# as well as generate infill boundaries # as well as generate infill boundaries
$status_cb->(20, "Generating perimeters"); $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), $status_cb->(30, "Preparing infill");
# we only need the max resolution for perimeters $object_step->(STEP_PREPARE_INFILL, sub {
$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION); 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 # decide what surfaces are to be filled
# and transform $layerm->fill_surfaces from expolygon $_->prepare_fill_surfaces for map @{$_->regions}, @{$object->layers};
# 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 # this will detect bridges and reverse bridges
$status_cb->(35, "Preparing infill surfaces"); # and rearrange top/bottom/internal surfaces
$_->prepare_fill_surfaces for map @{$_->regions}, map @{$_->layers}, @{$self->objects}; $object->process_external_surfaces;
# this will detect bridges and reverse bridges # detect which fill surfaces are near external layers
# and rearrange top/bottom/internal surfaces # they will be split in internal and internal-solid surfaces
$status_cb->(45, "Detect bridges"); $object->discover_horizontal_shells;
$_->process_external_surfaces for @{$self->objects}; $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 # combine fill surfaces to honor the "infill every N layers" option
# they will be split in internal and internal-solid surfaces $object->combine_infill;
$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};
# this will generate extrusion paths for each layer # 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( Slic3r::parallelize(
items => sub { items => sub {
my @items = (); # [obj_idx, layer_id] my @items = (); # [layer_id, region_id]
for my $obj_idx (0 .. $#{$self->objects}) { for my $region_id (0 .. ($self->regions_count-1)) {
for my $region_id (0 .. ($self->regions_count-1)) { push @items, map [$_, $region_id], 0..($object->layer_count-1);
push @items, map [$obj_idx, $_, $region_id], 0..($self->objects->[$obj_idx]->layer_count-1);
}
} }
@items; @items;
}, },
thread_cb => sub { thread_cb => sub {
my $q = shift; my $q = shift;
while (defined (my $obj_layer = $q->dequeue)) { while (defined (my $obj_layer = $q->dequeue)) {
my ($obj_idx, $layer_id, $region_id) = @$obj_layer; my ($layer_id, $region_id) = @$obj_layer;
my $object = $self->objects->[$obj_idx];
my $layerm = $object->layers->[$layer_id]->regions->[$region_id]; my $layerm = $object->layers->[$layer_id]->regions->[$region_id];
$layerm->fills->append( $object->fill_maker->make_fill($layerm) ); $layerm->fills->append( $object->fill_maker->make_fill($layerm) );
} }
}, },
collect_cb => sub {}, collect_cb => sub {},
no_threads_cb => sub { no_threads_cb => sub {
foreach my $layerm (map @{$_->regions}, map @{$_->layers}, @{$self->objects}) { foreach my $layerm (map @{$_->regions}, @{$object->layers}) {
$layerm->fills->append($layerm->layer->object->fill_maker->make_fill($layerm)); $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 # generate support material
if ($self->has_support_material) { $status_cb->(85, "Generating support material") if $self->has_support_material;
$status_cb->(85, "Generating support material"); $object_step->(STEP_SUPPORTMATERIAL, sub {
$_->generate_support_material for @{$self->objects}; $self->objects->[$_[0]]->generate_support_material;
} });
# free memory (note that support material needs fill_surfaces)
$_->fill_surfaces->clear for map @{$_->regions}, map @{$_->layers}, @{$self->objects};
# make skirt # make skirt
$status_cb->(88, "Generating skirt"); $status_cb->(88, "Generating skirt");
$self->make_skirt; $print_step->(STEP_SKIRT, sub {
$self->make_brim; # must come after make_skirt $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 # time to make some statistics
if (0) { if (0) {

View file

@ -273,6 +273,11 @@ sub slice {
$self->layers->[$i]->id($i); $self->layers->[$i]->id($i);
} }
} }
# simplify slices if required
if ($self->config->resolution) {
$self->_simplify_slices(scale($self->config->resolution));
}
} }
sub make_perimeters { sub make_perimeters {
@ -348,6 +353,11 @@ sub make_perimeters {
$_->make_perimeters for @{$self->layers}; $_->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 { sub detect_surfaces_type {
@ -850,4 +860,13 @@ sub generate_support_material {
->generate($self); ->generate($self);
} }
sub _simplify_slices {
my ($self, $distance) = @_;
foreach my $layer (@{$self->layers}) {
$layer->slices->simplify($distance);
$_->slices->simplify($distance) for @{$layer->regions};
}
}
1; 1;