2011-09-18 17:28:12 +00:00
|
|
|
package Slic3r::SVG;
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use SVG;
|
|
|
|
|
|
|
|
use constant X => 0;
|
|
|
|
use constant Y => 1;
|
|
|
|
|
2013-03-11 13:23:45 +00:00
|
|
|
our $filltype = 'evenodd';
|
|
|
|
|
2013-05-18 14:48:26 +00:00
|
|
|
sub factor {
|
2012-07-27 19:13:03 +00:00
|
|
|
return &Slic3r::SCALING_FACTOR * 10;
|
2011-09-18 17:28:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub svg {
|
2012-05-01 16:51:47 +00:00
|
|
|
my $svg = SVG->new(width => 200 * 10, height => 200 * 10);
|
2011-10-08 17:02:05 +00:00
|
|
|
my $marker_end = $svg->marker(
|
|
|
|
id => "endArrow",
|
|
|
|
viewBox => "0 0 10 10",
|
|
|
|
refX => "1",
|
|
|
|
refY => "5",
|
|
|
|
markerUnits => "strokeWidth",
|
|
|
|
orient => "auto",
|
|
|
|
markerWidth => "10",
|
|
|
|
markerHeight => "8",
|
|
|
|
);
|
|
|
|
$marker_end->polyline(
|
|
|
|
points => "0,0 10,5 0,10 1,5",
|
|
|
|
fill => "darkblue",
|
|
|
|
);
|
|
|
|
|
|
|
|
return $svg;
|
2011-09-18 17:28:12 +00:00
|
|
|
}
|
|
|
|
|
2011-10-06 09:55:26 +00:00
|
|
|
sub output {
|
2013-08-13 08:34:49 +00:00
|
|
|
my ($filename, @things) = @_;
|
2011-09-26 12:48:22 +00:00
|
|
|
|
2012-11-01 10:34:53 +00:00
|
|
|
my $svg = svg();
|
2013-08-13 08:34:49 +00:00
|
|
|
my $arrows = 1;
|
2011-10-06 09:55:26 +00:00
|
|
|
|
2013-08-13 08:34:49 +00:00
|
|
|
while (my $type = shift @things) {
|
|
|
|
my $value = shift @things;
|
|
|
|
|
|
|
|
if ($type eq 'no_arrows') {
|
|
|
|
$arrows = 0;
|
|
|
|
} elsif ($type =~ /^(?:(.+?)_)?expolygons$/) {
|
|
|
|
my $colour = $1;
|
2013-09-16 15:44:30 +00:00
|
|
|
$value = [ map $_->pp, @$value ];
|
2013-08-13 08:34:49 +00:00
|
|
|
|
|
|
|
my $g = $svg->group(
|
|
|
|
style => {
|
|
|
|
'stroke-width' => 2,
|
|
|
|
'stroke' => $colour || 'black',
|
|
|
|
'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')),
|
|
|
|
'fill-type' => $filltype,
|
|
|
|
},
|
2013-03-11 13:23:45 +00:00
|
|
|
);
|
2013-08-13 08:34:49 +00:00
|
|
|
foreach my $expolygon (@$value) {
|
|
|
|
my $points = join ' ', map "M $_ z", map join(" ", reverse map $_->[0]*factor() . " " . $_->[1]*factor(), @$_), @$expolygon;
|
|
|
|
$g->path(
|
|
|
|
d => $points,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} elsif ($type =~ /^(?:(.+?)_)?(polygon|polyline)s$/) {
|
|
|
|
my ($colour, $method) = ($1, $2);
|
2013-09-16 15:44:30 +00:00
|
|
|
$value = [ map $_->pp, @$value ];
|
2013-08-13 08:34:49 +00:00
|
|
|
|
2011-10-06 09:55:26 +00:00
|
|
|
my $g = $svg->group(
|
|
|
|
style => {
|
|
|
|
'stroke-width' => 2,
|
2011-11-27 10:40:03 +00:00
|
|
|
'stroke' => $colour || 'black',
|
2011-10-09 17:47:21 +00:00
|
|
|
'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')),
|
2011-10-06 09:55:26 +00:00
|
|
|
},
|
|
|
|
);
|
2013-08-13 08:34:49 +00:00
|
|
|
foreach my $polygon (@$value) {
|
2011-10-06 09:55:26 +00:00
|
|
|
my $path = $svg->get_path(
|
|
|
|
'x' => [ map($_->[X] * factor(), @$polygon) ],
|
|
|
|
'y' => [ map($_->[Y] * factor(), @$polygon) ],
|
|
|
|
-type => 'polygon',
|
|
|
|
);
|
|
|
|
$g->$method(
|
|
|
|
%$path,
|
2013-08-19 10:16:19 +00:00
|
|
|
'marker-end' => !$arrows ? "" : "url(#endArrow)",
|
2011-10-06 09:55:26 +00:00
|
|
|
);
|
|
|
|
}
|
2013-08-13 08:34:49 +00:00
|
|
|
} elsif ($type =~ /^(?:(.+?)_)?points$/) {
|
2013-09-02 20:10:52 +00:00
|
|
|
my $colour = $1 // 'black';
|
2013-09-16 15:44:30 +00:00
|
|
|
my $r = $colour eq 'black' ? 1 : 3;
|
|
|
|
$value = [ map $_->pp, @$value ];
|
2013-08-13 08:34:49 +00:00
|
|
|
|
2011-10-06 09:55:26 +00:00
|
|
|
my $g = $svg->group(
|
|
|
|
style => {
|
|
|
|
'stroke-width' => 2,
|
2011-10-07 17:07:57 +00:00
|
|
|
'stroke' => $colour,
|
2011-10-06 09:55:26 +00:00
|
|
|
'fill' => $colour,
|
|
|
|
},
|
|
|
|
);
|
2013-08-13 08:34:49 +00:00
|
|
|
foreach my $point (@$value) {
|
2011-10-06 09:55:26 +00:00
|
|
|
$g->circle(
|
|
|
|
cx => $point->[X] * factor(),
|
|
|
|
cy => $point->[Y] * factor(),
|
|
|
|
r => $r,
|
|
|
|
);
|
|
|
|
}
|
2013-08-13 08:34:49 +00:00
|
|
|
} elsif ($type =~ /^(?:(.+?)_)?lines$/) {
|
|
|
|
my $colour = $1;
|
2013-09-16 15:44:30 +00:00
|
|
|
$value = [ map $_->pp, @$value ];
|
2013-08-13 08:34:49 +00:00
|
|
|
|
2011-10-06 09:55:26 +00:00
|
|
|
my $g = $svg->group(
|
|
|
|
style => {
|
|
|
|
'stroke-width' => 2,
|
|
|
|
},
|
|
|
|
);
|
2013-08-13 08:34:49 +00:00
|
|
|
foreach my $line (@$value) {
|
2011-10-06 09:55:26 +00:00
|
|
|
$g->line(
|
|
|
|
x1 => $line->[0][X] * factor(),
|
|
|
|
y1 => $line->[0][Y] * factor(),
|
|
|
|
x2 => $line->[1][X] * factor(),
|
|
|
|
y2 => $line->[1][Y] * factor(),
|
|
|
|
style => {
|
2011-10-08 17:02:05 +00:00
|
|
|
'stroke' => $colour || 'black',
|
2011-10-06 09:55:26 +00:00
|
|
|
},
|
2013-08-19 10:16:19 +00:00
|
|
|
'marker-end' => !$arrows ? "" : "url(#endArrow)",
|
2011-10-06 09:55:26 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2011-09-26 12:48:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
write_svg($svg, $filename);
|
|
|
|
}
|
|
|
|
|
2011-09-18 17:28:12 +00:00
|
|
|
sub write_svg {
|
|
|
|
my ($svg, $filename) = @_;
|
|
|
|
|
2013-01-13 09:18:34 +00:00
|
|
|
Slic3r::open(\my $fh, '>', $filename);
|
2011-09-18 17:28:12 +00:00
|
|
|
print $fh $svg->xmlify;
|
|
|
|
close $fh;
|
|
|
|
printf "SVG written to %s\n", $filename;
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|