New --post-process option. Includes some cleaning of the STDOUT messages
This commit is contained in:
parent
ae35df716f
commit
555c23069d
@ -44,6 +44,7 @@ our $notes = '';
|
||||
|
||||
# output options
|
||||
our $output_filename_format = '[input_filename_base].gcode';
|
||||
our $post_process = [];
|
||||
|
||||
# printer options
|
||||
our $nozzle_diameter = 0.5;
|
||||
|
@ -254,6 +254,16 @@ our $Options = {
|
||||
serialize => sub { join '\n', split /\R+/, $_[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
|
||||
'retract_length' => {
|
||||
@ -352,6 +362,14 @@ sub serialize {
|
||||
: 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 {
|
||||
my $class = shift;
|
||||
my ($file) = @_;
|
||||
|
@ -45,7 +45,7 @@ sub make_fill {
|
||||
|
||||
$_->layer($layer) for values %{$self->fillers};
|
||||
|
||||
printf "Filling layer %d:\n", $layer->id;
|
||||
Slic3r::debugf "Filling layer %d:\n", $layer->id;
|
||||
|
||||
# merge overlapping surfaces
|
||||
my @surfaces = ();
|
||||
|
@ -33,7 +33,7 @@ sub new {
|
||||
$bold_font->SetPointSize($label->GetFont()->GetPointSize());
|
||||
$label->SetFont($bold_font) if $opt->{important};
|
||||
my $field;
|
||||
if ($opt->{type} =~ /^(i|f|s)$/) {
|
||||
if ($opt->{type} =~ /^(i|f|s|s@)$/) {
|
||||
my $style = 0;
|
||||
my $size = Wx::wxDefaultSize;
|
||||
|
||||
@ -42,10 +42,12 @@ sub new {
|
||||
$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);
|
||||
EVT_TEXT($parent, $field, sub { Slic3r::Config->set($opt_key, $field->GetValue) });
|
||||
push @reload_callbacks, sub { $field->SetValue(Slic3r::Config->get($opt_key)) };
|
||||
EVT_TEXT($parent, $field, sub { Slic3r::Config->$set($opt_key, $field->GetValue) });
|
||||
push @reload_callbacks, sub { $field->SetValue(Slic3r::Config->$get($opt_key)) };
|
||||
} elsif ($opt->{type} eq 'bool') {
|
||||
$field = Wx::CheckBox->new($parent, -1, "");
|
||||
$field->SetValue(Slic3r::Config->get($opt_key));
|
||||
|
@ -57,7 +57,7 @@ sub new {
|
||||
},
|
||||
gcode => {
|
||||
title => 'Custom GCODE',
|
||||
options => [qw(start_gcode end_gcode gcode_comments)],
|
||||
options => [qw(start_gcode end_gcode gcode_comments post_process)],
|
||||
},
|
||||
extrusion => {
|
||||
title => 'Extrusion',
|
||||
@ -181,7 +181,7 @@ sub do_slice {
|
||||
status_cb => sub {
|
||||
my ($percent, $message) = @_;
|
||||
if (&Wx::wxVERSION_STRING =~ / 2\.(8\.|9\.[2-9])/) {
|
||||
$process_dialog->Update($percent, $message);
|
||||
$process_dialog->Update($percent, "$message...");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -9,7 +9,7 @@ use XXX;
|
||||
sub make_perimeter {
|
||||
my $self = shift;
|
||||
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
|
||||
die "Can't slice object with no perimeters!\n"
|
||||
|
@ -45,9 +45,8 @@ sub new_from_mesh {
|
||||
# (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};
|
||||
|
||||
print "\n==> PROCESSING SLICES:\n";
|
||||
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
|
||||
# model facets with the layer plane. there may also be lines
|
||||
@ -517,8 +516,6 @@ sub export_gcode {
|
||||
my $self = shift;
|
||||
my ($file) = @_;
|
||||
|
||||
printf "Exporting GCODE file...\n";
|
||||
|
||||
# open output gcode file
|
||||
open my $fh, ">", $file
|
||||
or die "Failed to open $file for writing\n";
|
||||
|
@ -23,7 +23,7 @@ sub go {
|
||||
|
||||
# skein the STL into layers
|
||||
# each layer has surfaces with holes
|
||||
$self->status_cb->(10, "Processing triangulated mesh...");
|
||||
$self->status_cb->(10, "Processing triangulated mesh");
|
||||
my $print;
|
||||
{
|
||||
my $mesh = $self->input_file =~ /\.stl$/i
|
||||
@ -38,7 +38,7 @@ sub go {
|
||||
# make perimeters
|
||||
# this will add a set of extrusion loops to each layer
|
||||
# as well as generate infill boundaries
|
||||
$self->status_cb->(20, "Generating perimeters...");
|
||||
$self->status_cb->(20, "Generating perimeters");
|
||||
{
|
||||
my $perimeter_maker = Slic3r::Perimeter->new;
|
||||
$perimeter_maker->make_perimeter($_) for @{$print->layers};
|
||||
@ -46,42 +46,42 @@ sub go {
|
||||
|
||||
# this will clip $layer->surfaces to the infill boundaries
|
||||
# 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;
|
||||
|
||||
# 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};
|
||||
|
||||
# this will remove unprintable surfaces
|
||||
# (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};
|
||||
|
||||
# this will detect bridges and reverse bridges
|
||||
# and rearrange top/bottom/internal surfaces
|
||||
$self->status_cb->(45, "Detect bridges...");
|
||||
$self->status_cb->(45, "Detect bridges");
|
||||
$_->process_bridges for @{$print->layers};
|
||||
|
||||
# this will remove unprintable perimeter loops
|
||||
# (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};
|
||||
|
||||
# detect which fill surfaces are near external layers
|
||||
# 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;
|
||||
|
||||
# free memory
|
||||
@{$_->surfaces} = () for @{$print->layers};
|
||||
|
||||
# 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;
|
||||
|
||||
# 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);
|
||||
|
||||
@ -116,17 +116,27 @@ sub go {
|
||||
|
||||
# generate support material
|
||||
if ($Slic3r::support_material) {
|
||||
$self->status_cb->(85, "Generating support material...");
|
||||
$self->status_cb->(85, "Generating support material");
|
||||
$print->generate_support_material;
|
||||
}
|
||||
|
||||
# make skirt
|
||||
$self->status_cb->(88, "Generating skirt...");
|
||||
$self->status_cb->(88, "Generating skirt");
|
||||
$print->extrude_skirt;
|
||||
|
||||
# output everything to a GCODE file
|
||||
$self->status_cb->(90, "Exporting GCODE...");
|
||||
$print->export_gcode($self->expanded_output_filepath);
|
||||
$self->status_cb->(90, "Exporting GCODE");
|
||||
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
|
||||
$self->processing_time(tv_interval($t0));
|
||||
|
@ -79,6 +79,10 @@ if ($ARGV[0]) {
|
||||
my $skein = Slic3r::Skein->new(
|
||||
input_file => $input_file,
|
||||
output_file => $opt{output},
|
||||
status_cb => sub {
|
||||
my ($percent, $message) = @_;
|
||||
printf "=> $message\n";
|
||||
},
|
||||
);
|
||||
$skein->go;
|
||||
|
||||
@ -108,6 +112,8 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
|
||||
Output file name format; all config options enclosed in brackets
|
||||
will be replaced by their values, as well as [input_filename_base]
|
||||
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:
|
||||
--nozzle-diameter Diameter of nozzle in mm (default: $Slic3r::nozzle_diameter)
|
||||
|
@ -1,11 +1,12 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/perl -i
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $z = 0;
|
||||
|
||||
# read stdin and any/all files passed as parameters one line at a time
|
||||
for (<>) {
|
||||
while (<>) {
|
||||
# if we find a Z word, save it
|
||||
$z = $1 if /Z(\d+(\.\d+)?)/;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user