mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Improvements for bottom and top surfaces perimeters
This commit is contained in:
		
							parent
							
								
									a7d5e643ae
								
							
						
					
					
						commit
						34681af6ae
					
				
					 3 changed files with 50 additions and 18 deletions
				
			
		|  | @ -4,6 +4,7 @@ use Moo; | ||||||
| use Math::Clipper ':all'; | use Math::Clipper ':all'; | ||||||
| use Math::ConvexHull qw(convex_hull); | use Math::ConvexHull qw(convex_hull); | ||||||
| use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines); | use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines); | ||||||
|  | use Slic3r::Geometry::Clipper qw(union_ex); | ||||||
| use XXX; | use XXX; | ||||||
| 
 | 
 | ||||||
| use constant PI => 4 * atan2(1, 1); | use constant PI => 4 * atan2(1, 1); | ||||||
|  | @ -77,7 +78,7 @@ has 'fills' => ( | ||||||
| 
 | 
 | ||||||
| sub z { | sub z { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     return $self->id * $Slic3r::layer_height / $Slic3r::resolution; |     return ($self->id * $Slic3r::layer_height + $Slic3r::layer_height/2) / $Slic3r::resolution; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub add_surface { | sub add_surface { | ||||||
|  | @ -209,21 +210,25 @@ sub make_surfaces { | ||||||
|         push @polylines, [@points]; |         push @polylines, [@points]; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     #use Slic3r::SVG; | ||||||
|     #Slic3r::SVG::output(undef, "polylines.svg", |     #Slic3r::SVG::output(undef, "polylines.svg", | ||||||
|     #    polylines => [ @polylines ], |     #    polylines => [ @polylines ], | ||||||
|     #); |     #); | ||||||
|      |     #exit if $self->id == 30; | ||||||
|     #@polylines = map Slic3r::Polyline::Closed->cast($_), @polylines; |  | ||||||
|      |      | ||||||
|     { |     { | ||||||
|         my $clipper = Math::Clipper->new; |         my $expolygons = union_ex([ @polylines ]); | ||||||
|         $clipper->add_subject_polygons([ @polylines ]); |  | ||||||
|         my $expolygons = $clipper->ex_execute(CT_UNION, PFT_NONZERO, PFT_NONZERO); |  | ||||||
|          |          | ||||||
|         Slic3r::debugf "  %d surface(s) detected from %d polylines\n", |         Slic3r::debugf "  %d surface(s) detected from %d polylines\n", | ||||||
|             scalar(@$expolygons), scalar(@polylines); |             scalar(@$expolygons), scalar(@polylines); | ||||||
|         push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons; |         push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons; | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     #use Slic3r::SVG; | ||||||
|  |     #Slic3r::SVG::output(undef, "surfaces.svg", | ||||||
|  |     #    polygons        => [ map $_->contour->p, @{$self->surfaces} ], | ||||||
|  |     #    red_polygons    => [ map $_->p, map @{$_->holes}, @{$self->surfaces} ], | ||||||
|  |     #); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub remove_small_surfaces { | sub remove_small_surfaces { | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ package Slic3r::Print; | ||||||
| use Moo; | use Moo; | ||||||
| 
 | 
 | ||||||
| use Math::Clipper ':all'; | use Math::Clipper ':all'; | ||||||
|  | use Slic3r::Geometry::Clipper qw(diff_ex union_ex); | ||||||
| use XXX; | use XXX; | ||||||
| 
 | 
 | ||||||
| use constant X => 0; | use constant X => 0; | ||||||
|  | @ -83,10 +84,10 @@ sub detect_surfaces_type { | ||||||
|     # prepare a reusable subroutine to make surface differences |     # prepare a reusable subroutine to make surface differences | ||||||
|     my $surface_difference = sub { |     my $surface_difference = sub { | ||||||
|         my ($subject_surfaces, $clip_surfaces, $result_type) = @_; |         my ($subject_surfaces, $clip_surfaces, $result_type) = @_; | ||||||
|         $clipper->clear; |         my $expolygons = diff_ex( | ||||||
|         $clipper->add_subject_polygons([ map $_->p, @$subject_surfaces ]); |             [ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$subject_surfaces ], | ||||||
|         $clipper->add_clip_polygons([ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$clip_surfaces ]); |             [ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$clip_surfaces ], | ||||||
|         my $expolygons = $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO); |         ); | ||||||
|         return grep $_->contour->is_printable, |         return grep $_->contour->is_printable, | ||||||
|             map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type),  |             map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type),  | ||||||
|             @$expolygons; |             @$expolygons; | ||||||
|  | @ -94,6 +95,7 @@ sub detect_surfaces_type { | ||||||
|      |      | ||||||
|     for (my $i = 0; $i < $self->layer_count; $i++) { |     for (my $i = 0; $i < $self->layer_count; $i++) { | ||||||
|         my $layer = $self->layers->[$i]; |         my $layer = $self->layers->[$i]; | ||||||
|  |         Slic3r::debugf "Detecting solid surfaces for layer %d\n", $layer->id; | ||||||
|         my $upper_layer = $self->layers->[$i+1]; |         my $upper_layer = $self->layers->[$i+1]; | ||||||
|         my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef; |         my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef; | ||||||
|          |          | ||||||
|  | @ -103,13 +105,24 @@ sub detect_surfaces_type { | ||||||
|         # of current layer and upper one) |         # of current layer and upper one) | ||||||
|         if ($upper_layer) { |         if ($upper_layer) { | ||||||
|             # offset upper layer surfaces by extrusion_width * perimeters |             # offset upper layer surfaces by extrusion_width * perimeters | ||||||
|             my $upper_surfaces = offset( |             @top = $surface_difference->($layer->surfaces, $upper_layer->surfaces, 'top'); | ||||||
|                 [ map $_->p, @{$upper_layer->surfaces} ], |              | ||||||
|                 ($Slic3r::flow_width / $Slic3r::resolution * $Slic3r::perimeter_offsets), |             # now check whether each resulting top surfaces is large enough to have its | ||||||
|                 $Slic3r::resolution * 100, |             # own perimeters or whether it may be sufficient to use the lower layer's  | ||||||
|                 JT_MITER, 2, |             # perimeters | ||||||
|             ); |              | ||||||
|             @top = $surface_difference->($layer->surfaces, $upper_surfaces, 'top'); |             # offset upper layer's surfaces | ||||||
|  |             my $upper_surfaces_offsetted; | ||||||
|  |             { | ||||||
|  |                 my $distance = $Slic3r::flow_width * ($Slic3r::perimeter_offsets + 1) / $Slic3r::resolution; | ||||||
|  |                 $upper_surfaces_offsetted = offset([ map $_->p, @{$upper_layer->surfaces} ], $distance, 100, JT_MITER, 2); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             @top = grep { | ||||||
|  |                 my $surface = $_; | ||||||
|  |                 my $diff = diff_ex([ map $_->p, $surface ], $upper_surfaces_offsetted); | ||||||
|  |                 @$diff; | ||||||
|  |             } @top; | ||||||
|         } else { |         } else { | ||||||
|             # if no upper layer, all surfaces of this one are solid |             # if no upper layer, all surfaces of this one are solid | ||||||
|             @top = @{$layer->surfaces}; |             @top = @{$layer->surfaces}; | ||||||
|  | @ -120,6 +133,7 @@ sub detect_surfaces_type { | ||||||
|         # of current layer and lower one) |         # of current layer and lower one) | ||||||
|         if ($lower_layer) { |         if ($lower_layer) { | ||||||
|             @bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom'); |             @bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom'); | ||||||
|  |              | ||||||
|             for (@bottom) { |             for (@bottom) { | ||||||
|                 $_->contour->merge_continuous_lines; |                 $_->contour->merge_continuous_lines; | ||||||
|                 $_->contour->remove_acute_vertices; |                 $_->contour->remove_acute_vertices; | ||||||
|  | @ -135,6 +149,18 @@ sub detect_surfaces_type { | ||||||
|             #    red_polygons    => [ map $_->p, @{$lower_layer->surfaces} ], |             #    red_polygons    => [ map $_->p, @{$lower_layer->surfaces} ], | ||||||
|             #); |             #); | ||||||
|              |              | ||||||
|  |             # offset lower layer's surfaces | ||||||
|  |             my $lower_surfaces_offsetted; | ||||||
|  |             { | ||||||
|  |                 my $distance = $Slic3r::flow_width * ($Slic3r::perimeter_offsets + 1) / $Slic3r::resolution; | ||||||
|  |                 $lower_surfaces_offsetted = offset([ map $_->p, @{$lower_layer->surfaces} ], $distance, 100, JT_MITER, 2); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             @bottom = grep { | ||||||
|  |                 my $surface = $_; | ||||||
|  |                 my $diff = diff_ex([ map $_->p, $surface ], $lower_surfaces_offsetted); | ||||||
|  |                 @$diff; | ||||||
|  |             } @bottom; | ||||||
|              |              | ||||||
|         } else { |         } else { | ||||||
|             # if no lower layer, all surfaces of this one are solid |             # if no lower layer, all surfaces of this one are solid | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ sub output { | ||||||
|             my $g = $svg->group( |             my $g = $svg->group( | ||||||
|                 style => { |                 style => { | ||||||
|                     'stroke-width' => 2, |                     'stroke-width' => 2, | ||||||
|                     'stroke' => $colour || 'black', |                     'stroke' => 'black' || $colour || 'black', | ||||||
|                     'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')), |                     'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')), | ||||||
|                 }, |                 }, | ||||||
|             ); |             ); | ||||||
|  | @ -58,6 +58,7 @@ sub output { | ||||||
|                 ); |                 ); | ||||||
|                 $g->$method( |                 $g->$method( | ||||||
|                     %$path, |                     %$path, | ||||||
|  |                     'marker-end' => "url(#endArrow)", | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci