mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Don't store ->surfaces anymore. Save memory, save time
This commit is contained in:
		
							parent
							
								
									5930267de9
								
							
						
					
					
						commit
						15f07197d8
					
				
					 3 changed files with 19 additions and 46 deletions
				
			
		|  | @ -32,13 +32,7 @@ has 'thin_walls' => (is => 'rw', default => sub { [] }); | |||
| # need to be filled with a medial axis | ||||
| has 'thin_fills' => (is => 'rw', 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', 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 | ||||
| # collection of surfaces for infill generation | ||||
| has 'fill_surfaces' => (is => 'rw', default => sub { [] }); | ||||
| 
 | ||||
| # ordered collection of extrusion paths/loops to build all perimeters | ||||
|  | @ -160,7 +154,7 @@ sub make_perimeters { | |||
|     ])}; | ||||
|      | ||||
|     $self->perimeters([]); | ||||
|     $self->surfaces([]); | ||||
|     $self->fill_surfaces([]); | ||||
|     $self->thin_fills([]); | ||||
|      | ||||
|     # for each island: | ||||
|  | @ -227,9 +221,14 @@ sub make_perimeters { | |||
|          | ||||
|         # create one more offset to be used as boundary for fill | ||||
|         { | ||||
|             my @fill_boundaries = map $_->offset_ex(-$distance), @last_offsets; | ||||
|             my @fill_boundaries = @{union_ex([ | ||||
|                 Slic3r::Geometry::Clipper::offset( | ||||
|                     [Slic3r::Geometry::Clipper::offset([ map @$_, @last_offsets ], -1.5*$distance)],  | ||||
|                     +0.5*$distance, | ||||
|                 ), | ||||
|             ])}; | ||||
|             $_->simplify(&Slic3r::SCALED_RESOLUTION) for @fill_boundaries; | ||||
|             push @{ $self->surfaces }, @fill_boundaries; | ||||
|             push @{ $self->fill_surfaces }, @fill_boundaries; | ||||
|         } | ||||
|          | ||||
|         # fill gaps | ||||
|  | @ -390,48 +389,26 @@ sub _add_perimeter { | |||
| sub prepare_fill_surfaces { | ||||
|     my $self = shift; | ||||
|      | ||||
|     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::Config->top_solid_layers == 0) { | ||||
|         $_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type == S_TYPE_TOP, @surfaces; | ||||
|         $_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type == S_TYPE_TOP, @{$self->fill_surfaces}; | ||||
|     } | ||||
|     if ($Slic3r::Config->bottom_solid_layers == 0) { | ||||
|         $_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type == S_TYPE_BOTTOM, @surfaces; | ||||
|         $_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type == S_TYPE_BOTTOM, @{$self->fill_surfaces}; | ||||
|     } | ||||
|      | ||||
|     # if hollow object is requested, remove internal surfaces | ||||
|     if ($Slic3r::Config->fill_density == 0) { | ||||
|         @surfaces = grep $_->surface_type != S_TYPE_INTERNAL, @surfaces; | ||||
|     } | ||||
|      | ||||
|     # remove unprintable regions (they would slow down the infill process and also cause | ||||
|     # some weird failures during bridge neighbor detection) | ||||
|     { | ||||
|         my $distance = $self->infill_flow->scaled_spacing / 2; | ||||
|         @surfaces = map { | ||||
|             my $surface = $_; | ||||
|              | ||||
|             # offset inwards | ||||
|             my @offsets = $surface->expolygon->offset_ex(-$distance); | ||||
|             @offsets = @{union_ex([ Slic3r::Geometry::Clipper::offset([ map @$_, @offsets ], $distance)] )}; # isn't the union_ex useless? | ||||
|             map Slic3r::Surface->new( | ||||
|                 expolygon => $_, | ||||
|                 surface_type => $surface->surface_type, | ||||
|             ), @offsets; | ||||
|         } @surfaces; | ||||
|         @{$self->fill_surfaces} = grep $_->surface_type != S_TYPE_INTERNAL, @{$self->fill_surfaces}; | ||||
|     } | ||||
|          | ||||
|     # turn too small internal regions into solid regions | ||||
|     { | ||||
|         my $min_area = scale scale $Slic3r::Config->solid_infill_below_area; # scaling an area requires two calls! | ||||
|         my @small = grep $_->surface_type == S_TYPE_INTERNAL && $_->expolygon->contour->area <= $min_area, @surfaces; | ||||
|         my @small = grep $_->surface_type == S_TYPE_INTERNAL && $_->expolygon->contour->area <= $min_area, @{$self->fill_surfaces}; | ||||
|         $_->surface_type(S_TYPE_INTERNALSOLID) for @small; | ||||
|         Slic3r::debugf "identified %d small solid surfaces at layer %d\n", scalar(@small), $self->id if @small > 0; | ||||
|     } | ||||
|      | ||||
|     $self->fill_surfaces([@surfaces]); | ||||
| } | ||||
| 
 | ||||
| # make bridges printable | ||||
|  |  | |||
|  | @ -345,8 +345,8 @@ sub export_gcode { | |||
|             for @{$layer->slices}, (map $_->expolygon, map @{$_->slices}, @{$layer->regions}); | ||||
|     } | ||||
|      | ||||
|     # this will clip $layer->surfaces to the infill boundaries  | ||||
|     # and split them in top/bottom/internal surfaces; | ||||
|     # this will transform $layer->fill_surfaces from expolygon  | ||||
|     # to typed top/bottom/internal surfaces; | ||||
|     $status_cb->(30, "Detecting solid surfaces"); | ||||
|     $_->detect_surfaces_type for @{$self->objects}; | ||||
|      | ||||
|  | @ -364,9 +364,6 @@ sub export_gcode { | |||
|     $status_cb->(60, "Generating horizontal shells"); | ||||
|     $_->discover_horizontal_shells for @{$self->objects}; | ||||
|      | ||||
|     # free memory | ||||
|     $_->surfaces(undef) for map @{$_->regions}, map @{$_->layers}, @{$self->objects}; | ||||
|      | ||||
|     # combine fill surfaces to honor the "infill every N layers" option | ||||
|     $status_cb->(70, "Combining infill"); | ||||
|     $_->combine_infill for @{$self->objects}; | ||||
|  |  | |||
|  | @ -304,14 +304,14 @@ sub detect_surfaces_type { | |||
|         # clip surfaces to the fill boundaries | ||||
|         foreach my $layer (@{$self->layers}) { | ||||
|             my $layerm = $layer->regions->[$region_id]; | ||||
|             my $fill_boundaries = [ map @$_, @{$layerm->surfaces} ]; | ||||
|             @{$layerm->surfaces} = (); | ||||
|             my $fill_boundaries = [ map @$_, @{$layerm->fill_surfaces} ]; | ||||
|             @{$layerm->fill_surfaces} = (); | ||||
|             foreach my $surface (@{$layerm->slices}) { | ||||
|                 my $intersection = intersection_ex( | ||||
|                     [ $surface->p ], | ||||
|                     $fill_boundaries, | ||||
|                 ); | ||||
|                 push @{$layerm->surfaces}, map Slic3r::Surface->new | ||||
|                 push @{$layerm->fill_surfaces}, map Slic3r::Surface->new | ||||
|                     (expolygon => $_, surface_type => $surface->surface_type), | ||||
|                     @$intersection; | ||||
|             } | ||||
|  | @ -352,14 +352,13 @@ sub discover_horizontal_shells { | |||
|                     next if $n < 0 || $n >= $self->layer_count; | ||||
|                     Slic3r::debugf "  looking for neighbors on layer %d...\n", $n; | ||||
|                      | ||||
|                     my @neighbor_surfaces       = @{$self->layers->[$n]->regions->[$region_id]->surfaces}; | ||||
|                     my @neighbor_fill_surfaces  = @{$self->layers->[$n]->regions->[$region_id]->fill_surfaces}; | ||||
|                      | ||||
|                     # find intersection between neighbor and current layer's surfaces | ||||
|                     # intersections have contours and holes | ||||
|                     my $new_internal_solid = intersection_ex( | ||||
|                         $surfaces_p, | ||||
|                         [ map $_->p, grep { $_->surface_type == S_TYPE_INTERNAL || $_->surface_type == S_TYPE_INTERNALSOLID } @neighbor_surfaces ], | ||||
|                         [ map $_->p, grep { $_->surface_type == S_TYPE_INTERNAL || $_->surface_type == S_TYPE_INTERNALSOLID } @neighbor_fill_surfaces ], | ||||
|                         undef, 1, | ||||
|                     ); | ||||
|                     next if !@$new_internal_solid; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci