1

Topic: Slic3r post processing scripts

Now that the Panelolu is up and running, I'm looking at the possibility of adding lines to the gcode that will display text giving print feedback.

Currently, after the initial heating, the message 'Heating Done.' appears and stays on the screen until the print is done. I would love for updates at the start of every layer like 'Printing layer 4 of 50'.

There seems to be two options for this in slic3r.

1. Under Printer Settings/Custom gcode, custom gcode can be placed in the 'Layer change g-code' field. Marlin has support for the M117 command, which outputs fine.

M117 test brings up 'test' on the LCD when the layer changes.

The trouble comes in using variables which would be ideal. It accepts certain variables like [layer_height]:

M117 layer height- [layer_height]
brings up:
'layer height- 0.25'

I've poked around an awful lot in the Slic3r source code and can only get pre-slicing input variables to work, not variables that are being set during the slicing like current layer or total.

Any help here is appreciated.

2. A post-processing script can be run to process g-code, but there is very little documentation for this. The script language is Perl, which doesn't seem to work very nicely with windows. I've installed Strawberry but I'm not sure if some of the test scripts I've found are doing anything or even running.

I prefer not to go down this path but perhaps it's the only way.

Any help or ideas are appreciated.

2

Re: Slic3r post processing scripts

Ok I've managed to get Repetier-Host to read perl scripts.

I have installed a windows version of perl (ActivePerl) but somewhere along the way the association for .pl files ended up pointing to the windows command line. After much head scratching and googling I've managed to fix that problem, and now can run .pl files with the output coming up on the Repetier-Host log.

The Repetier-Host documentation is very outdated but my plan is as follows:

1. Have a string inserted at each layer change.
2. Have the post script loop through the gcode, counting these strings to work out the total layer changes.
3. Have the same script loop through again and replace the string with a 'M117 Layer x / y' command.

3

Re: Slic3r post processing scripts

good plan, i had to modify a perl script that changed hex fikes .. perl is a freaky language, read some tutorials and learnt a lot but only just enough.
the search strings should be fairly straightforward at least.

i can find the script and post it here if you want since it woukd make a good basis for what you want to do, it reads files, mods and rewrites .. of course if you are comfortable with perl, just ignore me..

4

Re: Slic3r post processing scripts

Stoney,

I have enough other programming experience to follow the gist of the sample files, but the syntax and keywords are unfamiliar to me. I will do some reading up but anything you can post would be great.

#!/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
while (<>) {
    # if we find a Z word, save it
    $z = $1 if /Z(\d+(\.\d+)?)/;

    # if we don't have Z, but we do have X and Y
    if (!/Z/ && /X/ && /Y/ && $z > 0) {
        # chop off the end of the line (incl. comments), saving chopped section in $1
        s/\s*([\r\n\;\(].*)//s;
        # print start of line, insert our Z value then re-add the chopped end of line
        print "$_ Z$z $1";
    }
    else {
        # nothing interesting, print line as-is
        #print;
    }
}

That is from a sample slic3r file, except I'm getting an error for the while argument, even though all the examples use the <>.

5

Re: Slic3r post processing scripts

codepad had no problem with it http://codepad.org/Eg3pF6JT

heres the hex file one, bit different as it reads in the whole file first ..

#!/usr/bin/env perl

use strict;
use warnings;

my $lolimit = 0x800;
my $hilimit = 0xC000;

my $usage = sprintf "usage: %s output.bin input.hex [input.hex ...]

Parses the input hex files, trims the data outside 0x%04X and 0x%04X,
fills any holes between those addresses with 0xFF, and then writes the
output binary.
", $0, $lolimit, $hilimit;

die $usage if @ARGV < 2;

my $output = shift @ARGV;

my $base_address    = undef;
my $current_address = undef;
my %data            = ();

open OUTPUT, '>', $output or die "Couldn't open '$output': $!";
binmode OUTPUT;

while (<>) {
    if (/^:02000004(....)..\s*$/ ) {
        # :02000004 0000 FA

        $base_address = hex($1);
        printf "Base address: 0x%04X\n", $base_address;
    }
    elsif (/^:..(....)00 (.*)                             ..\s*$/x) {
        #    :04 1000 00 88313728                         D4
        #    :10 1008 00 883120007F08F4000B1D0B280C283328 9A

        # Catch cases where the file has no base address
        unless (defined $base_address) {
            print "No base address found!\n";
            print "Defaulting to 0x0000\n";
            $base_address = 0;
        }

        # Determine the address for this chunk of data
        my $current_address = $base_address + hex($1);
        printf "Next address: 0x%04X\n", $current_address;

        # Store the bytes against their address
        my @bytes = $2 =~ /(..)/g;
        $data{$current_address++} = hex($_) for @bytes;
    }
}

my $before = scalar keys %data;

for (sort {$a <=> $b} keys %data) {
    # Cull any data outside of lolimit and hilimit
    delete $data{$_} if $_ < $lolimit or $_ >= $hilimit;
}

my $after = scalar keys %data;

printf "Trimmed %d out-of-bound addresses\n", $before - $after;

my $pad_start = undef;

# NOTE: It would be more efficient to write the output file in this loop,
#       rather than filling up our hash only to loop over it once more
for (my $i = $lolimit; $i < $hilimit; ++$i) {
    if (not defined $data{$i}) {
        # Pad any unset addresses between lolimit and hilimit
        $data{$i} = 0xFF;
        # Record the start of a padding section
        $pad_start = $i unless defined $pad_start;
    }
    elsif (defined $pad_start) {
        # Record the end of a padding section
        printf "Padded between 0x%04X and 0x%04X (0x%04X bytes)\n",
            $pad_start, $i, $i - $pad_start;
        $pad_start = undef;
    }g
}

# Write the output file
for (sort {$a <=> $b} keys %data) {
    # printf "%4X %2X\n", $_, $data{$_};
    print OUTPUT chr($data{$_});
}

close OUTPUT;

6

Re: Slic3r post processing scripts

I've cracked it but the result is slightly compromised.

Basically it doesn't seem as if the slic3r variables are being passed as arguments as they should be. The main problem is the lack of filename argument, so that had to be hard coded.

Instructions:

1. You will need to install Perl. For windows, this will be in the form of Strawberry Perl or ActivePerl. Make sure that executing  .pl Perl scripts is allocated to the new Perl installation and not the windows command line.

2. In Slic3r, add 'M117' in the Printer Settings > Custom G-code > Layer change G-code field.

3. In Slic3r, add the absolute path to this script in the Print Setting > Output Options > Post-processing scripts field.

eg. C:\perls\add_M117_layer_info.pl

Choose a path without gaps in the filename path or else.

4. Slice a file from Repetier-Host and inspect the resultant g-code. All of the bare M117 lines should be fixed. The log will also prived info from the script.

Unfortunately when printing from Repetier-Host the M117 commands are sent muddled. I have posted an issue on Github for this. When printing from an SD card the M117 commands work beautifully.

#!/usr/bin/perl
#
# Copyright 2012 Michael Laws
#
# This script relies on 'M117' being placed in the Printer Settings > Custom G-code > Layer change G-code field.
# This script will count the number of M117 commands, then append each one to have Layer X of Y.
# If printing with a Panelolu, every time a new layer is started, the 'Layer X of Y' message will appear on the LCD.

use strict;
use warnings;
use English '-no_match_vars';
use File::Temp qw/ tempfile /;
use File::Copy qw/ move /;
#my $file_in = $ARGV[0];
my $file_in = 'D:\STL\composition.gcode';
print "Processing: $file_in\n";
open FILE1, $file_in;
open FILE2, $file_in;
my ($file_out_h, $file_out_name) = tempfile() or die( "Cannot open temp work file !" );
my $layer = 0;
my $layercount = 0;
while (<FILE1>) {
    if(/M117/) {
        $layercount++;
    }
}
print "$layercount layers detected.\n";
close FILE1;
while (<FILE2>) {
    if(/M117/) {
        $layer++;
        print $file_out_h "M117 Layer $layer of $layercount\n";
    } else {
        print $file_out_h $_;
    }
}
print "$layer M117 commands inserted.\n";
close $file_out_h;
move( $file_out_name, $file_in );
Post's attachments

add_M117_layer_info.pl 1.15 kb, 31 downloads since 2012-09-10 

You don't have the permssions to download the attachments of this post.

7

Re: Slic3r post processing scripts

Update!

Recently got this working using Repetier-Host instead of Slic3r to run the script. Now the filename parameter is passed properly.


Instructions:

1. You will need to install Perl. For windows, this will be in the form of Strawberry Perl or ActivePerl.

2. In Slic3r, add 'M117' in the Printer Settings > Custom G-code > Layer change G-code field.

3. Save the .pl file somewhere on your computer. In repetier-Host, add the following line to Config > Printer Settings > Advanced > Filter Path and Parameter:

perl C:\perls\add_M117_layer_info.pl #out

Obviously your directory may be different but leave the perl at the start and the #out at the end. Choose a path without gaps in the filename path or else.

4. Tick run filter after every slice.

If you don't want the M117 commands added every time, make another Slic3r profile that avoids step 2 of this guide. The perl script will still run, but it won't change the g-code at all. I have an 'SD-CARD' and default profile for this purpose.

5. Slice a file from Repetier-Host and inspect the resultant g-code. All of the bare M117 lines should be fixed. The log will also provide info from the script.

Unfortunately when printing from Repetier-Host the M117 commands are sent muddled. I have posted an issue on Github for this. When printing from an SD card (or from Pronterface) the M117 commands work beautifully.

#!/usr/bin/perl
#
# Copyright 2013 Michael Laws
#
# This script relies on 'M117' being placed in the Printer Settings > Custom G-code > Layer change G-code field.
# This script will count the number of M117 commands, then append each one to have Layer X of Y.
# If printing with a Panelolu, every time a new layer is started, the 'Layer X of Y' message will appear on the LCD.

use strict;
use warnings;
use English '-no_match_vars';
use File::Temp qw/ tempfile /;
use File::Copy qw/ move /;
my $file_in = $ARGV[0];
print "Processing: $file_in\n";
open FILE1, $file_in;
open FILE2, $file_in;
my ($file_out_h, $file_out_name) = tempfile() or die( "Cannot open temp work file !" );
my $layer = 0;
my $layercount = 0;
while (<FILE1>) {
    if(/M117/) {
        $layercount++;
    }
}
print "$layercount layers detected.\n";
close FILE1;
while (<FILE2>) {
    if(/M117/) {
        $layer++;
        print $file_out_h "M117 Layer $layer of $layercount\n";
    } else {
        print $file_out_h $_;
    }
}
print "$layer M117 commands inserted.\n";
close $file_out_h;
move( $file_out_name, $file_in );
Post's attachments

add_M117_layer_info.pl 1.11 kb, 9 downloads since 2013-01-17 

You don't have the permssions to download the attachments of this post.

8

Re: Slic3r post processing scripts

Maybe add a step to "Reboot your computer" after installing Perl.  I was getting an error in Repetier but the script ran fine from the command prompt.

Thanks again!

9 (edited by tecan 2018-07-10 03:16:34)

Re: Slic3r post processing scripts

lawsy what can i do with the copyright code ? can i modify it and post more plugins is rewriting allowed ? after reading how to do it are we not allowed to make derivative works ? kindof a strange thing to do.

10

Re: Slic3r post processing scripts

Hi there, modify as you like. I'm an open source kind of guy. That string is probably in there from whatever I started with, I probably changed my name but didn't pay attention to the rest.