mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	GUI
This commit is contained in:
		
							parent
							
								
									a311220c19
								
							
						
					
					
						commit
						f2f9178e07
					
				
					 9 changed files with 478 additions and 83 deletions
				
			
		
							
								
								
									
										4
									
								
								Build.PL
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								Build.PL
									
										
									
									
									
								
							|  | @ -8,11 +8,13 @@ my $build = Module::Build->new( | |||
|     license         => 'perl', | ||||
|     requires        => { | ||||
|         'CAD::Format::STL'          => '0', | ||||
|         'File::Basename'            => '0', | ||||
|         'Getopt::Long'              => '0', | ||||
|         'Math::Clipper'             => '1.00', | ||||
|         'Math::Clipper'             => '1.01', | ||||
|         'Math::Geometry::Planar'    => '0', | ||||
|         'Moo'                       => '0', | ||||
|         'Time::HiRes'               => '0', | ||||
|         'XXX'                       => '0', | ||||
|     }, | ||||
|     build_requires => { | ||||
|         'Test::More' => '0.10', | ||||
|  |  | |||
|  | @ -63,8 +63,12 @@ Download the package, open a terminal and cd to its directory. Then type: | |||
| 
 | ||||
|     perl Build.PL | ||||
| 
 | ||||
| This will install any required dependency. If you want to install slic3r.pl | ||||
| in your system path, type this as root: | ||||
| This will install any required dependency. If you want the GUI, you should | ||||
| also install Wx using the following command (as root): | ||||
| 
 | ||||
|     cpan Wx | ||||
| 
 | ||||
| If you want to install slic3r.pl in your system path, type this as root: | ||||
| 
 | ||||
|     ./Build install | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ sub debugf { | |||
|     printf @_ if $debug; | ||||
| } | ||||
| 
 | ||||
| use Slic3r::Config; | ||||
| use Slic3r::Extruder; | ||||
| use Slic3r::ExtrusionLoop; | ||||
| use Slic3r::ExtrusionPath; | ||||
|  | @ -21,6 +22,7 @@ use Slic3r::Point; | |||
| use Slic3r::Polyline; | ||||
| use Slic3r::Polyline::Closed; | ||||
| use Slic3r::Print; | ||||
| use Slic3r::Skein; | ||||
| use Slic3r::STL; | ||||
| use Slic3r::Surface; | ||||
| use Slic3r::Surface::Collection; | ||||
|  |  | |||
							
								
								
									
										72
									
								
								lib/Slic3r/Config.pm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								lib/Slic3r/Config.pm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | |||
| package Slic3r::Config; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| use constant PI => 4 * atan2(1, 1); | ||||
| 
 | ||||
| sub validate { | ||||
|     my $class = shift; | ||||
| 
 | ||||
|     # --layer-height | ||||
|     die "Invalid value for --layer-height\n" | ||||
|         if $Slic3r::layer_height <= 0; | ||||
|     die "--layer-height must be a multiple of print resolution\n" | ||||
|         if $Slic3r::layer_height / $Slic3r::resolution % 1 != 0; | ||||
|      | ||||
|     # --filament-diameter | ||||
|     die "Invalid value for --filament-diameter\n" | ||||
|         if $Slic3r::filament_diameter < 1; | ||||
|      | ||||
|     # --nozzle-diameter | ||||
|     die "Invalid value for --nozzle-diameter\n" | ||||
|         if $Slic3r::nozzle_diameter < 0; | ||||
|     die "--layer-height can't be greater than --nozzle-diameter\n" | ||||
|         if $Slic3r::layer_height > $Slic3r::nozzle_diameter; | ||||
|     $Slic3r::flow_width = ($Slic3r::nozzle_diameter**2)  | ||||
|         * $Slic3r::thickness_ratio * PI / (4 * $Slic3r::layer_height); | ||||
|      | ||||
|     my $max_flow_width = $Slic3r::layer_height + $Slic3r::nozzle_diameter; | ||||
|     if ($Slic3r::flow_width > $max_flow_width) { | ||||
|         $Slic3r::thickness_ratio = $max_flow_width / $Slic3r::flow_width; | ||||
|         $Slic3r::flow_width = $max_flow_width; | ||||
|     } | ||||
|      | ||||
|     Slic3r::debugf "Flow width = $Slic3r::flow_width\n"; | ||||
|      | ||||
|     # --perimeters | ||||
|     die "Invalid value for --perimeters\n" | ||||
|         if $Slic3r::perimeter_offsets < 1; | ||||
|      | ||||
|     # --solid-layers | ||||
|     die "Invalid value for --solid-layers\n" | ||||
|         if $Slic3r::solid_layers < 1; | ||||
|      | ||||
|     # --print-center | ||||
|     die "Invalid value for --print-center\n" | ||||
|         if !ref $Slic3r::print_center  | ||||
|             && (!$Slic3r::print_center || $Slic3r::print_center !~ /^\d+,\d+$/); | ||||
|     $Slic3r::print_center = [ split /,/, $Slic3r::print_center ] | ||||
|         if !ref $Slic3r::print_center; | ||||
|      | ||||
|     # --fill-density | ||||
|     die "Invalid value for --fill-density\n" | ||||
|         if $Slic3r::fill_density < 0 || $Slic3r::fill_density > 1; | ||||
|      | ||||
|     # --scale | ||||
|     die "Invalid value for --scale\n" | ||||
|         if $Slic3r::scale <= 0; | ||||
|      | ||||
|     # --multiply-x | ||||
|     die "Invalid value for --multiply-x\n" | ||||
|         if $Slic3r::multiply_x < 1; | ||||
|      | ||||
|     # --multiply-y | ||||
|     die "Invalid value for --multiply-y\n" | ||||
|         if $Slic3r::multiply_y < 1; | ||||
|      | ||||
|     # --multiply-distance | ||||
|     die "Invalid value for --multiply-distance\n" | ||||
|         if $Slic3r::multiply_distance < 1; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
							
								
								
									
										44
									
								
								lib/Slic3r/GUI.pm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								lib/Slic3r/GUI.pm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| package Slic3r::GUI; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| use Slic3r::GUI::OptionsGroup; | ||||
| use Slic3r::GUI::SkeinPanel; | ||||
| 
 | ||||
| use Wx qw(:sizer :frame wxID_EXIT wxID_ABOUT); | ||||
| use Wx::Event qw(EVT_MENU); | ||||
| use base 'Wx::App'; | ||||
| 
 | ||||
| sub OnInit { | ||||
|     my $self = shift; | ||||
|      | ||||
|     #$self->SetIcon(Wx::Icon->new("path/to/my/icon.gif", wxBITMAP_TYPE_GIF) ); | ||||
|      | ||||
|     my $frame = Wx::Frame->new( undef, -1, 'Slic3r', [-1, -1], Wx::wxDefaultSize, | ||||
|          wxDEFAULT_FRAME_STYLE ^ (wxRESIZE_BORDER | wxMAXIMIZE_BOX) ); | ||||
|      | ||||
|     # menubar | ||||
|     my $menubar = Wx::MenuBar->new; | ||||
|     $frame->SetMenuBar($menubar); | ||||
|     EVT_MENU($frame, wxID_EXIT, sub {$_[0]->Close(1)}); | ||||
|     EVT_MENU($frame, wxID_ABOUT, \&About); | ||||
|      | ||||
|     my $panel = Slic3r::GUI::SkeinPanel->new($frame); | ||||
|     my $box = Wx::BoxSizer->new(wxVERTICAL); | ||||
|     $box->Add($panel, 0, wxALL, 20); | ||||
|      | ||||
|     $frame->SetSizerAndFit($box); | ||||
|     $frame->Show; | ||||
| } | ||||
| 
 | ||||
| sub About { | ||||
|     my $frame = shift; | ||||
|      | ||||
|     my $info = Wx::AboutDialogInfo->new; | ||||
|     $info->SetName('Slic3r'); | ||||
|     $info->AddDeveloper('Alessandro Ranellucci'); | ||||
|      | ||||
|     Wx::AboutBox($info); | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
							
								
								
									
										50
									
								
								lib/Slic3r/GUI/OptionsGroup.pm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								lib/Slic3r/GUI/OptionsGroup.pm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| package Slic3r::GUI::OptionsGroup; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| use Wx qw(:sizer); | ||||
| use Wx::Event qw(EVT_TEXT EVT_CHECKBOX); | ||||
| use base 'Wx::StaticBoxSizer'; | ||||
| 
 | ||||
| sub new { | ||||
|     my $class = shift; | ||||
|     my ($parent, %p) = @_; | ||||
|      | ||||
|     my $box = Wx::StaticBox->new($parent, -1, $p{title}); | ||||
|     my $self = $class->SUPER::new($box, wxVERTICAL); | ||||
|      | ||||
|     my $grid_sizer = Wx::FlexGridSizer->new(scalar(@{$p{options}}), 2, 2, 0); | ||||
|      | ||||
|     foreach my $opt (@{$p{options}}) { | ||||
|         my $label = Wx::StaticText->new($parent, -1, "$opt->{label}:", Wx::wxDefaultPosition, [180,-1]); | ||||
|         my $field; | ||||
|         if ($opt->{type} =~ /^(i|f)$/) { | ||||
|             $field = Wx::TextCtrl->new($parent, -1, ${$opt->{value}}); | ||||
|             EVT_TEXT($parent, $field, sub { ${$opt->{value}} = $field->GetValue }); | ||||
|         } elsif ($opt->{type} eq 'bool') { | ||||
|             $field = Wx::CheckBox->new($parent, -1, ""); | ||||
|             $field->SetValue(${$opt->{value}}); | ||||
|             EVT_TEXT($parent, $field, sub { ${$opt->{value}} = $field->GetValue }); | ||||
|         } elsif ($opt->{type} eq 'point') { | ||||
|             $field = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|             my $field_size = Wx::Size->new(40, -1); | ||||
|             $field->Add($_) for ( | ||||
|                 Wx::StaticText->new($parent, -1, "x:"), | ||||
|                 my $x_field = Wx::TextCtrl->new($parent, -1, ${$opt->{value}}->[0], Wx::wxDefaultPosition, $field_size), | ||||
|                 Wx::StaticText->new($parent, -1, "  y:"), | ||||
|                 my $y_field = Wx::TextCtrl->new($parent, -1, ${$opt->{value}}->[1], Wx::wxDefaultPosition, $field_size), | ||||
|             ); | ||||
|             EVT_TEXT($parent, $x_field, sub { ${$opt->{value}}->[0] = $x_field->GetValue }); | ||||
|             EVT_TEXT($parent, $y_field, sub { ${$opt->{value}}->[1] = $y_field->GetValue }); | ||||
|         } else { | ||||
|             die "Unsupported option type: " . $opt->{type}; | ||||
|         } | ||||
|         $grid_sizer->Add($_) for $label, $field; | ||||
|     } | ||||
|      | ||||
|     $self->Add($grid_sizer, 0, wxEXPAND); | ||||
|      | ||||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
							
								
								
									
										255
									
								
								lib/Slic3r/GUI/SkeinPanel.pm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								lib/Slic3r/GUI/SkeinPanel.pm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,255 @@ | |||
| package Slic3r::GUI::SkeinPanel; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| use File::Basename qw(basename); | ||||
| use Wx qw(:sizer :progressdialog wxOK wxICON_INFORMATION wxICON_ERROR wxID_OK wxFD_OPEN); | ||||
| use Wx::Event qw(EVT_BUTTON); | ||||
| use base 'Wx::Panel'; | ||||
| 
 | ||||
| sub new { | ||||
|     my $class = shift; | ||||
|     my ($parent) = @_; | ||||
|     my $self = $class->SUPER::new($parent, -1); | ||||
|      | ||||
|     my %panels = ( | ||||
|         printer => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Printer', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Nozzle diameter', | ||||
|                     value   => \$Slic3r::nozzle_diameter, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Print center', | ||||
|                     value   => \$Slic3r::print_center, | ||||
|                     type    => 'point', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Use relative E distances', | ||||
|                     value   => \$Slic3r::use_relative_e_distances, | ||||
|                     type    => 'bool', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Z offset', | ||||
|                     value   => \$Slic3r::z_offset, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         filament => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Filament', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Diameter (mm)', | ||||
|                     value   => \$Slic3r::filament_diameter, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Packing density (mm)', | ||||
|                     value   => \$Slic3r::filament_packing_density, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         speed => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Speed', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Print feed rate (mm/s)', | ||||
|                     value   => \$Slic3r::print_feed_rate, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Travel feed rate (mm/s)', | ||||
|                     value   => \$Slic3r::travel_feed_rate, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Perimeter feed rate (mm/s)', | ||||
|                     value   => \$Slic3r::perimeter_feed_rate, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Bottom layer ratio', | ||||
|                     value   => \$Slic3r::bottom_layer_speed_ratio, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         accuracy => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Accuracy', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Layer height (mm)', | ||||
|                     value   => \$Slic3r::layer_height, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         print => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Print settings', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Perimeters', | ||||
|                     value   => \$Slic3r::perimeter_offsets, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Solid layers', | ||||
|                     value   => \$Slic3r::solid_layers, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Fill density', | ||||
|                     value   => \$Slic3r::fill_density, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Fill angle (°)', | ||||
|                     value   => \$Slic3r::fill_angle, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Temperature (°C)', | ||||
|                     value   => \$Slic3r::temperature, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         retract => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Retraction', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Length (mm)', | ||||
|                     value   => \$Slic3r::retract_length, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Speed (mm/s)', | ||||
|                     value   => \$Slic3r::retract_speed, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Extra length on restart (mm)', | ||||
|                     value   => \$Slic3r::retract_restart_extra, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Minimum travel after retraction (mm)', | ||||
|                     value   => \$Slic3r::retract_before_travel, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         skirt => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Skirt', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Loops', | ||||
|                     value   => \$Slic3r::skirts, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Distance from object (mm)', | ||||
|                     value   => \$Slic3r::skirt_distance, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|          | ||||
|         transform => Slic3r::GUI::OptionsGroup->new($self, | ||||
|             title => 'Transform', | ||||
|             options => [ | ||||
|                 { | ||||
|                     label   => 'Scale', | ||||
|                     value   => \$Slic3r::scale, | ||||
|                     type    => 'f', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Rotate (°)', | ||||
|                     value   => \$Slic3r::rotate, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Multiply along X', | ||||
|                     value   => \$Slic3r::multiply_x, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Multiply along Y', | ||||
|                     value   => \$Slic3r::multiply_y, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|                 { | ||||
|                     label   => 'Multiply distance', | ||||
|                     value   => \$Slic3r::multiply_distance, | ||||
|                     type    => 'i', | ||||
|                 }, | ||||
|             ], | ||||
|         ), | ||||
|     ); | ||||
|      | ||||
|     $panels{slice} = Wx::BoxSizer->new(wxVERTICAL); | ||||
|     $panels{slice}->Add(-1, 20);  # empty space before button | ||||
|     my $slice_button = Wx::Button->new($self, -1, "Slice..."); | ||||
|     $panels{slice}->Add($slice_button, 0, wxALIGN_CENTER); | ||||
|     EVT_BUTTON($self, $slice_button, \&do_slice); | ||||
|      | ||||
|     my @cols = ( | ||||
|         [qw(printer filament speed transform)], [qw(accuracy print retract skirt slice)], | ||||
|     ); | ||||
|      | ||||
|     my $sizer = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|     foreach my $col (@cols) { | ||||
|         my $vertical_sizer = Wx::BoxSizer->new(wxVERTICAL); | ||||
|         $vertical_sizer->Add($panels{$_}, 0, wxEXPAND | wxRIGHT, 10) for @$col; | ||||
|         $sizer->Add($vertical_sizer); | ||||
|     } | ||||
|      | ||||
|     $sizer->SetSizeHints($self); | ||||
|     $self->SetSizer($sizer); | ||||
|      | ||||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| sub do_slice { | ||||
|     my $self = shift; | ||||
|      | ||||
|     eval { | ||||
|         # validate configuration | ||||
|         Slic3r::Config->validate; | ||||
|          | ||||
|         # select input file | ||||
|         my $dialog = Wx::FileDialog->new($self, 'Choose a STL file to slice:', "", "", "*.stl", wxFD_OPEN); | ||||
|         return unless $dialog->ShowModal == wxID_OK; | ||||
|         my ($input_file) = $dialog->GetPaths; | ||||
|         my $input_file_basename = basename($input_file); | ||||
|          | ||||
|         # show processbar dialog | ||||
|         my $process_dialog = Wx::ProgressDialog->new('Slicing...', "Processing $input_file_basename...",  | ||||
|             100, $self, wxPD_APP_MODAL); | ||||
|         $process_dialog->Pulse; | ||||
|         my $skein = Slic3r::Skein->new( | ||||
|             input_file  => $input_file, | ||||
|         ); | ||||
|         $skein->go; | ||||
|         $process_dialog->Destroy; | ||||
|          | ||||
|         Wx::MessageDialog->new($self, "$input_file_basename was successfully sliced.", 'Done!',  | ||||
|             wxOK | wxICON_INFORMATION)->ShowModal; | ||||
|     }; | ||||
|      | ||||
|     if (my $err = $@) { | ||||
|         Wx::MessageDialog->new($self, $err, 'Error', wxOK | wxICON_ERROR)->ShowModal; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
							
								
								
									
										34
									
								
								lib/Slic3r/Skein.pm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								lib/Slic3r/Skein.pm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| package Slic3r::Skein; | ||||
| use Moo; | ||||
| 
 | ||||
| use Time::HiRes qw(gettimeofday tv_interval); | ||||
| 
 | ||||
| has 'input_file'    => (is => 'ro', required => 1); | ||||
| has 'output_file'   => (is => 'rw', required => 0); | ||||
| 
 | ||||
| sub go { | ||||
|     my $self = shift; | ||||
|      | ||||
|     die "Input file must have .stl extension\n"  | ||||
|         if $self->input_file !~ /\.stl$/i; | ||||
|      | ||||
|     my $t0 = [gettimeofday]; | ||||
|     my $print = Slic3r::Print->new_from_stl($self->input_file); | ||||
|     $print->extrude_perimeters; | ||||
|     $print->remove_small_features; | ||||
|     $print->extrude_fills; | ||||
|      | ||||
|      | ||||
|     if (!$self->output_file) { | ||||
|         my $output_file = $self->input_file; | ||||
|         $output_file =~ s/\.stl$/.gcode/i; | ||||
|         $self->output_file($output_file); | ||||
|     } | ||||
|     $print->export_gcode($self->output_file); | ||||
|      | ||||
|     my $processing_time = tv_interval($t0); | ||||
|     printf "Done. Process took %d minutes and %.3f seconds\n",  | ||||
|         int($processing_time/60), $processing_time - int($processing_time/60)*60; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
							
								
								
									
										90
									
								
								slic3r.pl
									
										
									
									
									
								
							
							
						
						
									
										90
									
								
								slic3r.pl
									
										
									
									
									
								
							|  | @ -10,11 +10,8 @@ BEGIN { | |||
| 
 | ||||
| use Getopt::Long; | ||||
| use Slic3r; | ||||
| use Time::HiRes qw(gettimeofday tv_interval); | ||||
| use XXX; | ||||
| 
 | ||||
| use constant PI => 4 * atan2(1, 1); | ||||
| 
 | ||||
| my %opt; | ||||
| GetOptions( | ||||
|     'help'                  => sub { usage() }, | ||||
|  | @ -59,7 +56,7 @@ GetOptions( | |||
|     'skirt-distance=i'      => \$Slic3r::skirt_distance, | ||||
|      | ||||
|     # transform options | ||||
|     'scale=i'               => \$Slic3r::scale, | ||||
|     'scale=f'               => \$Slic3r::scale, | ||||
|     'rotate=i'              => \$Slic3r::rotate, | ||||
|     'multiply-x=i'          => \$Slic3r::multiply_x, | ||||
|     'multiply-y=i'          => \$Slic3r::multiply_y, | ||||
|  | @ -67,89 +64,24 @@ GetOptions( | |||
| ); | ||||
| 
 | ||||
| # validate configuration | ||||
| { | ||||
|     # --layer-height | ||||
|     die "Invalid value for --layer-height\n" | ||||
|         if $Slic3r::layer_height < 0; | ||||
|     die "--layer-height must be a multiple of print resolution\n" | ||||
|         if $Slic3r::layer_height / $Slic3r::resolution % 1 != 0; | ||||
| Slic3r::Config->validate; | ||||
| 
 | ||||
|     # --filament-diameter | ||||
|     die "Invalid value for --filament-diameter\n" | ||||
|         if $Slic3r::filament_diameter < 1; | ||||
|      | ||||
|     # --nozzle-diameter | ||||
|     die "Invalid value for --nozzle-diameter\n" | ||||
|         if $Slic3r::nozzle_diameter < 0; | ||||
|     die "--layer-height can't be greater than --nozzle-diameter\n" | ||||
|         if $Slic3r::layer_height > $Slic3r::nozzle_diameter; | ||||
|     $Slic3r::flow_width = ($Slic3r::nozzle_diameter**2)  | ||||
|         * $Slic3r::thickness_ratio * PI / (4 * $Slic3r::layer_height); | ||||
|      | ||||
|     my $max_flow_width = $Slic3r::layer_height + $Slic3r::nozzle_diameter; | ||||
|     if ($Slic3r::flow_width > $max_flow_width) { | ||||
|         $Slic3r::thickness_ratio = $max_flow_width / $Slic3r::flow_width; | ||||
|         $Slic3r::flow_width = $max_flow_width; | ||||
|     } | ||||
|      | ||||
|     Slic3r::debugf "Flow width = $Slic3r::flow_width\n"; | ||||
|      | ||||
|     # --perimeters | ||||
|     die "Invalid value for --perimeters\n" | ||||
|         if $Slic3r::perimeter_offsets < 1; | ||||
|      | ||||
|     # --solid-layers | ||||
|     die "Invalid value for --solid-layers\n" | ||||
|         if $Slic3r::solid_layers < 1; | ||||
|      | ||||
|     # --print-center | ||||
|     die "Invalid value for --print-center\n" | ||||
|         if !ref $Slic3r::print_center  | ||||
|             && (!$Slic3r::print_center || $Slic3r::print_center !~ /^\d+,\d+$/); | ||||
|     $Slic3r::print_center = [ split /,/, $Slic3r::print_center ] | ||||
|         if !ref $Slic3r::print_center; | ||||
|      | ||||
|     # --fill-density | ||||
|     die "Invalid value for --fill-density\n" | ||||
|         if $Slic3r::fill_density < 0 || $Slic3r::fill_density > 1; | ||||
|      | ||||
|     # --scale | ||||
|     die "Invalid value for --scale\n" | ||||
|         if $Slic3r::scale <= 0; | ||||
|      | ||||
|     # --multiply-x | ||||
|     die "Invalid value for --multiply-x\n" | ||||
|         if $Slic3r::multiply_x < 1; | ||||
|      | ||||
|     # --multiply-y | ||||
|     die "Invalid value for --multiply-y\n" | ||||
|         if $Slic3r::multiply_y < 1; | ||||
|      | ||||
|     # --multiply-distance | ||||
|     die "Invalid value for --multiply-distance\n" | ||||
|         if $Slic3r::multiply_distance < 1; | ||||
| # start GUI | ||||
| if (!@ARGV && eval "require Slic3r::GUI; 1") { | ||||
|     Slic3r::GUI->new->MainLoop; | ||||
|     exit; | ||||
| } | ||||
| 
 | ||||
| my $action = 'skein'; | ||||
| 
 | ||||
| if ($action eq 'skein') { | ||||
|     my $input_file = $ARGV[0] or usage(1); | ||||
|     die "Input file must have .stl extension\n"  | ||||
|         if $input_file !~ /\.stl$/i; | ||||
|      | ||||
|     my $t0 = [gettimeofday]; | ||||
|     my $print = Slic3r::Print->new_from_stl($input_file); | ||||
|     $print->extrude_perimeters; | ||||
|     $print->remove_small_features; | ||||
|     $print->extrude_fills; | ||||
|      | ||||
|     my $output_file = $input_file; | ||||
|     $output_file =~ s/\.stl$/.gcode/i; | ||||
|     $print->export_gcode($opt{output} || $output_file); | ||||
|      | ||||
|     my $processing_time = tv_interval($t0); | ||||
|     printf "Done. Process took %d minutes and %.3f seconds\n",  | ||||
|         int($processing_time/60), $processing_time - int($processing_time/60)*60; | ||||
|     my $skein = Slic3r::Skein->new( | ||||
|         input_file  => $input_file, | ||||
|         output_file => $opt{output}, | ||||
|     ); | ||||
|     $skein->go; | ||||
| } | ||||
| 
 | ||||
| sub usage { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci