New utility script to split STL plates into individual STL files

This commit is contained in:
Alessandro Ranellucci 2012-01-28 15:05:42 +01:00
parent 7305b6da88
commit 669341cd11
3 changed files with 128 additions and 0 deletions

View File

@ -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;

View File

@ -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
View 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__