~ubuntu-branches/ubuntu/utopic/slic3r/utopic

« back to all changes in this revision

Viewing changes to utils/gcode_sectioncut.pl

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2014-06-17 01:27:26 UTC
  • Revision ID: package-import@ubuntu.com-20140617012726-2wrs4zdo251nr4vg
Tags: upstream-1.1.4+dfsg
ImportĀ upstreamĀ versionĀ 1.1.4+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
# This script generates section cuts from a given G-Code file
 
3
 
 
4
use strict;
 
5
use warnings;
 
6
 
 
7
BEGIN {
 
8
    use FindBin;
 
9
    use lib "$FindBin::Bin/../lib";
 
10
}
 
11
 
 
12
use Getopt::Long qw(:config no_auto_abbrev);
 
13
use IO::All;
 
14
use List::Util qw(max);
 
15
use Slic3r;
 
16
use Slic3r::Geometry qw(X Y A B X1 Y1 X2 Y2);
 
17
use Slic3r::Geometry::Clipper qw(JT_SQUARE);
 
18
use Slic3r::Test;
 
19
use SVG;
 
20
 
 
21
my %opt = (
 
22
    layer_height    => 0.2,
 
23
    extrusion_width => 0.5,
 
24
    scale           => 30,
 
25
);
 
26
{
 
27
    my %options = (
 
28
        'help'                  => sub { usage() },
 
29
        'layer-height|h=f'      => \$opt{layer_height},
 
30
        'extrusion-width|w=f'   => \$opt{extrusion_width},
 
31
        'scale|s=i'             => \$opt{scale},
 
32
    );
 
33
    GetOptions(%options) or usage(1);
 
34
    $ARGV[0] or usage(1);
 
35
}
 
36
 
 
37
{
 
38
    my $input_file = $ARGV[0];
 
39
    my $output_file = $input_file;
 
40
    $output_file =~ s/\.(?:gcode|gco|ngc|g)$/.svg/;
 
41
    
 
42
    # read paths
 
43
    my %paths = ();    # z => [ path, path ... ]
 
44
    Slic3r::GCode::Reader->new->parse(io($input_file)->all, sub {
 
45
        my ($self, $cmd, $args, $info) = @_;
 
46
        
 
47
        if ($cmd eq 'G1' && $info->{extruding}) {
 
48
            $paths{ $self->Z } ||= [];
 
49
            push @{ $paths{ $self->Z } }, Slic3r::Line->new(
 
50
                [ $self->X, $self->Y ],
 
51
                [ $info->{new_X}, $info->{new_Y} ],
 
52
            );
 
53
        }
 
54
    });
 
55
    
 
56
    # calculate print extents
 
57
    my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, values %paths ]);
 
58
    
 
59
    # calculate section line
 
60
    my $section_y = $bounding_box->center->[Y];
 
61
    my $section_line = [
 
62
        [ $bounding_box->x_min, $section_y ],
 
63
        [ $bounding_box->x_max, $section_y ],
 
64
    ];
 
65
    
 
66
    # initialize output
 
67
    my $max_z = max(keys %paths);
 
68
    my $svg = SVG->new(
 
69
        width  => $opt{scale} * $bounding_box->size->[X],
 
70
        height => $opt{scale} * $max_z,
 
71
    );
 
72
    
 
73
    # put everything into a group
 
74
    my $g = $svg->group(style => {
 
75
        'stroke-width'  => 1,
 
76
        'stroke'        => '#444444',
 
77
        'fill'          => 'grey',
 
78
    });
 
79
    
 
80
    # draw paths
 
81
    foreach my $z (sort keys %paths) {
 
82
        foreach my $line (@{ $paths{$z} }) {
 
83
            my @intersections = @{intersection_pl(
 
84
                [ $section_line ],
 
85
                [ _grow($line, $opt{extrusion_width}/2) ],
 
86
            )};
 
87
            
 
88
            $g->rectangle(
 
89
                'x'         => $opt{scale} * ($_->[A][X] - $bounding_box->x_min),
 
90
                'y'         => $opt{scale} * ($max_z - $z),
 
91
                'width'     => $opt{scale} * abs($_->[B][X] - $_->[A][X]),
 
92
                'height'    => $opt{scale} * $opt{layer_height},
 
93
                'rx'        => $opt{scale} * $opt{layer_height} * 0.35,
 
94
                'ry'        => $opt{scale} * $opt{layer_height} * 0.35,
 
95
            ) for @intersections;
 
96
        }
 
97
    }
 
98
    
 
99
    # write output
 
100
    Slic3r::open(\my $fh, '>', $output_file);
 
101
    print $fh $svg->xmlify;
 
102
    close $fh;
 
103
    printf "Section cut SVG written to %s\n", $output_file;
 
104
}
 
105
 
 
106
# replace built-in Line->grow method which relies on int_offset()
 
107
sub _grow {
 
108
    my ($line, $distance) = @_;
 
109
    
 
110
    my $polygon = [ @$line, CORE::reverse @$line[1..($#$line-1)] ];
 
111
    return @{Math::Clipper::offset([$polygon], $distance, 100000, JT_SQUARE, 2)};
 
112
}
 
113
 
 
114
sub usage {
 
115
    my ($exit_code) = @_;
 
116
    
 
117
    print <<"EOF";
 
118
Usage: gcode_sectioncut.pl [ OPTIONS ] file.gcode
 
119
 
 
120
    --help              Output this usage screen and exit
 
121
    --layer-height, -h  Use the specified layer height
 
122
    --extrusion-width, -w  Use the specified extrusion width
 
123
    --scale             Factor for converting G-code units to SVG units
 
124
    
 
125
EOF
 
126
    exit ($exit_code || 0);
 
127
}
 
128
 
 
129
__END__