mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-20 07:11:12 -06:00 
			
		
		
		
	Stricter implementation of the overhang detection. Includes unit tests
This commit is contained in:
		
							parent
							
								
									caf7b3f97e
								
							
						
					
					
						commit
						a31b2e6ca2
					
				
					 5 changed files with 51 additions and 21 deletions
				
			
		|  | @ -5,7 +5,7 @@ use List::Util qw(min max first); | |||
| use Slic3r::ExtrusionPath ':roles'; | ||||
| use Slic3r::Flow ':roles'; | ||||
| use Slic3r::Geometry qw(epsilon scale unscale scaled_epsilon points_coincide PI X Y B); | ||||
| use Slic3r::Geometry::Clipper qw(union_ex); | ||||
| use Slic3r::Geometry::Clipper qw(union_ex offset_ex); | ||||
| use Slic3r::Surface ':types'; | ||||
| 
 | ||||
| has 'print_config'       => (is => 'ro', default => sub { Slic3r::Config::Print->new }); | ||||
|  | @ -19,7 +19,7 @@ has 'layer'              => (is => 'rw'); | |||
| has 'region'             => (is => 'rw'); | ||||
| has '_layer_islands'     => (is => 'rw'); | ||||
| has '_upper_layer_islands'  => (is => 'rw'); | ||||
| has '_layer_overhangs'   => (is => 'ro', default => sub { Slic3r::ExPolygon::Collection->new }); | ||||
| has '_lower_layer_slices'   => (is => 'ro', default => sub { Slic3r::ExPolygon::Collection->new }); | ||||
| has 'shift_x'            => (is => 'rw', default => sub {0} ); | ||||
| has 'shift_y'            => (is => 'rw', default => sub {0} ); | ||||
| has 'z'                  => (is => 'rw'); | ||||
|  | @ -111,11 +111,15 @@ sub change_layer { | |||
|     # avoid computing islands and overhangs if they're not needed | ||||
|     $self->_layer_islands($layer->islands); | ||||
|     $self->_upper_layer_islands($layer->upper_layer ? $layer->upper_layer->islands : []); | ||||
|     $self->_layer_overhangs->clear; | ||||
|     if ($layer->id > 0 && ($self->print_config->overhangs || $self->print_config->start_perimeters_at_non_overhang)) { | ||||
|         $self->_layer_overhangs->append( | ||||
|     $self->_lower_layer_slices->clear; | ||||
|     if ($layer->lower_layer && ($self->print_config->overhangs || $self->print_config->start_perimeters_at_non_overhang)) { | ||||
|         # We consider overhang any part where the entire nozzle diameter is not supported by the | ||||
|         # lower layer, so we take lower slices and offset them by half the nozzle diameter used  | ||||
|         # in the current layer | ||||
|         my $max_nozzle_diameter = max(map $layer->print->config->get_at('nozzle_diameter', $_->region->config->perimeter_extruder-1), @{$layer->regions}); | ||||
|         $self->_lower_layer_slices->append( | ||||
|             # clone ExPolygons because they come from Surface objects but will be used outside here | ||||
|             map $_->expolygon, map @{$_->slices->filter_by_type(S_TYPE_BOTTOMBRIDGE)}, @{$layer->regions} | ||||
|             @{offset_ex([ map @$_, @{$layer->lower_layer->slices} ], +scale($max_nozzle_diameter/2))}, | ||||
|         ); | ||||
|     } | ||||
|     if ($self->print_config->avoid_crossing_perimeters) { | ||||
|  | @ -205,7 +209,7 @@ sub extrude_loop { | |||
|     } | ||||
|     my @candidates = (); | ||||
|     if ($self->print_config->start_perimeters_at_non_overhang) { | ||||
|         @candidates = grep !$self->_layer_overhangs->contains_point($_), @concave; | ||||
|         @candidates = grep $self->_lower_layer_slices->contains_point($_), @concave; | ||||
|     } | ||||
|     if (!@candidates) { | ||||
|         # if none, look for any concave vertex | ||||
|  | @ -213,7 +217,7 @@ sub extrude_loop { | |||
|         if (!@candidates) { | ||||
|             # if none, look for any non-overhang vertex | ||||
|             if ($self->print_config->start_perimeters_at_non_overhang) { | ||||
|                 @candidates = grep !$self->_layer_overhangs->contains_point($_), @$polygon; | ||||
|                 @candidates = grep $self->_lower_layer_slices->contains_point($_), @$polygon; | ||||
|             } | ||||
|             if (!@candidates) { | ||||
|                 # if none, all points are valid candidates | ||||
|  | @ -243,14 +247,16 @@ sub extrude_loop { | |||
|      | ||||
|     my @paths = (); | ||||
|     # detect overhanging/bridging perimeters | ||||
|     if ($self->layer->print->config->overhangs && $extrusion_path->is_perimeter && $self->_layer_overhangs->count > 0) { | ||||
|         # get non-overhang paths by subtracting overhangs from the loop | ||||
|     if ($self->layer->print->config->overhangs && $extrusion_path->is_perimeter && $self->_lower_layer_slices->count > 0) { | ||||
|         # get non-overhang paths by intersecting this loop with the grown lower slices | ||||
|         push @paths, | ||||
|             map $_->clone, | ||||
|             @{$extrusion_path->subtract_expolygons($self->_layer_overhangs)}; | ||||
|             @{$extrusion_path->intersect_expolygons($self->_lower_layer_slices)}; | ||||
|          | ||||
|         # get overhang paths by intersecting overhangs with the loop | ||||
|         foreach my $path (@{$extrusion_path->intersect_expolygons($self->_layer_overhangs)}) { | ||||
|         # get overhang paths by checking what parts of this loop fall  | ||||
|         # outside the grown lower slices (thus where the distance between | ||||
|         # the loop centerline and original lower slices is >= half nozzle diameter | ||||
|         foreach my $path (@{$extrusion_path->subtract_expolygons($self->_lower_layer_slices)}) { | ||||
|             $path = $path->clone; | ||||
|             $path->role(EXTR_ROLE_OVERHANG_PERIMETER); | ||||
|             $path->mm3_per_mm($self->region->flow(FLOW_ROLE_PERIMETER, -1, 1, 0, undef, $self->layer->object)->mm3_per_mm(-1)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci