mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Refactoring: use indexed vertices
This commit is contained in:
		
							parent
							
								
									2e44f60c61
								
							
						
					
					
						commit
						f814ccf062
					
				
					 3 changed files with 45 additions and 36 deletions
				
			
		|  | @ -64,7 +64,7 @@ sub new_from_mesh { | ||||||
|          |          | ||||||
|         # transform vertex coordinates |         # transform vertex coordinates | ||||||
|         my ($normal, @vertices) = @$facet; |         my ($normal, @vertices) = @$facet; | ||||||
|         $mesh->_facet($print, $i, $normal, @vertices); |         $mesh->slice_facet($print, $i, $normal, @vertices); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     die "Invalid input file\n" if !@{$print->layers}; |     die "Invalid input file\n" if !@{$print->layers}; | ||||||
|  |  | ||||||
|  | @ -10,7 +10,6 @@ sub read_file { | ||||||
|     my ($file) = @_; |     my ($file) = @_; | ||||||
|      |      | ||||||
|     open my $fh, '<', $file or die "Failed to open $file\n"; |     open my $fh, '<', $file or die "Failed to open $file\n"; | ||||||
|     my $facets = []; |  | ||||||
|      |      | ||||||
|     # let's detect whether file is ASCII or binary |     # let's detect whether file is ASCII or binary | ||||||
|     my $mode; |     my $mode; | ||||||
|  | @ -35,12 +34,28 @@ sub read_file { | ||||||
|         $mode = ($size == $expected_size) ? 'binary' : 'ascii'; |         $mode = ($size == $expected_size) ? 'binary' : 'ascii'; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     my $facets = []; | ||||||
|     $mode eq 'ascii' |     $mode eq 'ascii' | ||||||
|         ? _read_ascii($fh, $facets) |         ? _read_ascii($fh, $facets) | ||||||
|         : _read_binary($fh, $facets); |         : _read_binary($fh, $facets); | ||||||
|      |  | ||||||
|     close $fh; |     close $fh; | ||||||
|     return Slic3r::TriangleMesh->new(facets => $facets); |      | ||||||
|  |     my $vertices = []; | ||||||
|  |     { | ||||||
|  |         my %vertices_map = (); | ||||||
|  |         foreach my $facet (@$facets) { | ||||||
|  |             for (1..3) { | ||||||
|  |                 if ($vertices_map{$facet->[$_]}) { | ||||||
|  |                     $facet->[$_] = $vertices_map{$facet->[$_]}; | ||||||
|  |                 } else { | ||||||
|  |                     push @$vertices, $facet->[$_]; | ||||||
|  |                     $facet->[$_] = $vertices_map{$facet->[$_]} = $#$vertices; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return Slic3r::TriangleMesh->new(vertices => $vertices, facets => $facets); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub _read_ascii { | sub _read_ascii { | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ use Slic3r::Geometry qw(X Y Z A B PI epsilon same_point points_coincide angle3po | ||||||
|     merge_collinear_lines nearest_point polyline_lines); |     merge_collinear_lines nearest_point polyline_lines); | ||||||
| use XXX; | use XXX; | ||||||
| 
 | 
 | ||||||
|  | has 'vertices'      => (is => 'ro', default => sub { [] }); | ||||||
| has 'facets'        => (is => 'ro', default => sub { [] }); | has 'facets'        => (is => 'ro', default => sub { [] }); | ||||||
| has 'edges'         => (is => 'ro', default => sub { [] }); | has 'edges'         => (is => 'ro', default => sub { [] }); | ||||||
| has 'edge_table'    => (is => 'ro', default => sub { {} }); | has 'edge_table'    => (is => 'ro', default => sub { {} }); | ||||||
|  | @ -234,12 +235,11 @@ sub rotate { | ||||||
|     return if $deg == 0; |     return if $deg == 0; | ||||||
|      |      | ||||||
|     my $rad = Slic3r::Geometry::deg2rad($deg); |     my $rad = Slic3r::Geometry::deg2rad($deg); | ||||||
|     foreach my $facet (@{$self->facets}) { |      | ||||||
|         my ($normal, @vertices) = @$facet; |     # transform vertex coordinates | ||||||
|         foreach my $vertex (@vertices) { |     foreach my $vertex (@{$self->vertices}) { | ||||||
|         @$vertex = (@{ +(Slic3r::Geometry::rotate_points($rad, undef, [ $vertex->[X], $vertex->[Y] ]))[0] }, $vertex->[Z]); |         @$vertex = (@{ +(Slic3r::Geometry::rotate_points($rad, undef, [ $vertex->[X], $vertex->[Y] ]))[0] }, $vertex->[Z]); | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub scale { | sub scale { | ||||||
|  | @ -247,26 +247,20 @@ sub scale { | ||||||
|     my ($factor) = @_; |     my ($factor) = @_; | ||||||
|     return if $factor == 1; |     return if $factor == 1; | ||||||
|      |      | ||||||
|     foreach my $facet (@{$self->facets}) { |  | ||||||
|     # transform vertex coordinates |     # transform vertex coordinates | ||||||
|         my ($normal, @vertices) = @$facet; |     foreach my $vertex (@{$self->vertices}) { | ||||||
|         foreach my $vertex (@vertices) { |  | ||||||
|         $vertex->[$_] *= $factor for X,Y,Z; |         $vertex->[$_] *= $factor for X,Y,Z; | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub move { | sub move { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my (@shift) = @_; |     my (@shift) = @_; | ||||||
|      |      | ||||||
|     foreach my $facet (@{$self->facets}) { |  | ||||||
|     # transform vertex coordinates |     # transform vertex coordinates | ||||||
|         my ($normal, @vertices) = @$facet; |     foreach my $vertex (@{$self->vertices}) { | ||||||
|         foreach my $vertex (@vertices) { |  | ||||||
|         $vertex->[$_] += $shift[$_] for X,Y,Z; |         $vertex->[$_] += $shift[$_] for X,Y,Z; | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub duplicate { | sub duplicate { | ||||||
|  | @ -280,7 +274,8 @@ sub duplicate { | ||||||
|         foreach my $shift (@shifts) { |         foreach my $shift (@shifts) { | ||||||
|             push @new_facets, [ $normal ]; |             push @new_facets, [ $normal ]; | ||||||
|             foreach my $vertex (@vertices) { |             foreach my $vertex (@vertices) { | ||||||
|                 push @{$new_facets[-1]}, [ map $vertex->[$_] + ($shift->[$_] || 0), (X,Y,Z) ]; |                 push @{$self->vertices}, [ map $self->vertices->[$vertex][$_] + ($shift->[$_] || 0), (X,Y,Z) ]; | ||||||
|  |                 push @{$new_facets[-1]}, $#{$self->vertices}; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -289,14 +284,11 @@ sub duplicate { | ||||||
| 
 | 
 | ||||||
| sub bounding_box { | sub bounding_box { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my @extents = (map [9999999999999999999999, -9999999999999999999999], X,Y,Z); |     my @extents = (map [undef, undef], X,Y,Z); | ||||||
|     foreach my $facet (@{$self->facets}) { |     foreach my $vertex (@{$self->vertices}) { | ||||||
|         my ($normal, @vertices) = @$facet; |  | ||||||
|         foreach my $vertex (@vertices) { |  | ||||||
|         for (X,Y,Z) { |         for (X,Y,Z) { | ||||||
|                 $extents[$_][MIN] = $vertex->[$_] if $vertex->[$_] < $extents[$_][MIN]; |             $extents[$_][MIN] = $vertex->[$_] if !defined $extents[$_][MIN] || $vertex->[$_] < $extents[$_][MIN]; | ||||||
|                 $extents[$_][MAX] = $vertex->[$_] if $vertex->[$_] > $extents[$_][MAX]; |             $extents[$_][MAX] = $vertex->[$_] if !defined $extents[$_][MAX] || $vertex->[$_] > $extents[$_][MAX]; | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return @extents; |     return @extents; | ||||||
|  | @ -309,16 +301,18 @@ sub size { | ||||||
|     return map $extents[$_][MAX] - $extents[$_][MIN], (X,Y,Z); |     return map $extents[$_][MAX] - $extents[$_][MIN], (X,Y,Z); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub _facet { | sub slice_facet { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my ($print, $facet_index, $normal, @vertices) = @_; |     my ($print, $facet_index, $normal, @vertices) = @_; | ||||||
|     Slic3r::debugf "\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", |     Slic3r::debugf "\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", | ||||||
|         $facet_index, map @$_, @vertices |         $facet_index, map @{$self->vertices->[$_]}, @vertices | ||||||
|         if $Slic3r::debug; |         if $Slic3r::debug; | ||||||
|      |      | ||||||
|  |     my @vertices_coordinates = map $self->vertices->[$_], @vertices; | ||||||
|  |      | ||||||
|     # find the vertical extents of the facet |     # find the vertical extents of the facet | ||||||
|     my ($min_z, $max_z) = (99999999999, -99999999999); |     my ($min_z, $max_z) = (99999999999, -99999999999); | ||||||
|     foreach my $vertex (@vertices) { |     foreach my $vertex (@vertices_coordinates) { | ||||||
|         $min_z = $vertex->[Z] if $vertex->[Z] < $min_z; |         $min_z = $vertex->[Z] if $vertex->[Z] < $min_z; | ||||||
|         $max_z = $vertex->[Z] if $vertex->[Z] > $max_z; |         $max_z = $vertex->[Z] if $vertex->[Z] > $max_z; | ||||||
|     } |     } | ||||||
|  | @ -341,7 +335,7 @@ sub _facet { | ||||||
|     # this is needed to get all intersection lines in a consistent order |     # this is needed to get all intersection lines in a consistent order | ||||||
|     # (external on the right of the line) |     # (external on the right of the line) | ||||||
|     { |     { | ||||||
|         my @z_order = sort { $vertices[$a][Z] <=> $vertices[$b][Z] } 0..2; |         my @z_order = sort { $vertices_coordinates[$a][Z] <=> $vertices_coordinates[$b][Z] } 0..2; | ||||||
|         @vertices = (splice(@vertices, $z_order[0]), splice(@vertices, 0, $z_order[0])); |         @vertices = (splice(@vertices, $z_order[0]), splice(@vertices, 0, $z_order[0])); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  | @ -367,7 +361,7 @@ sub intersect_facet { | ||||||
|          |          | ||||||
|         if (abs($a->[Z] - $b->[Z]) < epsilon && abs($a->[Z] - $z) < epsilon) { |         if (abs($a->[Z] - $b->[Z]) < epsilon && abs($a->[Z] - $z) < epsilon) { | ||||||
|             # edge is horizontal and belongs to the current layer |             # edge is horizontal and belongs to the current layer | ||||||
|             my $edge_type = (grep $_->[Z] < $z - epsilon, @$vertices) ? 'top' : 'bottom'; |             my $edge_type = (grep $self->vertices->[$_][Z] < $z - epsilon, @$vertices) ? 'top' : 'bottom'; | ||||||
|             ($a, $b) = ($b, $a) if $edge_type eq 'top'; |             ($a, $b) = ($b, $a) if $edge_type eq 'top'; | ||||||
|             push @lines, Slic3r::TriangleMesh::IntersectionLine->new( |             push @lines, Slic3r::TriangleMesh::IntersectionLine->new( | ||||||
|                 a           => [$a->[X], $a->[Y]], |                 a           => [$a->[X], $a->[Y]], | ||||||
|  | @ -440,7 +434,7 @@ sub facet_edges { | ||||||
|     my ($facet) = @_; |     my ($facet) = @_; | ||||||
|      |      | ||||||
|     # ignore the normal if provided |     # ignore the normal if provided | ||||||
|     my @vertices = @$facet[-3..-1]; |     my @vertices = map $self->vertices->[$_], @$facet[-3..-1]; | ||||||
|      |      | ||||||
|     return ( |     return ( | ||||||
|         [ $vertices[0], $vertices[1] ], |         [ $vertices[0], $vertices[1] ], | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci