mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-29 19:53:44 -06:00 
			
		
		
		
	Large refactoring. Cleaner logic, smaller memory footprint.
This commit is contained in:
		
							parent
							
								
									13ef24b5eb
								
							
						
					
					
						commit
						8598b66b0a
					
				
					 6 changed files with 178 additions and 247 deletions
				
			
		|  | @ -29,20 +29,6 @@ has 'surfaces' => ( | |||
|     default => sub { [] }, | ||||
| ); | ||||
| 
 | ||||
| # collection of surfaces representing bridges | ||||
| has 'bridges' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[Slic3r::Surface]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| 
 | ||||
| # collection of surfaces to make perimeters for | ||||
| has 'perimeter_surfaces' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[Slic3r::Surface]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| 
 | ||||
| # ordered collection of extrusion paths to build all perimeters | ||||
| has 'perimeters' => ( | ||||
|     is      => 'rw', | ||||
|  | @ -58,10 +44,10 @@ has 'skirts' => ( | |||
| ); | ||||
| 
 | ||||
| # collection of surfaces generated by offsetting the innermost perimeter(s) | ||||
| # they represent boundaries of areas to fill (grouped by original objects) | ||||
| has 'fill_surfaces' => ( | ||||
| # they represent boundaries of areas to fill | ||||
| has 'fill_boundaries' => ( | ||||
|     is      => 'rw', | ||||
|     #isa     => 'ArrayRef[ArrayRef[Slic3r::Surface]]', | ||||
|     #isa     => 'ArrayRef[Slic3r::Surface]', | ||||
|     default => sub { [] }, | ||||
| ); | ||||
| 
 | ||||
|  | @ -352,6 +338,8 @@ sub remove_small_perimeters { | |||
| sub process_bridges { | ||||
|     my $self = shift; | ||||
|      | ||||
|     my @bridges = (); | ||||
|      | ||||
|     # a bottom surface on a layer > 0 is either a bridge or a overhang  | ||||
|     # or a combination of both; any top surface is a candidate for | ||||
|     # reverse bridge processing | ||||
|  | @ -426,8 +414,8 @@ sub process_bridges { | |||
|          | ||||
|         # now, extend our bridge by taking a portion of supporting surfaces | ||||
|         { | ||||
|             # offset the bridge by the specified amount of mm | ||||
|             my $bridge_overlap = 2 * $Slic3r::perimeters * $Slic3r::flow_width / $Slic3r::resolution; | ||||
|             # offset the bridge by the specified amount of mm (minimum 3) | ||||
|             my $bridge_overlap = 3 / $Slic3r::resolution; | ||||
|             my ($bridge_offset) = $expolygon->contour->offset($bridge_overlap, $Slic3r::resolution * 100, JT_MITER, 2); | ||||
|              | ||||
|             # calculate the new bridge | ||||
|  | @ -436,7 +424,7 @@ sub process_bridges { | |||
|                 [ $bridge_offset ], | ||||
|             ); | ||||
|              | ||||
|             push @{$self->bridges}, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|             push @bridges, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|                 surface_type => $surface->surface_type, | ||||
|                 bridge_angle => $bridge_angle, | ||||
|             ), @$intersection; | ||||
|  | @ -446,86 +434,52 @@ sub process_bridges { | |||
|     # now we need to merge bridges to avoid overlapping | ||||
|     { | ||||
|         # build a list of unique bridge types | ||||
|         my @surface_groups = Slic3r::Surface->group(@{$self->bridges}); | ||||
|         my @surface_groups = Slic3r::Surface->group(@bridges); | ||||
|          | ||||
|         # merge bridges of the same type, removing any of the bridges already merged; | ||||
|         # the order of @surface_groups determines the priority between bridges having  | ||||
|         # different surface_type or bridge_angle | ||||
|         @{$self->bridges} = (); | ||||
|         @bridges = (); | ||||
|         foreach my $surfaces (@surface_groups) { | ||||
|             my $union = union_ex([ map $_->p, @$surfaces ]); | ||||
|             my $diff = diff_ex( | ||||
|                 [ map @$_, @$union ], | ||||
|                 [ map $_->p, @{$self->bridges} ], | ||||
|                 [ map $_->p, @bridges ], | ||||
|             ); | ||||
|              | ||||
|             push @{$self->bridges}, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|             push @bridges, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|                 surface_type => $surfaces->[0]->surface_type, | ||||
|                 bridge_angle => $surfaces->[0]->bridge_angle, | ||||
|             ), @$union; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| # generates a set of surfaces that will be used to make perimeters | ||||
| # thus, we need to merge internal surfaces and bridges | ||||
| sub detect_perimeter_surfaces { | ||||
|     my $self = shift; | ||||
|      | ||||
|     # little optimization: skip the Clipper UNION if we have no bridges | ||||
|     if (!@{$self->bridges}) { | ||||
|         push @{$self->perimeter_surfaces}, @{$self->surfaces}; | ||||
|     } else { | ||||
|         my $union = union_ex([ | ||||
|             (map $_->p, grep $_->surface_type =~ /internal/, @{$self->surfaces}), | ||||
|             (map $_->p, @{$self->bridges}), | ||||
|         ]); | ||||
|     # apply bridges to layer | ||||
|     { | ||||
|         my @surfaces = @{$self->surfaces}; | ||||
|         @{$self->surfaces} = (); | ||||
|          | ||||
|         # schedule perimeters for internal surfaces merged with bridges | ||||
|         push @{$self->perimeter_surfaces},  | ||||
|             map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'),  | ||||
|             @$union; | ||||
|          | ||||
|         # schedule perimeters for the remaining surfaces | ||||
|         foreach my $type (qw(top bottom)) { | ||||
|             my $diff = diff_ex( | ||||
|                 [ map $_->p, grep $_->surface_type eq $type, @{$self->surfaces} ], | ||||
|                 [ map @$_, @$union ], | ||||
|             ); | ||||
|             push @{$self->perimeter_surfaces},  | ||||
|                 map Slic3r::Surface->cast_from_expolygon($_, surface_type => $type),  | ||||
|                 @$diff; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| # splits fill_surfaces in internal and bridge surfaces | ||||
| sub split_bridges_fills { | ||||
|     my $self = shift; | ||||
|      | ||||
|     foreach my $surfaces (@{$self->fill_surfaces}) { | ||||
|         my @surfaces = @$surfaces; | ||||
|         @$surfaces = (); | ||||
|          | ||||
|         # intersect fill_surfaces with bridges to get actual bridges | ||||
|         foreach my $bridge (@{$self->bridges}) { | ||||
|             my $intersection = intersection_ex( | ||||
|         # intersect layer surfaces with bridges to get actual bridges | ||||
|         foreach my $bridge (@bridges) { | ||||
|             my $actual_bridge = intersection_ex( | ||||
|                 [ map $_->p, @surfaces ], | ||||
|                 [ $bridge->p ], | ||||
|             ); | ||||
|              | ||||
|             push @$surfaces, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|             push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|                 surface_type => $bridge->surface_type, | ||||
|                 bridge_angle => $bridge->bridge_angle, | ||||
|             ), @$intersection; | ||||
|             ), @$actual_bridge; | ||||
|         } | ||||
|          | ||||
|         # difference between fill_surfaces and bridges are the other surfaces | ||||
|         foreach my $type (qw(top bottom internal internal-solid)) { | ||||
|             my @my_surfaces = grep $_->surface_type eq $type, @surfaces; | ||||
|             my $difference = diff_ex([ map $_->p, @my_surfaces ], [ map $_->p, @{$self->bridges} ]); | ||||
|             push @$surfaces, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|                 surface_type => $type), @$difference; | ||||
|         # difference between layer surfaces and bridges are the other surfaces | ||||
|         foreach my $group (Slic3r::Surface->group(@surfaces)) { | ||||
|             my $difference = diff_ex( | ||||
|                 [ map $_->p, @$group ], | ||||
|                 [ map $_->p, @bridges ], | ||||
|             ); | ||||
|             push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, | ||||
|                 surface_type => $group->[0]->surface_type), @$difference; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci