Cleanup the --output-filename-format implementation. #53 #137

This commit is contained in:
Alessandro Ranellucci 2011-12-26 17:20:26 +01:00
parent 1071b556cb
commit f9446b9c6e
5 changed files with 79 additions and 40 deletions

View File

@ -81,13 +81,15 @@ The author is Alessandro Ranellucci (me).
--help Output this usage screen and exit --help Output this usage screen and exit
--save <file> Save configuration to the specified file --save <file> Save configuration to the specified file
--load <file> Load configuration from the specified file --load <file> Load configuration from the specified file
-o <filename> File name to output gcode to (default: --output) -o, --output <file> File to output gcode to (by default, the file will be saved
into the same directory as the input file using the
--output-filename-format to generate the filename)
Output options: Output options:
--output Output file name format (default: [input_filename_base].gcode) --output-filament-format
examples: Output file name format; all config options enclosed in brackets
[input_filename_base]_h[layer_height]_p[perimeters]_s[solid_layers].gcode will be replaced by their values, as well as [input_filename_base]
[input_filename]_center[print_center]_layer[layer_height].gcode and [input_filename] (default: [input_filename_base].gcode)
Printer options: Printer options:
--nozzle-diameter Diameter of nozzle in mm (default: 0.5) --nozzle-diameter Diameter of nozzle in mm (default: 0.5)
@ -160,10 +162,10 @@ The author is Alessandro Ranellucci (me).
--retract-lift Lift Z by the given distance in mm when retracting (default: 0) --retract-lift Lift Z by the given distance in mm when retracting (default: 0)
Skirt options: Skirt options:
--skirts Number of skirts to draw (default: 1) --skirts Number of skirts to draw (0+, default: 1)
--skirt-distance Distance in mm between innermost skirt and object --skirt-distance Distance in mm between innermost skirt and object
(default: 6) (default: 6)
--skirt-height Height of skirts to draw (expressed in layers, default: 1) --skirt-height Height of skirts to draw (expressed in layers, 0+, default: 1)
Transform options: Transform options:
--scale Factor for scaling input object (default: 1) --scale Factor for scaling input object (default: 1)
@ -202,3 +204,21 @@ you like).
On Mac, the executable has a path like this: On Mac, the executable has a path like this:
/Applications/Slic3r.app/Contents/MacOS/slic3r /Applications/Slic3r.app/Contents/MacOS/slic3r
## How can I specify a custom filename format for output G-code files?
You can specify a filename format by using any of the config options.
Just enclose them in square brackets, and Slic3r will replace them upon
exporting.
The additional `[input_filename]` and `[input_filename_base]` options will
be replaced by the input file name (in the second case, the .stl extension
is stripped).
The default format is `[input_filename_base].gcode`, meaning that if you slice
a *foo.stl* file, the output will be saved to *foo.gcode*.
See below for more complex examples:
[input_filename_base]_h[layer_height]_p[perimeters]_s[solid_layers].gcode
[input_filename]_center[print_center]_[layer_height]layers.gcode

View File

@ -10,7 +10,7 @@ our $Options = {
# output options # output options
'output_filename_format' => { 'output_filename_format' => {
label => 'Output filename format', label => 'Output filename format',
cli => 'output=s', cli => 'output-filename-format=s',
type => 's', type => 's',
}, },
@ -296,6 +296,14 @@ sub set {
${"Slic3r::$opt_key"} = $value; ${"Slic3r::$opt_key"} = $value;
} }
sub serialize {
my $class = @_ == 2 ? shift : undef;
my ($opt_key) = @_;
return $Options->{$opt_key}{serialize}
? $Options->{$opt_key}{serialize}->(get($opt_key))
: get($opt_key);
}
sub save { sub save {
my $class = shift; my $class = shift;
my ($file) = @_; my ($file) = @_;

View File

@ -154,6 +154,7 @@ sub do_slice {
my $skein = Slic3r::Skein->new( my $skein = Slic3r::Skein->new(
input_file => $input_file, input_file => $input_file,
output_file => $main::opt{output},
status_cb => sub { status_cb => sub {
my ($percent, $message) = @_; my ($percent, $message) = @_;
if (&Wx::wxVERSION_STRING =~ / 2\.(8\.|9\.[2-9])/) { if (&Wx::wxVERSION_STRING =~ / 2\.(8\.|9\.[2-9])/) {
@ -163,11 +164,8 @@ sub do_slice {
); );
# select output file # select output file
my $output_file = $main::opt{output_filename};
if ($params{save_as}) { if ($params{save_as}) {
if (!$output_file) { my $output_file = $skein->expanded_output_filepath;
$output_file = $skein->get_output_filename($input_file);
}
my $dlg = Wx::FileDialog->new($self, 'Save gcode file as:', dirname($output_file), my $dlg = Wx::FileDialog->new($self, 'Save gcode file as:', dirname($output_file),
basename($output_file), $gcode_wildcard, wxFD_SAVE); basename($output_file), $gcode_wildcard, wxFD_SAVE);
return if $dlg->ShowModal != wxID_OK; return if $dlg->ShowModal != wxID_OK;

View File

@ -1,12 +1,18 @@
package Slic3r::Skein; package Slic3r::Skein;
use Moo; use Moo;
use File::Basename qw(basename fileparse);
use Slic3r::Geometry qw(PI); use Slic3r::Geometry qw(PI);
use Time::HiRes qw(gettimeofday tv_interval); use Time::HiRes qw(gettimeofday tv_interval);
use XXX; use XXX;
# full path (relative or absolute) to the input file
has 'input_file' => (is => 'ro', required => 1); has 'input_file' => (is => 'ro', required => 1);
has 'output_file' => (is => 'rw', required => 0);
# full path (relative or absolute) to the output file; it may contain
# formatting variables like [layer_height] etc.
has 'output_file' => (is => 'rw', required => 0);
has 'status_cb' => (is => 'rw', required => 0, default => sub { sub {} }); has 'status_cb' => (is => 'rw', required => 0, default => sub { sub {} });
has 'processing_time' => (is => 'rw', required => 0); has 'processing_time' => (is => 'rw', required => 0);
@ -83,11 +89,7 @@ sub go {
# output everything to a GCODE file # output everything to a GCODE file
$self->status_cb->(90, "Exporting GCODE..."); $self->status_cb->(90, "Exporting GCODE...");
if ($self->output_file) { $print->export_gcode($self->expanded_output_filepath);
$print->export_gcode($self->output_file);
} else {
$print->export_gcode($self->get_output_filename);
}
# output some statistics # output some statistics
$self->processing_time(tv_interval($t0)); $self->processing_time(tv_interval($t0));
@ -100,20 +102,30 @@ sub go {
$print->total_extrusion_length, $print->total_extrusion_volume; $print->total_extrusion_length, $print->total_extrusion_volume;
} }
sub get_output_filename { # this method will return the value of $self->output_file after expanding its
# format variables with their values
sub expanded_output_filepath {
my $self = shift; my $self = shift;
my $filename = Slic3r::Config->get('output_filename_format');
my %opts = %$Slic3r::Config::Options; my $path = $self->output_file;
my $input = $self->input_file;
# these pseudo-options are the path and filename, without and with extension, of the input file # if no explicit output file was defined, we take the input
$filename =~ s/\[input_filename\]/$input/g; # file directory and append the specified filename format
$input =~ s/\.stl$//i; $path ||= (fileparse($self->input_file))[1] . $Slic3r::output_filename_format;
$filename =~ s/\[input_filename_base\]/$input/g;
# make a list of options my $input_basename = basename($self->input_file);
my $options = join '|', keys %$Slic3r::Config::Options; $path =~ s/\[input_filename\]/$input_basename/g;
# use that list to search and replace option names with option values $input_basename =~ s/\.stl$//i;
$filename =~ s/\[($options)\]/Slic3r::Config->get($1)/eg; $path =~ s/\[input_filename_base\]/$input_basename/g;
return $filename;
# build a regexp to match the available options
my $options = join '|',
grep !$Slic3r::Config::Options->{$_}{multiline},
keys %$Slic3r::Config::Options;
# use that regexp to search and replace option names with option values
$path =~ s/\[($options)\]/Slic3r::Config->serialize($1)/eg;
return $path;
} }
1; 1;

View File

@ -20,8 +20,7 @@ my %cli_options = ();
'help' => sub { usage() }, 'help' => sub { usage() },
'debug' => \$Slic3r::debug, 'debug' => \$Slic3r::debug,
'o|output=s' => \$opt{output},
'o=s' => \$opt{output_filename},
'save=s' => \$opt{save}, 'save=s' => \$opt{save},
'load=s' => \$opt{load}, 'load=s' => \$opt{load},
@ -71,7 +70,7 @@ if ($ARGV[0]) {
my $skein = Slic3r::Skein->new( my $skein = Slic3r::Skein->new(
input_file => $input_file, input_file => $input_file,
output_file => $opt{output_filename}, output_file => $opt{output},
); );
$skein->go; $skein->go;
@ -91,13 +90,15 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
--help Output this usage screen and exit --help Output this usage screen and exit
--save <file> Save configuration to the specified file --save <file> Save configuration to the specified file
--load <file> Load configuration from the specified file --load <file> Load configuration from the specified file
-o <filename> File name to output gcode to (default: --output) -o, --output <file> File to output gcode to (by default, the file will be saved
into the same directory as the input file using the
--output-filename-format to generate the filename)
Output options: Output options:
--output Output file name format (default: [input_filename_base].gcode) --output-filament-format
examples: Output file name format; all config options enclosed in brackets
[input_filename_base]_h[layer_height]_p[perimeters]_s[solid_layers].gcode will be replaced by their values, as well as [input_filename_base]
[input_filename]_center[print_center]_layer[layer_height].gcode and [input_filename] (default: $Slic3r::output_filename_format)
Printer options: Printer options:
--nozzle-diameter Diameter of nozzle in mm (default: $Slic3r::nozzle_diameter) --nozzle-diameter Diameter of nozzle in mm (default: $Slic3r::nozzle_diameter)