mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	New utility script to split STL plates into individual STL files
This commit is contained in:
		
							parent
							
								
									7305b6da88
								
							
						
					
					
						commit
						669341cd11
					
				
					 3 changed files with 128 additions and 0 deletions
				
			
		|  | @ -83,4 +83,42 @@ sub _read_binary { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| sub write_file { | ||||
|     my $self = shift; | ||||
|     my ($file, $mesh, $binary) = @_; | ||||
|      | ||||
|     open my $fh, '>', $file; | ||||
|      | ||||
|     $binary | ||||
|         ? _write_binary($fh, $mesh->facets) | ||||
|         : _write_ascii($fh, $mesh->facets); | ||||
|      | ||||
|     close $fh; | ||||
| } | ||||
| 
 | ||||
| sub _write_binary { | ||||
|     my ($fh, $facets) = @_; | ||||
|      | ||||
|     die "bigfloat" unless length(pack "f", 1) == 4; | ||||
|      | ||||
|     binmode $fh; | ||||
|     print $fh pack 'x80'; | ||||
|     print $fh pack 'L', ($#$facets + 1); | ||||
|     print $fh pack '(f<3)4S', (map @$_, @$_), 0 for @$facets; | ||||
| } | ||||
| 
 | ||||
| sub _write_ascii { | ||||
|     my ($fh, $facets) = @_; | ||||
|      | ||||
|     printf $fh "solid\n"; | ||||
|     foreach my $facet (@$facets) { | ||||
|         printf $fh "   facet normal %f %f %f\n", @{$facet->[0]}; | ||||
|         printf $fh "      outer loop\n"; | ||||
|         printf $fh "         vertex %f %f %f\n", @$_ for @$facet[1,2,3]; | ||||
|         printf $fh "      endloop\n"; | ||||
|         printf $fh "   endfacet\n"; | ||||
|     } | ||||
|     printf $fh "endsolid\n"; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
|  | @ -457,4 +457,20 @@ sub edge_id { | |||
|     return join "-", sort @point_ids; | ||||
| } | ||||
| 
 | ||||
| sub get_connected_facets { | ||||
|     my $self = shift; | ||||
|     my ($facet_id) = @_; | ||||
|      | ||||
|     my @facets = (); | ||||
|     foreach my $edge_facets (values %{$self->edge_facets}) { | ||||
|         if (grep $_ == $facet_id, @$edge_facets) { | ||||
|             # this edge belongs to the current facet, so let's get | ||||
|             # the other facet(s) | ||||
|             push @facets, grep $_ != $facet_id, @$edge_facets; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     return @facets; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
							
								
								
									
										74
									
								
								utils/split_stl.pl
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								utils/split_stl.pl
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,74 @@ | |||
| #!/usr/bin/perl | ||||
| # This script splits a STL plate into individual files | ||||
| 
 | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| BEGIN { | ||||
|     use FindBin; | ||||
|     use lib "$FindBin::Bin/../lib"; | ||||
| } | ||||
| 
 | ||||
| use File::Basename qw(basename); | ||||
| use Getopt::Long qw(:config no_auto_abbrev); | ||||
| use Slic3r; | ||||
| $|++; | ||||
| 
 | ||||
| my %opt = (); | ||||
| { | ||||
|     my %options = ( | ||||
|         'help'                  => sub { usage() }, | ||||
|         'ascii'                 => \$opt{ascii}, | ||||
|     ); | ||||
|     GetOptions(%options) or usage(1); | ||||
|     $ARGV[0] or usage(1); | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $mesh = Slic3r::STL->read_file($ARGV[0]); | ||||
|     my $basename = $ARGV[0]; | ||||
|     $basename =~ s/\.stl$//i; | ||||
|      | ||||
|     # loop while we have remaining facets | ||||
|     my $part_count = 0; | ||||
|     $mesh->make_edge_table; | ||||
|     while (1) { | ||||
|         # get the first facet | ||||
|         my @facet_queue = (); | ||||
|         my @facets = (); | ||||
|         for (my $i = 0; $i <= $#{$mesh->facets}; $i++) { | ||||
|             if (defined $mesh->facets->[$i]) { | ||||
|                 push @facet_queue, $i; | ||||
|                 last; | ||||
|             } | ||||
|         } | ||||
|         last if !@facet_queue; | ||||
|          | ||||
|         while (defined (my $facet_id = shift @facet_queue)) { | ||||
|             next unless defined $mesh->facets->[$facet_id]; | ||||
|             push @facets, $mesh->facets->[$facet_id]; | ||||
|             push @facet_queue, $mesh->get_connected_facets($facet_id); | ||||
|             $mesh->facets->[$facet_id] = undef; | ||||
|         } | ||||
|          | ||||
|         my $output_file = sprintf '%s_%02d.stl', $basename, ++$part_count; | ||||
|         printf "Writing to %s\n", basename($output_file); | ||||
|         Slic3r::STL->write_file($output_file, Slic3r::TriangleMesh->new(facets => \@facets), !$opt{ascii}); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| sub usage { | ||||
|     my ($exit_code) = @_; | ||||
|      | ||||
|     print <<"EOF"; | ||||
| Usage: split_stl.pl [ OPTIONS ] file.stl | ||||
| 
 | ||||
|     --help              Output this usage screen and exit | ||||
|     --ascii             Generate ASCII STL files (default: binary) | ||||
|      | ||||
| EOF | ||||
|     exit ($exit_code || 0); | ||||
| } | ||||
| 
 | ||||
| __END__ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci