mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			142 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| package Slic3r::SVG;
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| use SVG;
 | |
| 
 | |
| use constant X => 0;
 | |
| use constant Y => 1;
 | |
| 
 | |
| our $filltype = 'evenodd';
 | |
| 
 | |
| sub factor {
 | |
|     return &Slic3r::SCALING_FACTOR * 10;
 | |
| }
 | |
| 
 | |
| sub svg {
 | |
|     my $svg = SVG->new(width => 200 * 10, height => 200 * 10);
 | |
|     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;
 | |
| }
 | |
| 
 | |
| sub output {
 | |
|     my ($filename, @things) = @_;
 | |
|     
 | |
|     my $svg = svg();
 | |
|     my $arrows = 1;
 | |
|     
 | |
|     while (my $type = shift @things) {
 | |
|         my $value = shift @things;
 | |
|         
 | |
|         if ($type eq 'no_arrows') {
 | |
|             $arrows = 0;
 | |
|         } elsif ($type =~ /^(?:(.+?)_)?expolygons$/) {
 | |
|             my $colour = $1;
 | |
|             $value = [ map $_->pp, @$value ];
 | |
|             
 | |
|             my $g = $svg->group(
 | |
|                 style => {
 | |
|                     'stroke-width' => 0,
 | |
|                     'stroke' => $colour || 'black',
 | |
|                     'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')),
 | |
|                     'fill-type' => $filltype,
 | |
|                 },
 | |
|             );
 | |
|             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);
 | |
|             $value = [ map $_->pp, @$value ];
 | |
|             
 | |
|             my $g = $svg->group(
 | |
|                 style => {
 | |
|                     'stroke-width' => ($method eq 'polyline') ? 1 : 0,
 | |
|                     'stroke' => $colour || 'black',
 | |
|                     'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')),
 | |
|                 },
 | |
|             );
 | |
|             foreach my $polygon (@$value) {
 | |
|                 my $path = $svg->get_path(
 | |
|                     'x' => [ map($_->[X] * factor(), @$polygon) ],
 | |
|                     'y' => [ map($_->[Y] * factor(), @$polygon) ],
 | |
|                     -type => 'polygon',
 | |
|                 );
 | |
|                 $g->$method(
 | |
|                     %$path,
 | |
|                     'marker-end' => !$arrows ? "" : "url(#endArrow)",
 | |
|                 );
 | |
|             }
 | |
|         } elsif ($type =~ /^(?:(.+?)_)?points$/) {
 | |
|             my $colour = $1 // 'black';
 | |
|             my $r = $colour eq 'black' ? 1 : 3;
 | |
|             $value = [ map $_->pp, @$value ];
 | |
|             
 | |
|             my $g = $svg->group(
 | |
|                 style => {
 | |
|                     'stroke-width' => 2,
 | |
|                     'stroke' => $colour,
 | |
|                     'fill' => $colour,
 | |
|                 },
 | |
|             );
 | |
|             foreach my $point (@$value) {
 | |
|                 $g->circle(
 | |
|                     cx      => $point->[X] * factor(),
 | |
|                     cy      => $point->[Y] * factor(),
 | |
|                     r       => $r,
 | |
|                 );
 | |
|             }
 | |
|         } elsif ($type =~ /^(?:(.+?)_)?lines$/) {
 | |
|             my $colour = $1;
 | |
|             $value = [ map $_->pp, @$value ];
 | |
|             
 | |
|             my $g = $svg->group(
 | |
|                 style => {
 | |
|                     'stroke-width' => 2,
 | |
|                 },
 | |
|             );
 | |
|             foreach my $line (@$value) {
 | |
|                 $g->line(
 | |
|                     x1 => $line->[0][X] * factor(),
 | |
|                     y1 => $line->[0][Y] * factor(),
 | |
|                     x2 => $line->[1][X] * factor(),
 | |
|                     y2 => $line->[1][Y] * factor(),
 | |
|                     style => {
 | |
|                         'stroke' => $colour || 'black',
 | |
|                     },
 | |
|                     'marker-end' => !$arrows ? "" : "url(#endArrow)",
 | |
|                 );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     write_svg($svg, $filename);
 | |
| }
 | |
| 
 | |
| sub write_svg {
 | |
|     my ($svg, $filename) = @_;
 | |
|     
 | |
|     Slic3r::open(\my $fh, '>', $filename);
 | |
|     print $fh $svg->xmlify;
 | |
|     close $fh;
 | |
|     printf "SVG written to %s\n", $filename;
 | |
| }
 | |
| 
 | |
| 1;
 | 
