mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	SVG export
This commit is contained in:
		
							parent
							
								
									5bd16ffed6
								
							
						
					
					
						commit
						32c46f0ea3
					
				
					 5 changed files with 79 additions and 13 deletions
				
			
		|  | @ -37,12 +37,14 @@ sub OnInit { | |||
|     $fileMenu->Append(3, "Slice…"); | ||||
|     $fileMenu->Append(4, "Reslice"); | ||||
|     $fileMenu->Append(5, "Slice and Save As…"); | ||||
|     $fileMenu->Append(6, "Export SVG…"); | ||||
|     $menubar->Append($fileMenu, "&File"); | ||||
|     EVT_MENU($frame, 1, sub { $panel->save_config }); | ||||
|     EVT_MENU($frame, 2, sub { $panel->load_config }); | ||||
|     EVT_MENU($frame, 3, sub { $panel->do_slice }); | ||||
|     EVT_MENU($frame, 4, sub { $panel->do_slice(reslice => 1) }); | ||||
|     EVT_MENU($frame, 5, sub { $panel->do_slice(save_as => 1) }); | ||||
|     EVT_MENU($frame, 6, sub { $panel->do_slice(save_as => 1, export_svg => 1) }); | ||||
|      | ||||
|     $box->SetSizeHints($frame); | ||||
|     $frame->SetSizer($box); | ||||
|  |  | |||
|  | @ -222,7 +222,8 @@ sub do_slice { | |||
|             } | ||||
|         } elsif ($params{save_as}) { | ||||
|             my $output_file = $skein->expanded_output_filepath; | ||||
|             my $dlg = Wx::FileDialog->new($self, 'Save gcode file as:', dirname($output_file), | ||||
|             $output_file =~ s/\.gcode$/.svg/i if $params{export_svg}; | ||||
|             my $dlg = Wx::FileDialog->new($self, 'Save ' . ($params{export_svg} ? 'SVG' : 'G-code') . ' file as:', dirname($output_file), | ||||
|                 basename($output_file), $gcode_wildcard, wxFD_SAVE); | ||||
|             return if $dlg->ShowModal != wxID_OK; | ||||
|             $skein->output_file($dlg->GetPath); | ||||
|  | @ -237,15 +238,22 @@ sub do_slice { | |||
|         { | ||||
|             my @warnings = (); | ||||
|             local $SIG{__WARN__} = sub { push @warnings, $_[0] }; | ||||
|             $skein->go; | ||||
|             if ($params{export_svg}) { | ||||
|                 $skein->export_svg; | ||||
|             } else { | ||||
|                 $skein->go; | ||||
|             } | ||||
|             $self->catch_warning->($_) for @warnings; | ||||
|         } | ||||
|         $process_dialog->Destroy; | ||||
|         undef $process_dialog; | ||||
|          | ||||
|         my $message = sprintf "%s was successfully sliced in %d minutes and %.3f seconds.", | ||||
|             $input_file_basename, int($skein->processing_time/60), | ||||
|             $skein->processing_time - int($skein->processing_time/60)*60; | ||||
|         my $message = "$input_file_basename was successfully sliced"; | ||||
|         $message .= sprintf " in %d minutes and %.3f seconds", | ||||
|             int($skein->processing_time/60), | ||||
|             $skein->processing_time - int($skein->processing_time/60)*60 | ||||
|             if $skein->processing_time; | ||||
|         $message .= "."; | ||||
|         eval { | ||||
|             $self->{growler}->notify(Event => 'SKEIN_DONE', Title => 'Slicing Done!', Message => $message) | ||||
|                 if ($self->{growler}); | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ use Moo; | |||
| 
 | ||||
| use Config; | ||||
| use File::Basename qw(basename fileparse); | ||||
| use Slic3r::Geometry qw(PI); | ||||
| use Slic3r::Geometry qw(PI unscale); | ||||
| use Time::HiRes qw(gettimeofday tv_interval); | ||||
| use XXX; | ||||
| 
 | ||||
|  | @ -17,14 +17,9 @@ has 'output_file'   => (is => 'rw', required => 0); | |||
| has 'status_cb'     => (is => 'rw', required => 0, default => sub { sub {} }); | ||||
| has 'processing_time' => (is => 'rw', required => 0); | ||||
| 
 | ||||
| sub go { | ||||
| sub slice_input { | ||||
|     my $self = shift; | ||||
|     my $t0 = [gettimeofday]; | ||||
|      | ||||
|     # skein the STL into layers | ||||
|     # each layer has surfaces with holes | ||||
|     $self->status_cb->(5, "Processing input file " . $self->input_file);     | ||||
|     $self->status_cb->(10, "Processing triangulated mesh"); | ||||
|     my $print; | ||||
|     if ($self->input_file =~ /\.stl$/i) { | ||||
|         my $mesh = Slic3r::Format::STL->read_file($self->input_file); | ||||
|  | @ -37,6 +32,17 @@ sub go { | |||
|     } else { | ||||
|         die "Input file must have .stl or .amf(.xml) extension\n"; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sub go { | ||||
|     my $self = shift; | ||||
|     my $t0 = [gettimeofday]; | ||||
|      | ||||
|     # skein the STL into layers | ||||
|     # each layer has surfaces with holes | ||||
|     $self->status_cb->(5, "Processing input file " . $self->input_file);     | ||||
|     $self->status_cb->(10, "Processing triangulated mesh"); | ||||
|     my $print = $self->slice_input; | ||||
|      | ||||
|     # make perimeters | ||||
|     # this will add a set of extrusion loops to each layer | ||||
|  | @ -152,6 +158,49 @@ sub go { | |||
|         $print->total_extrusion_length, $print->total_extrusion_volume; | ||||
| } | ||||
| 
 | ||||
| sub export_svg { | ||||
|     my $self = shift; | ||||
|      | ||||
|     my $print = $self->slice_input; | ||||
|     my $output_file = $self->expanded_output_filepath; | ||||
|     $output_file =~ s/\.gcode$/.svg/i; | ||||
|      | ||||
|     open my $fh, ">", $output_file or die "Failed to open $output_file for writing\n"; | ||||
|     print "Exporting to $output_file..."; | ||||
|     print $fh sprintf <<"EOF", unscale($print->total_x_length), unscale($print->total_y_length); | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> | ||||
| <svg width="%s" height="%s" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||||
| EOF | ||||
|      | ||||
|     my $print_polygon = sub { | ||||
|         my ($polygon, $fill) = @_; | ||||
|         printf $fh qq{    <polygon points="%s" style="fill: %s" />}, | ||||
|             (join ' ', map { join ',', map unscale $_, @$_ } @$polygon), $fill; | ||||
|     }; | ||||
|      | ||||
|     foreach my $layer (@{$print->layers}) { | ||||
|         printf $fh qq{  <g id="layer%d">\n}, $layer->id; | ||||
|         # sort slices so that the outermost ones come first | ||||
|         my @slices = sort { $a->expolygon->contour->encloses_point($b->expolygon->contour->[0]) ? 0 : 1 } @{$layer->slices}; | ||||
|         foreach my $slice (@slices) { | ||||
|             $print_polygon->($slice->expolygon->contour, 'black'); | ||||
|             $print_polygon->($_, 'white') for $slice->expolygon->holes; | ||||
|         } | ||||
|         print $fh qq{  </g>\n}; | ||||
|     } | ||||
|      | ||||
|     print $fh <<"EOF"; | ||||
| 	<!--  | ||||
| 	Generated using Slic3r $Slic3r::VERSION | ||||
| 	http://slic3r.org/ | ||||
|      --> | ||||
| </svg> | ||||
| EOF | ||||
|     close $fh; | ||||
|     print "Done.\n"; | ||||
| } | ||||
| 
 | ||||
| # this method will return the value of $self->output_file after expanding its | ||||
| # format variables with their values | ||||
| sub expanded_output_filepath { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci