mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			129 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| package Slic3r::ExtrusionPath;
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| use parent qw(Exporter);
 | |
| 
 | |
| our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_EXTERNAL_PERIMETER 
 | |
|     EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER EXTR_ROLE_OVERHANG_PERIMETER
 | |
|     EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL EXTR_ROLE_TOPSOLIDFILL EXTR_ROLE_BRIDGE 
 | |
|     EXTR_ROLE_INTERNALBRIDGE EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_GAPFILL);
 | |
| our %EXPORT_TAGS = (roles => \@EXPORT_OK);
 | |
| 
 | |
| use Slic3r::Geometry qw(PI X Y epsilon deg2rad rotate_points);
 | |
| 
 | |
| sub clip_with_polygon {
 | |
|     my $self = shift;
 | |
|     my ($polygon) = @_;
 | |
|     
 | |
|     return $self->clip_with_expolygon(Slic3r::ExPolygon->new($polygon));
 | |
| }
 | |
| 
 | |
| sub clip_with_expolygon {
 | |
|     my $self = shift;
 | |
|     my ($expolygon) = @_;
 | |
|     
 | |
|     return map $self->clone(polyline => $_),
 | |
|         $self->polyline->clip_with_expolygon($expolygon);
 | |
| }
 | |
| 
 | |
| sub intersect_expolygons {
 | |
|     my $self = shift;
 | |
|     my ($expolygons) = @_;
 | |
|     
 | |
|     return map $self->clone(polyline => Slic3r::Polyline->new(@$_)),
 | |
|         @{Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection([ map $_->pp, @$expolygons ], [$self->pp])};
 | |
| }
 | |
| 
 | |
| sub subtract_expolygons {
 | |
|     my $self = shift;
 | |
|     my ($expolygons) = @_;
 | |
|     
 | |
|     return map $self->clone(polyline => Slic3r::Polyline->new(@$_)),
 | |
|         @{Boost::Geometry::Utils::multi_linestring_multi_polygon_difference([$self->pp], [ map $_->pp, @$expolygons ])};
 | |
| }
 | |
| 
 | |
| sub simplify {
 | |
|     my $self = shift;
 | |
|     $self->polyline($self->polyline->simplify(@_));
 | |
| }
 | |
| 
 | |
| sub clip_end {
 | |
|     my $self = shift;
 | |
|     my $polyline = $self->polyline;
 | |
|     $polyline->clip_end(@_);
 | |
|     $self->polyline($polyline);
 | |
| }
 | |
| 
 | |
| sub length {
 | |
|     my $self = shift;
 | |
|     return $self->polyline->length;
 | |
| }
 | |
| 
 | |
| sub points {
 | |
|     my $self = shift;
 | |
|     return $self->polyline;
 | |
| }
 | |
| 
 | |
| sub last_point {
 | |
|     my $self = shift;
 | |
|     return $self->polyline->[-1];
 | |
| }
 | |
| 
 | |
| sub is_perimeter {
 | |
|     my $self = shift;
 | |
|     return $self->role == EXTR_ROLE_PERIMETER
 | |
|         || $self->role == EXTR_ROLE_EXTERNAL_PERIMETER
 | |
|         || $self->role == EXTR_ROLE_OVERHANG_PERIMETER
 | |
|         || $self->role == EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER;
 | |
| }
 | |
| 
 | |
| sub is_fill {
 | |
|     my $self = shift;
 | |
|     return $self->role == EXTR_ROLE_FILL
 | |
|         || $self->role == EXTR_ROLE_SOLIDFILL
 | |
|         || $self->role == EXTR_ROLE_TOPSOLIDFILL;
 | |
| }
 | |
| 
 | |
| sub is_bridge {
 | |
|     my $self = shift;
 | |
|     return $self->role == EXTR_ROLE_BRIDGE
 | |
|         || $self->role == EXTR_ROLE_INTERNALBRIDGE
 | |
|         || $self->role == EXTR_ROLE_OVERHANG_PERIMETER;
 | |
| }
 | |
| 
 | |
| sub split_at_acute_angles {
 | |
|     my $self = shift;
 | |
|     
 | |
|     # calculate angle limit
 | |
|     my $angle_limit = abs(Slic3r::Geometry::deg2rad(40));
 | |
|     my @points = @{$self->p};
 | |
|     
 | |
|     my @paths = ();
 | |
|     
 | |
|     # take first two points
 | |
|     my @p = splice @points, 0, 2;
 | |
|     
 | |
|     # loop until we have one spare point
 | |
|     while (my $p3 = shift @points) {
 | |
|         my $angle = abs(Slic3r::Geometry::angle3points($p[-1], $p[-2], $p3));
 | |
|         $angle = 2*PI - $angle if $angle > PI;
 | |
|         
 | |
|         if ($angle < $angle_limit) {
 | |
|             # if the angle between $p[-2], $p[-1], $p3 is too acute
 | |
|             # then consider $p3 only as a starting point of a new
 | |
|             # path and stop the current one as it is
 | |
|             push @paths, $self->clone(polyline => Slic3r::Polyline->new(@p));
 | |
|             @p = ($p3);
 | |
|             push @p, grep $_, shift @points or last;
 | |
|         } else {
 | |
|             push @p, $p3;
 | |
|         }
 | |
|     }
 | |
|     push @paths, $self->clone(polyline => Slic3r::Polyline->new(@p))
 | |
|         if @p > 1;
 | |
|     
 | |
|     return @paths;
 | |
| }
 | |
| 
 | |
| 1;
 | 
