New --post-process option. Includes some cleaning of the STDOUT messages

This commit is contained in:
Alessandro Ranellucci 2012-02-20 12:50:05 +01:00
parent ae35df716f
commit 555c23069d
10 changed files with 63 additions and 28 deletions

View file

@ -44,6 +44,7 @@ our $notes = '';
# output options # output options
our $output_filename_format = '[input_filename_base].gcode'; our $output_filename_format = '[input_filename_base].gcode';
our $post_process = [];
# printer options # printer options
our $nozzle_diameter = 0.5; our $nozzle_diameter = 0.5;

View file

@ -254,6 +254,16 @@ our $Options = {
serialize => sub { join '\n', split /\R+/, $_[0] }, serialize => sub { join '\n', split /\R+/, $_[0] },
deserialize => sub { join "\n", split /\\n/, $_[0] }, deserialize => sub { join "\n", split /\\n/, $_[0] },
}, },
'post_process' => {
label => 'Post-processing scripts',
cli => 'post-process=s@',
type => 's@',
multiline => 1,
width => 350,
height => 60,
serialize => sub { join '; ', @{$_[0]} },
deserialize => sub { [ split /\s*;\s*/, $_[0] ] },
},
# retraction options # retraction options
'retract_length' => { 'retract_length' => {
@ -352,6 +362,14 @@ sub serialize {
: get($opt_key); : get($opt_key);
} }
sub deserialize {
my $class = @_ == 3 ? shift : undef;
my ($opt_key, $value) = @_;
return $Options->{$opt_key}{deserialize}
? set($opt_key, $Options->{$opt_key}{deserialize}->($value))
: set($opt_key, $value);
}
sub save { sub save {
my $class = shift; my $class = shift;
my ($file) = @_; my ($file) = @_;

View file

@ -45,7 +45,7 @@ sub make_fill {
$_->layer($layer) for values %{$self->fillers}; $_->layer($layer) for values %{$self->fillers};
printf "Filling layer %d:\n", $layer->id; Slic3r::debugf "Filling layer %d:\n", $layer->id;
# merge overlapping surfaces # merge overlapping surfaces
my @surfaces = (); my @surfaces = ();

View file

@ -33,7 +33,7 @@ sub new {
$bold_font->SetPointSize($label->GetFont()->GetPointSize()); $bold_font->SetPointSize($label->GetFont()->GetPointSize());
$label->SetFont($bold_font) if $opt->{important}; $label->SetFont($bold_font) if $opt->{important};
my $field; my $field;
if ($opt->{type} =~ /^(i|f|s)$/) { if ($opt->{type} =~ /^(i|f|s|s@)$/) {
my $style = 0; my $style = 0;
my $size = Wx::wxDefaultSize; my $size = Wx::wxDefaultSize;
@ -42,10 +42,12 @@ sub new {
$size = Wx::Size->new($opt->{width} || -1, $opt->{height} || -1); $size = Wx::Size->new($opt->{width} || -1, $opt->{height} || -1);
} }
$field = Wx::TextCtrl->new($parent, -1, Slic3r::Config->get($opt_key), my ($get, $set) = $opt->{type} eq 's@' ? qw(serialize deserialize) : qw(get set);
$field = Wx::TextCtrl->new($parent, -1, Slic3r::Config->$get($opt_key),
Wx::wxDefaultPosition, $size, $style); Wx::wxDefaultPosition, $size, $style);
EVT_TEXT($parent, $field, sub { Slic3r::Config->set($opt_key, $field->GetValue) }); EVT_TEXT($parent, $field, sub { Slic3r::Config->$set($opt_key, $field->GetValue) });
push @reload_callbacks, sub { $field->SetValue(Slic3r::Config->get($opt_key)) }; push @reload_callbacks, sub { $field->SetValue(Slic3r::Config->$get($opt_key)) };
} elsif ($opt->{type} eq 'bool') { } elsif ($opt->{type} eq 'bool') {
$field = Wx::CheckBox->new($parent, -1, ""); $field = Wx::CheckBox->new($parent, -1, "");
$field->SetValue(Slic3r::Config->get($opt_key)); $field->SetValue(Slic3r::Config->get($opt_key));

View file

@ -57,7 +57,7 @@ sub new {
}, },
gcode => { gcode => {
title => 'Custom GCODE', title => 'Custom GCODE',
options => [qw(start_gcode end_gcode gcode_comments)], options => [qw(start_gcode end_gcode gcode_comments post_process)],
}, },
extrusion => { extrusion => {
title => 'Extrusion', title => 'Extrusion',
@ -181,7 +181,7 @@ sub do_slice {
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])/) {
$process_dialog->Update($percent, $message); $process_dialog->Update($percent, "$message...");
} }
}, },
); );

View file

@ -9,7 +9,7 @@ use XXX;
sub make_perimeter { sub make_perimeter {
my $self = shift; my $self = shift;
my ($layer) = @_; my ($layer) = @_;
printf "Making perimeter for layer %d\n", $layer->id; Slic3r::debugf "Making perimeters for layer %d\n", $layer->id;
# at least one perimeter is required # at least one perimeter is required
die "Can't slice object with no perimeters!\n" die "Can't slice object with no perimeters!\n"

View file

@ -45,9 +45,8 @@ sub new_from_mesh {
# (we might have created it because of the $max_layer = ... + 1 code below) # (we might have created it because of the $max_layer = ... + 1 code below)
pop @{$print->layers} if !@{$print->layers->[-1]->surfaces} && !@{$print->layers->[-1]->lines}; pop @{$print->layers} if !@{$print->layers->[-1]->surfaces} && !@{$print->layers->[-1]->lines};
print "\n==> PROCESSING SLICES:\n";
foreach my $layer (@{ $print->layers }) { foreach my $layer (@{ $print->layers }) {
printf "Making surfaces for layer %d:\n", $layer->id; Slic3r::debugf "Making surfaces for layer %d:\n", $layer->id;
# layer currently has many lines representing intersections of # layer currently has many lines representing intersections of
# model facets with the layer plane. there may also be lines # model facets with the layer plane. there may also be lines
@ -517,8 +516,6 @@ sub export_gcode {
my $self = shift; my $self = shift;
my ($file) = @_; my ($file) = @_;
printf "Exporting GCODE file...\n";
# open output gcode file # open output gcode file
open my $fh, ">", $file open my $fh, ">", $file
or die "Failed to open $file for writing\n"; or die "Failed to open $file for writing\n";

View file

@ -23,7 +23,7 @@ sub go {
# skein the STL into layers # skein the STL into layers
# each layer has surfaces with holes # each layer has surfaces with holes
$self->status_cb->(10, "Processing triangulated mesh..."); $self->status_cb->(10, "Processing triangulated mesh");
my $print; my $print;
{ {
my $mesh = $self->input_file =~ /\.stl$/i my $mesh = $self->input_file =~ /\.stl$/i
@ -38,7 +38,7 @@ sub go {
# make perimeters # make perimeters
# this will add a set of extrusion loops to each layer # this will add a set of extrusion loops to each layer
# as well as generate infill boundaries # as well as generate infill boundaries
$self->status_cb->(20, "Generating perimeters..."); $self->status_cb->(20, "Generating perimeters");
{ {
my $perimeter_maker = Slic3r::Perimeter->new; my $perimeter_maker = Slic3r::Perimeter->new;
$perimeter_maker->make_perimeter($_) for @{$print->layers}; $perimeter_maker->make_perimeter($_) for @{$print->layers};
@ -46,42 +46,42 @@ sub go {
# this will clip $layer->surfaces to the infill boundaries # this will clip $layer->surfaces to the infill boundaries
# and split them in top/bottom/internal surfaces; # and split them in top/bottom/internal surfaces;
$self->status_cb->(30, "Detecting solid surfaces..."); $self->status_cb->(30, "Detecting solid surfaces");
$print->detect_surfaces_type; $print->detect_surfaces_type;
# decide what surfaces are to be filled # decide what surfaces are to be filled
$self->status_cb->(35, "Preparing infill surfaces..."); $self->status_cb->(35, "Preparing infill surfaces");
$_->prepare_fill_surfaces for @{$print->layers}; $_->prepare_fill_surfaces for @{$print->layers};
# this will remove unprintable surfaces # this will remove unprintable surfaces
# (those that are too tight for extrusion) # (those that are too tight for extrusion)
$self->status_cb->(40, "Cleaning up..."); $self->status_cb->(40, "Cleaning up");
$_->remove_small_surfaces for @{$print->layers}; $_->remove_small_surfaces for @{$print->layers};
# this will detect bridges and reverse bridges # this will detect bridges and reverse bridges
# and rearrange top/bottom/internal surfaces # and rearrange top/bottom/internal surfaces
$self->status_cb->(45, "Detect bridges..."); $self->status_cb->(45, "Detect bridges");
$_->process_bridges for @{$print->layers}; $_->process_bridges for @{$print->layers};
# this will remove unprintable perimeter loops # this will remove unprintable perimeter loops
# (those that are too tight for extrusion) # (those that are too tight for extrusion)
$self->status_cb->(50, "Cleaning up the perimeters..."); $self->status_cb->(50, "Cleaning up the perimeters");
$_->remove_small_perimeters for @{$print->layers}; $_->remove_small_perimeters for @{$print->layers};
# detect which fill surfaces are near external layers # detect which fill surfaces are near external layers
# they will be split in internal and internal-solid surfaces # they will be split in internal and internal-solid surfaces
$self->status_cb->(60, "Generating horizontal shells..."); $self->status_cb->(60, "Generating horizontal shells");
$print->discover_horizontal_shells; $print->discover_horizontal_shells;
# free memory # free memory
@{$_->surfaces} = () for @{$print->layers}; @{$_->surfaces} = () for @{$print->layers};
# combine fill surfaces to honor the "infill every N layers" option # combine fill surfaces to honor the "infill every N layers" option
$self->status_cb->(70, "Combining infill..."); $self->status_cb->(70, "Combining infill");
$print->infill_every_layers; $print->infill_every_layers;
# this will generate extrusion paths for each layer # this will generate extrusion paths for each layer
$self->status_cb->(80, "Infilling layers..."); $self->status_cb->(80, "Infilling layers");
{ {
my $fill_maker = Slic3r::Fill->new('print' => $print); my $fill_maker = Slic3r::Fill->new('print' => $print);
@ -116,17 +116,27 @@ sub go {
# generate support material # generate support material
if ($Slic3r::support_material) { if ($Slic3r::support_material) {
$self->status_cb->(85, "Generating support material..."); $self->status_cb->(85, "Generating support material");
$print->generate_support_material; $print->generate_support_material;
} }
# make skirt # make skirt
$self->status_cb->(88, "Generating skirt..."); $self->status_cb->(88, "Generating skirt");
$print->extrude_skirt; $print->extrude_skirt;
# output everything to a GCODE file # output everything to a GCODE file
$self->status_cb->(90, "Exporting GCODE..."); $self->status_cb->(90, "Exporting GCODE");
$print->export_gcode($self->expanded_output_filepath); my $output_file = $self->expanded_output_filepath;
$print->export_gcode($output_file);
# run post-processing scripts
if (@$Slic3r::post_process) {
$self->status_cb->(95, "Running post-processing scripts");
for (@$Slic3r::post_process) {
Slic3r::debugf " '%s' '%s'\n", $_, $output_file;
system($_, $output_file);
}
}
# output some statistics # output some statistics
$self->processing_time(tv_interval($t0)); $self->processing_time(tv_interval($t0));

View file

@ -79,6 +79,10 @@ 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}, output_file => $opt{output},
status_cb => sub {
my ($percent, $message) = @_;
printf "=> $message\n";
},
); );
$skein->go; $skein->go;
@ -108,6 +112,8 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
Output file name format; all config options enclosed in brackets Output file name format; all config options enclosed in brackets
will be replaced by their values, as well as [input_filename_base] will be replaced by their values, as well as [input_filename_base]
and [input_filename] (default: $Slic3r::output_filename_format) and [input_filename] (default: $Slic3r::output_filename_format)
--post-process Generated G-code will be processed with the supplied script;
call this more than once to process through multiple scripts.
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)

View file

@ -1,11 +1,12 @@
#!/usr/bin/perl #!/usr/bin/perl -i
use strict; use strict;
use warnings;
my $z = 0; my $z = 0;
# read stdin and any/all files passed as parameters one line at a time # read stdin and any/all files passed as parameters one line at a time
for (<>) { while (<>) {
# if we find a Z word, save it # if we find a Z word, save it
$z = $1 if /Z(\d+(\.\d+)?)/; $z = $1 if /Z(\d+(\.\d+)?)/;