mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	New coverage detection for bridges. Includes implementation of ExPolygon::get_trapezoids()
This commit is contained in:
		
							parent
							
								
									d458a7c4d2
								
							
						
					
					
						commit
						6201aacf88
					
				
					 21 changed files with 358 additions and 27 deletions
				
			
		|  | @ -1,9 +1,9 @@ | |||
| package Slic3r::Layer::BridgeDetector; | ||||
| use Moo; | ||||
| 
 | ||||
| use List::Util qw(first sum max); | ||||
| use List::Util qw(first sum max min); | ||||
| use Slic3r::Geometry qw(PI unscale scaled_epsilon rad2deg epsilon); | ||||
| use Slic3r::Geometry::Clipper qw(intersection_pl intersection_ex); | ||||
| use Slic3r::Geometry::Clipper qw(intersection_pl intersection_ex union); | ||||
| 
 | ||||
| has 'expolygon'         => (is => 'ro', required => 1); | ||||
| has 'lower_slices'      => (is => 'rw', required => 1);  # ExPolygons or ExPolygonCollection | ||||
|  | @ -153,4 +153,61 @@ sub detect_angle { | |||
|     return $self->angle; | ||||
| } | ||||
| 
 | ||||
| sub coverage { | ||||
|     my ($self, $angle) = @_; | ||||
|      | ||||
|     if (!defined $angle) { | ||||
|         return [] if !defined($angle = $self->detect_angle); | ||||
|     } | ||||
|      | ||||
|     # Clone our expolygon and rotate it so that we work with vertical lines. | ||||
|     my $expolygon = $self->expolygon->clone; | ||||
|     $expolygon->rotate(PI/2 - $angle, [0,0]); | ||||
|      | ||||
|     # Outset the bridge expolygon by half the amount we used for detecting anchors; | ||||
|     # we'll use this one to generate our trapezoids and be sure that their vertices | ||||
|     # are inside the anchors and not on their contours leading to false negatives. | ||||
|     my $grown = $expolygon->offset_ex(+$self->extrusion_width/2); | ||||
|      | ||||
|     # Compute trapezoids according to a vertical orientation | ||||
|     my $trapezoids = [ map @{$_->get_trapezoids(PI/2)}, @$grown ]; | ||||
|      | ||||
|     # get anchors and rotate them too | ||||
|     my $anchors = [ map $_->clone, @{$self->_anchors} ]; | ||||
|     $_->rotate(PI/2 - $angle, [0,0]) for @$anchors; | ||||
|      | ||||
|     my @covered = ();  # polygons | ||||
|     foreach my $trapezoid (@$trapezoids) { | ||||
|         my @polylines = map $_->as_polyline, @{$trapezoid->lines}; | ||||
|         my @supported = @{intersection_pl(\@polylines, [map @$_, @$anchors])}; | ||||
|          | ||||
|         if (@supported >= 2) { | ||||
|             push @covered, $trapezoid; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     # merge trapezoids and rotate them back | ||||
|     my $coverage = union(\@covered); | ||||
|     $_->rotate(-(PI/2 - $angle), [0,0]) for @$coverage; | ||||
|      | ||||
|     # intersect trapezoids with actual bridge area to remove extra margins | ||||
|     $coverage = intersection_ex($coverage, [ @{$self->expolygon} ]); | ||||
|      | ||||
|     if (0) { | ||||
|         my @lines = map @{$_->lines}, @$trapezoids; | ||||
|         $_->rotate(-(PI/2 - $angle), [0,0]) for @lines; | ||||
|          | ||||
|         require "Slic3r/SVG.pm"; | ||||
|         Slic3r::SVG::output( | ||||
|             "coverage_" . rad2deg($angle) . ".svg", | ||||
|             expolygons          => [$self->expolygon], | ||||
|             green_expolygons    => $self->_anchors, | ||||
|             red_expolygons      => $coverage, | ||||
|             lines               => \@lines, | ||||
|         ); | ||||
|     } | ||||
|      | ||||
|     return $coverage; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci