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 # this will assign a type (top/bottom/internal) to $layerm->slices
# and transform $layerm->fill_surfaces from expolygon # and transform $layerm->fill_surfaces from expolygon
# to typed top/bottom/internal surfaces; # to typed top/bottom/internal surfaces;
$status_cb->(30, "Detecting solid surfaces"); $object->detect_surfaces_type;
$_->detect_surfaces_type for @{$self->objects};
# decide what surfaces are to be filled # decide what surfaces are to be filled
$status_cb->(35, "Preparing infill surfaces"); $_->prepare_fill_surfaces for map @{$_->regions}, @{$object->layers};
$_->prepare_fill_surfaces for map @{$_->regions}, map @{$_->layers}, @{$self->objects};
# this will detect bridges and reverse bridges # this will detect bridges and reverse bridges
# and rearrange top/bottom/internal surfaces # and rearrange top/bottom/internal surfaces
$status_cb->(45, "Detect bridges"); $object->process_external_surfaces;
$_->process_external_surfaces for @{$self->objects};
# detect which fill surfaces are near external layers # detect which fill surfaces are near external layers
# they will be split in internal and internal-solid surfaces # they will be split in internal and internal-solid surfaces
$status_cb->(60, "Generating horizontal shells"); $object->discover_horizontal_shells;
$_->discover_horizontal_shells for @{$self->objects}; $object->clip_fill_surfaces;
$_->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 # the following step needs to be done before combination because it may need
$status_cb->(70, "Combining infill"); # to remove only half of the combined infill
$_->combine_infill for @{$self->objects}; $object->bridge_over_infill;
# combine fill surfaces to honor the "infill every N layers" option
$object->combine_infill;
});
# 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;