mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Refactor/clean up. Merge remove_small_surfaces() into prepare_fill_surfaces(), rename infill_every_layers() to combine_infill(), remove $layer->fill_boundaries, initialize layer properties explicitely for clarity.
This commit is contained in:
		
							parent
							
								
									a5d683a9b9
								
							
						
					
					
						commit
						1d04e15b63
					
				
					 3 changed files with 47 additions and 74 deletions
				
			
		|  | @ -25,60 +25,36 @@ has 'infill_flow'     => (is => 'lazy'); | |||
| 
 | ||||
| # collection of spare segments generated by slicing the original geometry; | ||||
| # these need to be merged in continuos (closed) polylines | ||||
| has 'lines' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[ArrayRef]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| has 'lines' => (is => 'rw', default => sub { [] }); | ||||
| 
 | ||||
| # collection of surfaces generated by slicing the original geometry | ||||
| has 'slices' => (is => 'ro', default => sub { [] }); | ||||
| has 'slices' => (is => 'rw'); | ||||
| 
 | ||||
| # collection of polygons or polylines representing thin walls contained  | ||||
| # in the original geometry | ||||
| has 'thin_walls' => (is => 'ro', default => sub { [] }); | ||||
| 
 | ||||
| # collection of expolygons generated by offsetting the innermost perimeter(s) | ||||
| # they represent boundaries of areas to fill | ||||
| has 'fill_boundaries' => (is => 'ro', default => sub { [] }); | ||||
| has 'thin_walls' => (is => 'rw'); | ||||
| 
 | ||||
| # collection of polygons or polylines representing thin infill regions that | ||||
| # need to be filled with a medial axis | ||||
| has 'thin_fills' => (is => 'ro', default => sub { [] }); | ||||
| has 'thin_fills' => (is => 'rw'); | ||||
| 
 | ||||
| # collection of surfaces generated by clipping the slices to the fill boundaries | ||||
| has 'surfaces' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[Slic3r::Surface]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| # collection of expolygons generated by offsetting the innermost perimeter(s) | ||||
| # they represent boundaries of areas to fill, typed (top/bottom/internal) | ||||
| has 'surfaces' => (is => 'rw'); | ||||
| 
 | ||||
| # collection of surfaces for infill | ||||
| has 'fill_surfaces' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[Slic3r::Surface]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| # collection of surfaces for infill generation. the difference between surfaces | ||||
| # fill_surfaces is that this one honors fill_density == 0 and turns small internal | ||||
| # surfaces into solid ones | ||||
| has 'fill_surfaces' => (is => 'rw'); | ||||
| 
 | ||||
| # ordered collection of extrusion paths to build all perimeters | ||||
| has 'perimeters' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[Slic3r::ExtrusionLoop]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| # ordered collection of extrusion paths/loops to build all perimeters | ||||
| has 'perimeters' => (is => 'rw'); | ||||
| 
 | ||||
| # ordered collection of extrusion paths to fill surfaces for support material | ||||
| has 'support_fills' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'Slic3r::ExtrusionPath::Collection', | ||||
| ); | ||||
| has 'support_fills' => (is => 'rw'); | ||||
| 
 | ||||
| # ordered collection of extrusion paths to fill surfaces | ||||
| has 'fills' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[Slic3r::ExtrusionPath::Collection]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| has 'fills' => (is => 'rw'); | ||||
| 
 | ||||
| # Z used for slicing | ||||
| sub _build_slice_z { | ||||
|  | @ -123,14 +99,6 @@ sub _build_infill_flow { | |||
|         : $Slic3r::infill_flow; | ||||
| } | ||||
| 
 | ||||
| sub add_line { | ||||
|     my $self = shift; | ||||
|     my ($line) = @_; | ||||
|      | ||||
|     push @{ $self->lines }, $line; | ||||
|     return $line; | ||||
| } | ||||
| 
 | ||||
| # build polylines from lines | ||||
| sub make_surfaces { | ||||
|     my $self = shift; | ||||
|  | @ -144,9 +112,10 @@ sub make_surfaces { | |||
|         Slic3r::debugf "  %d surface(s) having %d holes detected from %d polylines\n", | ||||
|             scalar(@$expolygons), scalar(map $_->holes, @$expolygons), scalar(@$loops); | ||||
|          | ||||
|         push @{$self->slices}, | ||||
|         $self->slices([ | ||||
|             map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_INTERNAL), | ||||
|                 @$expolygons; | ||||
|                 @$expolygons | ||||
|         ]); | ||||
|     } | ||||
|      | ||||
|     # the contours must be offsetted by half extrusion width inwards | ||||
|  | @ -170,13 +139,12 @@ sub make_surfaces { | |||
|             1, | ||||
|         ); | ||||
|          | ||||
|         $self->thin_walls([]); | ||||
|         if (@$diff) { | ||||
|             my $area_threshold = scale($self->perimeters_flow->spacing) ** 2; | ||||
|             @$diff = grep $_->area > ($area_threshold), @$diff; | ||||
|              | ||||
|             push @{$self->thin_walls}, | ||||
|                 map $_->medial_axis(scale $self->perimeters_flow->width), | ||||
|                 @$diff; | ||||
|             @{$self->thin_walls} = map $_->medial_axis(scale $self->perimeters_flow->width), @$diff; | ||||
|              | ||||
|             Slic3r::debugf "  %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls}; | ||||
|         } | ||||
|  | @ -216,6 +184,10 @@ sub make_perimeters { | |||
|         map [ $_->contour->[0], $_ ], @{$self->slices}, | ||||
|     ])}; | ||||
|      | ||||
|     $self->perimeters([]); | ||||
|     $self->surfaces([]); | ||||
|     $self->thin_fills([]); | ||||
|      | ||||
|     # for each island: | ||||
|     foreach my $surface (@surfaces) { | ||||
|         my @last_offsets = ($surface->expolygon); | ||||
|  | @ -276,7 +248,7 @@ sub make_perimeters { | |||
|         { | ||||
|             my @fill_boundaries = map $_->offset_ex(-$distance), @last_offsets; | ||||
|             $_->simplify(scale $Slic3r::resolution) for @fill_boundaries; | ||||
|             push @{ $self->fill_boundaries }, @fill_boundaries; | ||||
|             push @{ $self->surfaces }, @fill_boundaries; | ||||
|              | ||||
|             # detect the small gaps that we need to treat like thin polygons, | ||||
|             # thus generating the skeleton and using it to fill them | ||||
|  | @ -336,13 +308,13 @@ sub make_perimeters { | |||
|         } | ||||
|          | ||||
|         # do holes, then contours starting from innermost one | ||||
|         $self->add_perimeter($holes[$_], $is_external{$_} ? EXTR_ROLE_EXTERNAL_PERIMETER : undef) | ||||
|         $self->_add_perimeter($holes[$_], $is_external{$_} ? EXTR_ROLE_EXTERNAL_PERIMETER : undef) | ||||
|             for reverse 0 .. $#holes; | ||||
|         for my $depth (reverse 0 .. $#$island) { | ||||
|             my $role = $depth == $#$island ? EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER | ||||
|                 : $depth == 0 ? EXTR_ROLE_EXTERNAL_PERIMETER | ||||
|                 : EXTR_ROLE_PERIMETER; | ||||
|             $self->add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]}; | ||||
|             $self->_add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]}; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  | @ -363,7 +335,7 @@ sub make_perimeters { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| sub add_perimeter { | ||||
| sub _add_perimeter { | ||||
|     my $self = shift; | ||||
|     my ($polygon, $role) = @_; | ||||
|      | ||||
|  | @ -381,6 +353,7 @@ sub prepare_fill_surfaces { | |||
|     my @surfaces = @{$self->surfaces}; | ||||
|      | ||||
|     # if no solid layers are requested, turn top/bottom surfaces to internal | ||||
|     # note that this modifies $self->surfaces in place | ||||
|     if ($Slic3r::solid_layers == 0) { | ||||
|         $_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type != S_TYPE_INTERNAL, @surfaces; | ||||
|     } | ||||
|  | @ -414,6 +387,7 @@ sub prepare_fill_surfaces { | |||
|     # (those that are too tight for extrusion) | ||||
|     { | ||||
|         my $distance = scale $self->infill_flow->spacing / 2; | ||||
|         my @fill_surfaces = (); | ||||
|          | ||||
|         foreach my $surface (@surfaces) { | ||||
|             # offset inwards | ||||
|  | @ -423,25 +397,26 @@ sub prepare_fill_surfaces { | |||
|             @offsets = map $_->offset_ex($distance), @offsets; | ||||
|             @offsets = @{ union_ex([ map @$_, @offsets ], undef, 1) }; | ||||
|              | ||||
|             push @{$self->fill_surfaces}, map Slic3r::Surface->new( | ||||
|             push @fill_surfaces, map Slic3r::Surface->new( | ||||
|                 expolygon => $_, | ||||
|                 surface_type => $surface->surface_type), @offsets; | ||||
|         } | ||||
|          | ||||
|         Slic3r::debugf "identified %d small surfaces at layer %d\n", | ||||
|             (@surfaces - @{$self->fill_surfaces}), $self->id  | ||||
|             if @{$self->fill_surfaces} != @surfaces; | ||||
|             (@surfaces - @fill_surfaces), $self->id  | ||||
|             if @fill_surfaces != @surfaces; | ||||
|          | ||||
|         # the difference between @surfaces and $self->fill_surfaces | ||||
|         # is what's too small; we add it back as solid infill | ||||
|         if ($Slic3r::fill_density > 0) { | ||||
|             my $diff = diff_ex( | ||||
|                 [ map $_->p, @surfaces ], | ||||
|                 [ map $_->p, @{$self->fill_surfaces} ], | ||||
|                 [ map $_->p, @fill_surfaces ], | ||||
|             ); | ||||
|             push @{$self->fill_surfaces}, map Slic3r::Surface->new( | ||||
|             push @surfaces, map Slic3r::Surface->new( | ||||
|                 expolygon => $_, | ||||
|                 surface_type => S_TYPE_INTERNALSOLID), @$diff; | ||||
|                 surface_type => S_TYPE_INTERNALSOLID | ||||
|             ), @$diff; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  |  | |||
|  | @ -252,11 +252,11 @@ sub export_gcode { | |||
|     $_->discover_horizontal_shells for @{$self->objects}; | ||||
|      | ||||
|     # free memory | ||||
|     @{$_->surfaces} = () for map @{$_->layers}, @{$self->objects}; | ||||
|     $_->surfaces(undef) for map @{$_->layers}, @{$self->objects}; | ||||
|      | ||||
|     # combine fill surfaces to honor the "infill every N layers" option | ||||
|     $status_cb->(70, "Combining infill"); | ||||
|     $_->infill_every_layers for @{$self->objects}; | ||||
|     $_->combine_infill for @{$self->objects}; | ||||
|      | ||||
|     # this will generate extrusion paths for each layer | ||||
|     $status_cb->(80, "Infilling layers"); | ||||
|  | @ -284,13 +284,13 @@ sub export_gcode { | |||
|                 my $fills = shift; | ||||
|                 foreach my $obj_idx (keys %$fills) { | ||||
|                     foreach my $layer_id (keys %{$fills->{$obj_idx}}) { | ||||
|                         @{$self->objects->[$obj_idx]->layers->[$layer_id]->fills} = @{$fills->{$obj_idx}{$layer_id}}; | ||||
|                         $self->objects->[$obj_idx]->layers->[$layer_id]->fills($fills->{$obj_idx}{$layer_id}); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             no_threads_cb => sub { | ||||
|                 foreach my $layer (map @{$_->layers}, @{$self->objects}) { | ||||
|                     @{$layer->fills} = $fill_maker->make_fill($layer); | ||||
|                     $layer->fills([ $fill_maker->make_fill($layer) ]); | ||||
|                 } | ||||
|             }, | ||||
|         ); | ||||
|  | @ -303,7 +303,7 @@ sub export_gcode { | |||
|     } | ||||
|      | ||||
|     # free memory (note that support material needs fill_surfaces) | ||||
|     @{$_->fill_surfaces} = () for map @{$_->layers}, @{$self->objects}; | ||||
|     $_->fill_surfaces(undef) for map @{$_->layers}, @{$self->objects}; | ||||
|      | ||||
|     # make skirt | ||||
|     $status_cb->(88, "Generating skirt"); | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ sub slice { | |||
|             my $lines = shift; | ||||
|             foreach my $layer_id (keys %$lines) { | ||||
|                 my $layer = $self->layer($layer_id); | ||||
|                 $layer->add_line($_) for @{ $lines->{$layer_id} }; | ||||
|                 push @{$layer->lines}, @{$lines->{$layer_id}}; | ||||
|             } | ||||
|         }; | ||||
|         Slic3r::parallelize( | ||||
|  | @ -84,7 +84,7 @@ sub slice { | |||
|      | ||||
|     # remove last layer if empty | ||||
|     # (we might have created it because of the $max_layer = ... + 1 code below) | ||||
|     pop @{$self->layers} if !@{$self->layers->[-1]->surfaces} && !@{$self->layers->[-1]->lines}; | ||||
|     pop @{$self->layers} if !@{$self->layers->[-1]->lines}; | ||||
|      | ||||
|     foreach my $layer (@{ $self->layers }) { | ||||
|         Slic3r::debugf "Making surfaces for layer %d (slice z = %f):\n", | ||||
|  | @ -291,19 +291,17 @@ sub detect_surfaces_type { | |||
|      | ||||
|     # clip surfaces to the fill boundaries | ||||
|     foreach my $layer (@{$self->layers}) { | ||||
|         my $fill_boundaries = [ map @$_, @{$layer->surfaces} ]; | ||||
|         @{$layer->surfaces} = (); | ||||
|         foreach my $surface (@{$layer->slices}) { | ||||
|             my $intersection = intersection_ex( | ||||
|                 [ $surface->p ], | ||||
|                 [ map @$_, @{$layer->fill_boundaries} ], | ||||
|                 $fill_boundaries, | ||||
|             ); | ||||
|             push @{$layer->surfaces}, map Slic3r::Surface->new | ||||
|                 (expolygon => $_, surface_type => $surface->surface_type), | ||||
|                 @$intersection; | ||||
|         } | ||||
|          | ||||
|         # free memory | ||||
|         @{$layer->fill_boundaries} = (); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -394,7 +392,7 @@ sub discover_horizontal_shells { | |||
| } | ||||
| 
 | ||||
| # combine fill surfaces across layers | ||||
| sub infill_every_layers { | ||||
| sub combine_infill { | ||||
|     my $self = shift; | ||||
|     return unless $Slic3r::infill_every_layers > 1 && $Slic3r::fill_density > 0; | ||||
|      | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci