mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Port offset_ex() and offset2_ex() to XS
This commit is contained in:
		
							parent
							
								
									9458c7db97
								
							
						
					
					
						commit
						898007fc36
					
				
					 20 changed files with 4349 additions and 52 deletions
				
			
		|  | @ -51,12 +51,12 @@ sub offset { | |||
| 
 | ||||
| sub offset_ex { | ||||
|     my $self = shift; | ||||
|     return Slic3r::Geometry::Clipper::offset_ex($self, @_); | ||||
|     return Slic3r::Geometry::Clipper::offset_ex(\@$self, @_); | ||||
| } | ||||
| 
 | ||||
| sub safety_offset { | ||||
|     my $self = shift; | ||||
|     return Slic3r::Geometry::Clipper::safety_offset_ex($self, @_); | ||||
|     return Slic3r::Geometry::Clipper::safety_offset_ex(\@$self, @_); | ||||
| } | ||||
| 
 | ||||
| sub noncollapsing_offset_ex { | ||||
|  | @ -69,7 +69,7 @@ sub noncollapsing_offset_ex { | |||
| sub encloses_point { | ||||
|     my $self = shift; | ||||
|     my ($point) = @_; | ||||
|     return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, $self->pp); | ||||
|     return Boost::Geometry::Utils::point_covered_by_polygon($point->pp, $self->pp); | ||||
| } | ||||
| 
 | ||||
| # A version of encloses_point for use when hole borders do not matter. | ||||
|  | @ -78,7 +78,7 @@ sub encloses_point { | |||
| sub encloses_point_quick { | ||||
|     my $self = shift; | ||||
|     my ($point) = @_; | ||||
|     return Boost::Geometry::Utils::point_within_polygon($point->arrayref, $self->arrayref); | ||||
|     return Boost::Geometry::Utils::point_within_polygon($point->pp, $self->pp); | ||||
| } | ||||
| 
 | ||||
| sub encloses_line { | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ sub fill_surface { | |||
|         # clip paths again to prevent connection segments from crossing the expolygon boundaries | ||||
|         @paths = map Slic3r::Polyline->new(@$_), | ||||
|             @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection( | ||||
|                 [ map $_->pp, $surface->expolygon->offset_ex(scaled_epsilon) ], | ||||
|                 [ map $_->pp, @{$surface->expolygon->offset_ex(scaled_epsilon)} ], | ||||
|                 [ map $_->pp, @paths ], | ||||
|             ) } if @paths;  # this temporary check is a workaround for the multilinestring bug in B::G::U | ||||
|     } | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ sub fill_surface { | |||
|     my $rotate_vector = $self->infill_direction($surface); | ||||
|     $self->rotate_points($expolygon, $rotate_vector); | ||||
|      | ||||
|     my ($expolygon_off) = $expolygon->offset_ex(scale $params{flow_spacing}/2); | ||||
|     my $expolygon_off = $expolygon->offset_ex(scale $params{flow_spacing}/2)->[0]; | ||||
|     return {} if !defined $expolygon_off;  # skip some very small polygons (which shouldn't arrive here) | ||||
|      | ||||
|     my $flow_spacing = $params{flow_spacing}; | ||||
|  | @ -67,7 +67,7 @@ sub fill_surface { | |||
|     # are kept even if the expolygon has vertical sides | ||||
|     my @polylines = map Slic3r::Polyline->new(@$_), | ||||
|         @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection( | ||||
|             [ map $_->pp, $expolygon->offset_ex(scaled_epsilon) ], | ||||
|             [ map $_->pp, @{ $expolygon->offset_ex(scaled_epsilon) } ], | ||||
|             [ map $_->pp, @{ $self->cache->{$cache_id} } ], | ||||
|         ) }; | ||||
|      | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ sub BUILD { | |||
|         # so that no motion along external perimeters happens | ||||
|         $self->_inner->[$i] = $self->no_internal | ||||
|             ? [] | ||||
|             : [ $self->islands->[$i]->offset_ex(-$self->_inner_margin) ]; | ||||
|             : $self->islands->[$i]->offset_ex(-$self->_inner_margin); | ||||
|          | ||||
|         # offset the island outwards to make the boundaries for external movements | ||||
|         $self->_outer->[$i] = [ offset([ $self->islands->[$i]->contour], $self->_outer_margin) ]; | ||||
|  |  | |||
|  | @ -45,26 +45,6 @@ sub offset2 { | |||
|     return @$offsets; | ||||
| } | ||||
| 
 | ||||
| sub offset_ex { | ||||
|     my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_; | ||||
|     $scale      ||= 100000; | ||||
|     $joinType   //= JT_MITER; | ||||
|     $miterLimit //= 3; | ||||
|      | ||||
|     my $offsets = Math::Clipper::ex_int_offset(_convert($polygons), $distance, $scale, $joinType, $miterLimit); | ||||
|     return map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}), @$offsets; | ||||
| } | ||||
| 
 | ||||
| sub offset2_ex { | ||||
|     my ($polygons, $delta1, $delta2, $scale, $joinType, $miterLimit) = @_; | ||||
|     $scale      ||= 100000; | ||||
|     $joinType   //= JT_MITER; | ||||
|     $miterLimit //= 3; | ||||
|      | ||||
|     my $offsets = Math::Clipper::ex_int_offset2(_convert($polygons), $delta1, $delta2, $scale, $joinType, $miterLimit); | ||||
|     return map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}), @$offsets; | ||||
| } | ||||
| 
 | ||||
| sub diff_ex { | ||||
|     my ($subject, $clip, $safety_offset) = @_; | ||||
|      | ||||
|  | @ -147,7 +127,7 @@ sub xor_ex { | |||
| 
 | ||||
| sub collapse_ex { | ||||
|     my ($polygons, $width) = @_; | ||||
|     return [ offset2_ex($polygons, -$width/2, +$width/2) ]; | ||||
|     return offset2_ex($polygons, -$width/2, +$width/2); | ||||
| } | ||||
| 
 | ||||
| sub simplify_polygon { | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ use List::Util qw(sum first); | |||
| use Slic3r::ExtrusionPath ':roles'; | ||||
| use Slic3r::Geometry qw(PI A B scale chained_path_items points_coincide); | ||||
| use Slic3r::Geometry::Clipper qw(safety_offset union_ex diff_ex intersection_ex  | ||||
|     offset offset2 offset2_ex PFT_EVENODD union_pt traverse_pt diff intersection); | ||||
|     offset offset2 offset_ex offset2_ex PFT_EVENODD union_pt traverse_pt diff intersection); | ||||
| use Slic3r::Surface ':types'; | ||||
| 
 | ||||
| has 'layer' => ( | ||||
|  | @ -141,7 +141,7 @@ sub _merge_loops { | |||
|             $expolygons = diff_ex([ map @$_, @$expolygons ], [$loop]); | ||||
|         } | ||||
|     } | ||||
|     $expolygons = [ map $_->offset_ex(-$safety_offset), @$expolygons ]; | ||||
|     $expolygons = offset_ex([ map @$_, @$expolygons ], -$safety_offset); | ||||
|      | ||||
|     Slic3r::debugf "  %d surface(s) having %d holes detected from %d polylines\n", | ||||
|         scalar(@$expolygons), scalar(map $_->holes, @$expolygons), scalar(@$loops); | ||||
|  | @ -180,7 +180,7 @@ sub make_perimeters { | |||
|                 ? $perimeter_spacing / 2 | ||||
|                 : $perimeter_spacing; | ||||
|              | ||||
|             my @offsets = offset2_ex(\@last, -1.5*$spacing,  +0.5*$spacing); | ||||
|             my @offsets = @{offset2_ex(\@last, -1.5*$spacing,  +0.5*$spacing)}; | ||||
|             my @contours_offsets    = map $_->contour, @offsets; | ||||
|             my @holes_offsets       = map $_->holes, @offsets; | ||||
|             @offsets = (@contours_offsets, @holes_offsets);     # turn @offsets from ExPolygons to Polygons | ||||
|  | @ -209,11 +209,11 @@ sub make_perimeters { | |||
|         # non-collapsing regions | ||||
|         # use a bogus surface_type | ||||
|         $self->fill_surfaces->append( | ||||
|             map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_TOP), offset2_ex( | ||||
|             map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_TOP), @{offset2_ex( | ||||
|                 [ map $_->simplify(&Slic3r::SCALED_RESOLUTION), @last ], | ||||
|                 -($perimeter_spacing/2 + $infill_spacing), | ||||
|                 +$infill_spacing, | ||||
|             ) | ||||
|             )} | ||||
|         ); | ||||
|     } | ||||
|      | ||||
|  | @ -322,8 +322,8 @@ sub _fill_gaps { | |||
|         my $flow = $self->perimeter_flow->clone(width => $width); | ||||
|          | ||||
|         # extract the gaps having this width | ||||
|         my @this_width = map $_->offset_ex(+0.5*$flow->scaled_width), | ||||
|             map $_->noncollapsing_offset_ex(-0.5*$flow->scaled_width), | ||||
|         my @this_width = map @{$_->offset_ex(+0.5*$flow->scaled_width)}, | ||||
|             map @{$_->noncollapsing_offset_ex(-0.5*$flow->scaled_width)}, | ||||
|             @$gaps; | ||||
|          | ||||
|         if (0) {  # remember to re-enable t/dynamic.t | ||||
|  | @ -346,7 +346,7 @@ sub _fill_gaps { | |||
|             # fill gaps using zigzag infill | ||||
|              | ||||
|             # since this is infill, we have to offset by half-extrusion width inwards | ||||
|             my @infill = map $_->offset_ex(-0.5*$flow->scaled_width), @this_width; | ||||
|             my @infill = map @{$_->offset_ex(-0.5*$flow->scaled_width)}, @this_width; | ||||
|              | ||||
|             foreach my $expolygon (@infill) { | ||||
|                 my @paths = $filler->fill_surface( | ||||
|  | @ -520,7 +520,7 @@ sub _detect_bridges { | |||
|             } | ||||
|         } elsif (@edges) { | ||||
|             # inset the bridge expolygon; we'll use this one to clip our test lines | ||||
|             my $inset = [ $surface->expolygon->offset_ex($self->infill_flow->scaled_width) ]; | ||||
|             my $inset = $surface->expolygon->offset_ex($self->infill_flow->scaled_width); | ||||
|              | ||||
|             # detect anchors as intersection between our bridge expolygon and the lower slices | ||||
|             my $anchors = intersection_ex( | ||||
|  |  | |||
|  | @ -766,9 +766,9 @@ sub write_gcode { | |||
|             ]); | ||||
|             # discard layers only containing thin walls (offset would fail on an empty polygon) | ||||
|             if (@$convex_hull) { | ||||
|                 my @island = Slic3r::ExPolygon->new($convex_hull) | ||||
|                     ->translate(scale $shift[X], scale $shift[Y]) | ||||
|                     ->offset_ex(scale $distance_from_objects, 1, JT_SQUARE); | ||||
|                 my $expolygon = Slic3r::ExPolygon->new($convex_hull); | ||||
|                 $expolygon->translate(scale $shift[X], scale $shift[Y]); | ||||
|                 my @island = @{$expolygon->offset_ex(scale $distance_from_objects, 1, JT_SQUARE)}; | ||||
|                 foreach my $copy (@{ $self->objects->[$obj_idx]->copies }) { | ||||
|                     push @islands, map $_->clone->translate(@$copy), @island; | ||||
|                 } | ||||
|  |  | |||
|  | @ -488,9 +488,9 @@ sub clip_fill_surfaces { | |||
|                 my $overhang_width = $layerm->overhang_width; | ||||
|                 # we want to support any solid surface, not just tops | ||||
|                 # (internal solids might have been generated) | ||||
|                 push @overhangs, map $_->offset_ex($additional_margin), @{intersection_ex( | ||||
|                 push @overhangs, map @{$_->offset_ex($additional_margin)}, @{intersection_ex( | ||||
|                     [ map @{$_->expolygon}, grep $_->surface_type != S_TYPE_INTERNAL, @{$layerm->fill_surfaces} ], | ||||
|                     [ map @$_, map $_->offset_ex(-$overhang_width), @{$lower_layer->slices} ], | ||||
|                     [ map @$_, map @{$_->offset_ex(-$overhang_width)}, @{$lower_layer->slices} ], | ||||
|                 )}; | ||||
|             } | ||||
|         } | ||||
|  | @ -825,7 +825,7 @@ sub generate_support_material { | |||
|             my $layer = $self->layers->[$i]; | ||||
|             my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef; | ||||
|              | ||||
|             my @current_layer_offsetted_slices = map $_->offset_ex($distance_from_object), @{$layer->slices}; | ||||
|             my @current_layer_offsetted_slices = map @{$_->offset_ex($distance_from_object)}, @{$layer->slices}; | ||||
|              | ||||
|             # $upper_layers_overhangs[-1] contains the overhangs of the upper layer, regardless of any interface layers | ||||
|             # $upper_layers_overhangs[0] contains the overhangs of the first upper layer above the interface layers | ||||
|  | @ -884,7 +884,7 @@ sub generate_support_material { | |||
|                         ? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad)) | ||||
|                         : $self->layers->[1]->regions->[0]->overhang_width; | ||||
|                  | ||||
|                 @overhangs = map $_->offset_ex(+$distance), @{diff_ex( | ||||
|                 @overhangs = map @{$_->offset_ex(+$distance)}, @{diff_ex( | ||||
|                     [ map @$_, @{$layer->slices} ], | ||||
|                     [ map @$_, @{$lower_layer->slices} ], | ||||
|                     1, | ||||
|  | @ -906,7 +906,7 @@ sub generate_support_material { | |||
|     my $support_interface_patterns = []; | ||||
|     { | ||||
|         # 0.5 ensures the paths don't get clipped externally when applying them to layers | ||||
|         my @areas = map $_->offset_ex(- 0.5 * $flow->scaled_width), | ||||
|         my @areas = map @{$_->offset_ex(- 0.5 * $flow->scaled_width)}, | ||||
|             @{union_ex([ map $_->contour, map @$_, values %layers, values %layers_interfaces, values %layers_contact_areas ])}; | ||||
|          | ||||
|         my $pattern = $Slic3r::Config->support_material_pattern; | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ sub group { | |||
| 
 | ||||
| sub offset { | ||||
|     my $self = shift; | ||||
|     return map $self->clone(expolygon => $_), $self->expolygon->offset_ex(@_); | ||||
|     return map $self->clone(expolygon => $_), @{$self->expolygon->offset_ex(@_)}; | ||||
| } | ||||
| 
 | ||||
| sub simplify { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci