mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Smarter ordering of brim loops. #687
This commit is contained in:
		
							parent
							
								
									855ba90332
								
							
						
					
					
						commit
						4aad2f6243
					
				
					 2 changed files with 39 additions and 8 deletions
				
			
		|  | @ -6,7 +6,7 @@ require Exporter; | ||||||
| our @ISA = qw(Exporter); | our @ISA = qw(Exporter); | ||||||
| our @EXPORT_OK = qw(safety_offset safety_offset_ex offset offset_ex collapse_ex | our @EXPORT_OK = qw(safety_offset safety_offset_ex offset offset_ex collapse_ex | ||||||
|     diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND |     diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND | ||||||
|     JT_SQUARE is_counter_clockwise); |     JT_SQUARE is_counter_clockwise union_pt); | ||||||
| 
 | 
 | ||||||
| use Math::Clipper 1.17 qw(:cliptypes :polyfilltypes :jointypes is_counter_clockwise area); | use Math::Clipper 1.17 qw(:cliptypes :polyfilltypes :jointypes is_counter_clockwise area); | ||||||
| use Slic3r::Geometry qw(scale); | use Slic3r::Geometry qw(scale); | ||||||
|  | @ -78,6 +78,14 @@ sub union_ex { | ||||||
|     ]; |     ]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | sub union_pt { | ||||||
|  |     my ($polygons, $jointype, $safety_offset) = @_; | ||||||
|  |     $jointype = PFT_NONZERO unless defined $jointype; | ||||||
|  |     $clipper->clear; | ||||||
|  |     $clipper->add_subject_polygons($safety_offset ? safety_offset($polygons) : $polygons); | ||||||
|  |     return $clipper->pt_execute(CT_UNION, $jointype, $jointype); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| sub intersection_ex { | sub intersection_ex { | ||||||
|     my ($subject, $clip, $jointype, $safety_offset) = @_; |     my ($subject, $clip, $jointype, $safety_offset) = @_; | ||||||
|     $jointype = PFT_NONZERO unless defined $jointype; |     $jointype = PFT_NONZERO unless defined $jointype; | ||||||
|  |  | ||||||
|  | @ -6,8 +6,8 @@ use File::Spec; | ||||||
| use List::Util qw(max first); | use List::Util qw(max first); | ||||||
| use Math::ConvexHull::MonotoneChain qw(convex_hull); | use Math::ConvexHull::MonotoneChain qw(convex_hull); | ||||||
| use Slic3r::ExtrusionPath ':roles'; | use Slic3r::ExtrusionPath ':roles'; | ||||||
| use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point); | use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point chained_path_items); | ||||||
| use Slic3r::Geometry::Clipper qw(diff_ex union_ex intersection_ex offset JT_ROUND JT_SQUARE); | use Slic3r::Geometry::Clipper qw(diff_ex union_ex union_pt intersection_ex offset JT_ROUND JT_SQUARE PFT_EVENODD); | ||||||
| use Time::HiRes qw(gettimeofday tv_interval); | use Time::HiRes qw(gettimeofday tv_interval); | ||||||
| 
 | 
 | ||||||
| has 'config'                 => (is => 'rw', default => sub { Slic3r::Config->new_from_defaults }, trigger => 1); | has 'config'                 => (is => 'rw', default => sub { Slic3r::Config->new_from_defaults }, trigger => 1); | ||||||
|  | @ -673,16 +673,39 @@ sub make_brim { | ||||||
|         push @islands, map $_->unpack->split_at_first_point->polyline->grow($grow_distance), @{$self->skirt}; |         push @islands, map $_->unpack->split_at_first_point->polyline->grow($grow_distance), @{$self->skirt}; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     my @loops = (); | ||||||
|     my $num_loops = sprintf "%.0f", $Slic3r::Config->brim_width / $flow->width; |     my $num_loops = sprintf "%.0f", $Slic3r::Config->brim_width / $flow->width; | ||||||
|     for my $i (reverse 1 .. $num_loops) { |     for my $i (reverse 1 .. $num_loops) { | ||||||
|         # JT_SQUARE ensures no vertex is outside the given offset distance |         # JT_SQUARE ensures no vertex is outside the given offset distance | ||||||
|         push @{$self->brim}, Slic3r::ExtrusionLoop->pack( |         # -0.5 because islands are not represented by their centerlines | ||||||
|             polygon         => Slic3r::Polygon->new($_), |  | ||||||
|             role            => EXTR_ROLE_SKIRT, |  | ||||||
|             flow_spacing    => $flow->spacing, |  | ||||||
|         ) for Slic3r::Geometry::Clipper::offset(\@islands, ($i - 0.5) * $flow->scaled_spacing, undef, JT_SQUARE); # -0.5 because islands are not represented by their centerlines |  | ||||||
|         # TODO: we need the offset inwards/offset outwards logic to avoid overlapping extrusions |         # TODO: we need the offset inwards/offset outwards logic to avoid overlapping extrusions | ||||||
|  |         push @loops, offset(\@islands, ($i - 0.5) * $flow->scaled_spacing, undef, JT_SQUARE); | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     # prepare a subroutine to traverse the tree and return inner perimeters first | ||||||
|  |     my $traverse; | ||||||
|  |     $traverse = sub { | ||||||
|  |         my ($loops) = @_; | ||||||
|  |          | ||||||
|  |         # use a nearest neighbor search to order these children | ||||||
|  |         # TODO: supply second argument to chained_path_items() too? | ||||||
|  |         @$loops = @{chained_path_items( | ||||||
|  |             [ map [ ($_->{outer} ? $_->{outer}[0] : $_->{hole}[0]), $_ ], @$loops ], | ||||||
|  |         )}; | ||||||
|  |          | ||||||
|  |         my @polygons = (); | ||||||
|  |         foreach my $loop (@$loops) { | ||||||
|  |             push @polygons, $traverse->($loop->{children}); | ||||||
|  |             push @polygons, Slic3r::ExtrusionLoop->pack( | ||||||
|  |                 polygon         => Slic3r::Polygon->new($loop->{outer} // [ reverse @{$loop->{hole}} ]), | ||||||
|  |                 role            => EXTR_ROLE_SKIRT, | ||||||
|  |                 flow_spacing    => $flow->spacing, | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         return @polygons; | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     @{$self->brim} = reverse $traverse->( union_pt(\@loops, PFT_EVENODD) ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub write_gcode { | sub write_gcode { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci