2011-10-03 11:55:32 +02:00
package Slic3r::Config ;
use strict ;
use warnings ;
2011-10-09 22:29:13 +02:00
use utf8 ;
2011-10-03 11:55:32 +02:00
use constant PI => 4 * atan2 ( 1 , 1 );
2011-10-05 18:13:47 +02:00
our $Options = {
2012-02-05 20:55:17 +01:00
# miscellaneous options
'notes' => {
2012-03-03 22:53:12 +01:00
label => 'Configuration notes' ,
2012-03-06 14:55:21 +11:00
cli => 'notes=s' ,
2012-02-05 20:55:17 +01:00
type => 's' ,
multiline => 1 ,
2012-03-03 22:50:08 +01:00
width => 350 ,
height => 300 ,
2012-02-05 20:55:17 +01:00
serialize => sub { join '\n' , split /\R/ , $_ [ 0 ] },
deserialize => sub { join "\n" , split /\\n/ , $_ [ 0 ] },
},
2011-12-26 04:20:45 -05:00
# output options
'output_filename_format' => {
label => 'Output filename format' ,
2011-12-26 17:20:26 +01:00
cli => 'output-filename-format=s' ,
2011-12-26 04:20:45 -05:00
type => 's' ,
},
2011-10-05 18:13:47 +02:00
# printer options
'nozzle_diameter' => {
2012-02-12 22:42:03 +01:00
label => 'Nozzle diameter (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'nozzle-diameter=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
2011-12-02 17:02:36 +01:00
important => 1 ,
2011-10-05 18:13:47 +02:00
},
'print_center' => {
2012-02-12 22:42:03 +01:00
label => 'Print center (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'print-center=s' ,
2011-10-05 18:13:47 +02:00
type => 'point' ,
serialize => sub { join ',' , @ { $_ [ 0 ]} },
deserialize => sub { [ split /,/ , $_ [ 0 ] ] },
},
2012-02-20 11:44:30 +01:00
'gcode_flavor' => {
label => 'G-code flavor' ,
cli => 'gcode-flavor=s' ,
type => 'select' ,
values => [ qw(reprap teacup makerbot mach3 no-extrusion) ],
labels => [ 'RepRap (Marlin/Sprinter)' , 'Teacup' , 'MakerBot' , 'Mach3/EMC' , 'No extrusion' ],
},
2011-10-05 18:13:47 +02:00
'use_relative_e_distances' => {
label => 'Use relative E distances' ,
2011-12-01 22:03:13 +01:00
cli => 'use-relative-e-distances' ,
2011-11-13 18:26:31 +01:00
type => 'bool' ,
},
2011-12-01 22:34:21 +01:00
'extrusion_axis' => {
label => 'Extrusion axis' ,
2012-02-26 11:33:58 +01:00
cli => 'extrusion-axis=s' ,
2011-12-01 22:34:21 +01:00
type => 's' ,
2011-10-05 18:13:47 +02:00
},
'z_offset' => {
2012-02-12 22:42:03 +01:00
label => 'Z offset (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'z-offset=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
2011-12-01 22:03:13 +01:00
'gcode_arcs' => {
2012-03-26 22:33:43 +02:00
label => 'Use native G-code arcs' ,
2011-12-01 22:03:13 +01:00
cli => 'gcode-arcs' ,
type => 'bool' ,
},
'g0' => {
2012-02-06 21:17:01 +01:00
label => 'Use G0 for travel moves' ,
2011-12-01 22:03:13 +01:00
cli => 'g0' ,
type => 'bool' ,
},
2011-12-14 19:49:21 +01:00
'gcode_comments' => {
2012-03-03 22:53:12 +01:00
label => 'Verbose G-code' ,
2011-12-14 19:49:21 +01:00
cli => 'gcode-comments' ,
type => 'bool' ,
},
2011-10-05 18:13:47 +02:00
# filament options
'filament_diameter' => {
label => 'Diameter (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'filament-diameter=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
2011-12-02 17:02:36 +01:00
important => 1 ,
2011-10-05 18:13:47 +02:00
},
2011-11-25 11:15:20 +01:00
'extrusion_multiplier' => {
label => 'Extrusion multiplier' ,
2011-12-01 22:03:13 +01:00
cli => 'extrusion-multiplier=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
2011-11-25 11:15:20 +01:00
aliases => [ qw(filament_packing_density) ],
2011-10-05 18:13:47 +02:00
},
2012-02-26 14:54:38 +01:00
'first_layer_temperature' => {
label => 'First layer temperature (°C)' ,
2012-02-28 22:04:48 +01:00
cli => 'first-layer-temperature=i' ,
2012-02-26 14:54:38 +01:00
type => 'i' ,
},
2012-03-01 14:08:07 +11:00
'first_layer_bed_temperature' => {
label => 'First layer bed temperature (°C)' ,
cli => 'first-layer-bed-temperature=i' ,
type => 'i' ,
},
2011-10-09 22:29:13 +02:00
'temperature' => {
label => 'Temperature (°C)' ,
2011-12-01 22:03:13 +01:00
cli => 'temperature=i' ,
2011-10-09 22:29:13 +02:00
type => 'i' ,
2011-12-02 17:02:36 +01:00
important => 1 ,
2011-10-09 22:29:13 +02:00
},
2012-03-01 14:08:07 +11:00
'bed_temperature' => {
label => 'Bed Temperature (°C)' ,
cli => 'bed-temperature=i' ,
type => 'i' ,
},
2011-10-05 18:13:47 +02:00
# speed options
2011-12-01 22:03:13 +01:00
'travel_speed' => {
2011-11-28 19:11:26 +01:00
label => 'Travel (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'travel-speed=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
2011-12-01 22:03:13 +01:00
aliases => [ qw(travel_feed_rate) ],
2011-10-05 18:13:47 +02:00
},
2011-12-01 22:03:13 +01:00
'perimeter_speed' => {
2011-11-28 19:11:26 +01:00
label => 'Perimeters (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'perimeter-speed=f' ,
2011-11-28 19:11:26 +01:00
type => 'f' ,
2011-12-01 22:03:13 +01:00
aliases => [ qw(perimeter_feed_rate) ],
2011-11-28 19:11:26 +01:00
},
2011-12-04 20:50:03 +01:00
'small_perimeter_speed' => {
label => 'Small perimeters (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'small-perimeter-speed=f' ,
2011-12-04 20:50:03 +01:00
type => 'f' ,
},
2011-12-01 22:03:13 +01:00
'infill_speed' => {
2011-11-28 19:11:26 +01:00
label => 'Infill (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'infill-speed=f' ,
2011-11-28 19:11:26 +01:00
type => 'f' ,
2011-12-01 22:03:13 +01:00
aliases => [ qw(print_feed_rate infill_feed_rate) ],
2011-11-28 19:11:26 +01:00
},
2011-12-01 22:03:13 +01:00
'solid_infill_speed' => {
2011-11-28 19:11:26 +01:00
label => 'Solid infill (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'solid-infill-speed=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
2011-12-01 22:03:13 +01:00
aliases => [ qw(solid_infill_feed_rate) ],
2011-10-05 18:13:47 +02:00
},
2011-12-01 22:03:13 +01:00
'bridge_speed' => {
2011-11-28 19:11:26 +01:00
label => 'Bridges (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'bridge-speed=f' ,
2011-11-28 18:37:53 +01:00
type => 'f' ,
2011-12-01 22:03:13 +01:00
aliases => [ qw(bridge_feed_rate) ],
2011-11-28 18:37:53 +01:00
},
2011-10-05 18:13:47 +02:00
'bottom_layer_speed_ratio' => {
2011-11-28 19:11:26 +01:00
label => 'Bottom layer speed ratio' ,
2011-12-01 22:03:13 +01:00
cli => 'bottom-layer-speed-ratio=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
2012-02-10 14:53:44 +01:00
# acceleration options
'acceleration' => {
label => 'Enable acceleration control' ,
cli => 'acceleration' ,
type => 'bool' ,
},
'perimeter_acceleration' => {
2012-02-18 22:36:13 +01:00
label => 'Perimeters (mm/s²)' ,
2012-02-10 14:53:44 +01:00
cli => 'perimeter-acceleration' ,
type => 'f' ,
},
'infill_acceleration' => {
2012-02-18 22:36:13 +01:00
label => 'Infill (mm/s²)' ,
2012-02-10 14:53:44 +01:00
cli => 'infill-acceleration' ,
type => 'f' ,
},
2011-10-05 18:13:47 +02:00
# accuracy options
'layer_height' => {
label => 'Layer height (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'layer-height=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
2011-12-07 19:33:59 +01:00
'first_layer_height_ratio' => {
label => 'First layer height ratio' ,
cli => 'first-layer-height-ratio=f' ,
type => 'f' ,
},
'infill_every_layers' => {
label => 'Infill every N layers' ,
cli => 'infill-every-layers=i' ,
type => 'i' ,
},
# flow options
2011-11-25 10:58:13 +01:00
'extrusion_width_ratio' => {
2011-11-26 20:51:04 +01:00
label => 'Extrusion width (ratio over layer height; leave zero to calculate automatically)' ,
2011-12-01 22:03:13 +01:00
cli => 'extrusion-width-ratio=f' ,
2011-11-25 10:58:13 +01:00
type => 'f' ,
},
2011-12-04 20:29:21 +01:00
'bridge_flow_ratio' => {
label => 'Bridge flow ratio' ,
cli => 'bridge-flow-ratio=f' ,
type => 'f' ,
},
2011-10-05 18:13:47 +02:00
# print options
2011-11-17 10:38:23 +01:00
'perimeters' => {
2011-10-05 18:13:47 +02:00
label => 'Perimeters' ,
2011-12-01 22:03:13 +01:00
cli => 'perimeters=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
2011-11-17 10:38:23 +01:00
aliases => [ qw(perimeter_offsets) ],
2011-10-05 18:13:47 +02:00
},
'solid_layers' => {
label => 'Solid layers' ,
2011-12-01 22:03:13 +01:00
cli => 'solid-layers=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
},
2011-11-13 18:14:02 +01:00
'fill_pattern' => {
label => 'Fill pattern' ,
2011-12-01 22:03:13 +01:00
cli => 'fill-pattern=s' ,
2011-11-13 18:14:02 +01:00
type => 'select' ,
2011-11-26 10:38:05 +01:00
values => [ qw(rectilinear line concentric hilbertcurve archimedeanchords octagramspiral) ],
2011-11-26 22:41:23 +01:00
labels => [ qw(rectilinear line concentric) , 'hilbertcurve (slow)' , 'archimedeanchords (slow)' , 'octagramspiral (slow)' ],
2011-11-13 18:14:02 +01:00
},
'solid_fill_pattern' => {
label => 'Solid fill pattern' ,
2011-12-01 22:03:13 +01:00
cli => 'solid-fill-pattern=s' ,
2011-11-13 18:14:02 +01:00
type => 'select' ,
2011-11-26 10:38:05 +01:00
values => [ qw(rectilinear concentric hilbertcurve archimedeanchords octagramspiral) ],
2011-11-26 22:41:23 +01:00
labels => [ qw(rectilinear concentric) , 'hilbertcurve (slow)' , 'archimedeanchords (slow)' , 'octagramspiral (slow)' ],
2011-11-13 18:14:02 +01:00
},
2011-10-05 18:13:47 +02:00
'fill_density' => {
label => 'Fill density' ,
2011-12-01 22:03:13 +01:00
cli => 'fill-density=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
'fill_angle' => {
label => 'Fill angle (°)' ,
2011-12-01 22:03:13 +01:00
cli => 'fill-angle=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
},
2012-02-19 12:03:36 +01:00
'support_material' => {
label => 'Generate support material' ,
cli => 'support-material' ,
type => 'bool' ,
},
2012-02-19 17:02:49 +01:00
'support_material_tool' => {
label => 'Tool used to extrude support material' ,
cli => 'support-material-tool=i' ,
type => 'select' ,
values => [ 0 , 1 ],
labels => [ qw(Primary Secondary) ],
},
2011-10-14 16:24:55 +02:00
'start_gcode' => {
2012-03-26 22:33:43 +02:00
label => 'Start G-code' ,
2011-12-01 22:03:13 +01:00
cli => 'start-gcode=s' ,
2011-10-14 16:24:55 +02:00
type => 's' ,
2011-11-13 22:48:21 +01:00
multiline => 1 ,
width => 350 ,
2012-03-26 12:14:15 +02:00
height => 120 ,
2011-10-14 16:24:55 +02:00
serialize => sub { join '\n' , split /\R+/ , $_ [ 0 ] },
deserialize => sub { join "\n" , split /\\n/ , $_ [ 0 ] },
},
'end_gcode' => {
2012-03-26 22:33:43 +02:00
label => 'End G-code' ,
2011-12-01 22:03:13 +01:00
cli => 'end-gcode=s' ,
2011-10-14 16:24:55 +02:00
type => 's' ,
2011-11-13 22:48:21 +01:00
multiline => 1 ,
width => 350 ,
2012-03-26 12:14:15 +02:00
height => 120 ,
serialize => sub { join '\n' , split /\R+/ , $_ [ 0 ] },
deserialize => sub { join "\n" , split /\\n/ , $_ [ 0 ] },
},
'layer_gcode' => {
2012-03-26 22:33:43 +02:00
label => 'Layer Change G-code' ,
2012-03-26 12:14:15 +02:00
cli => 'layer-gcode=s' ,
type => 's' ,
multiline => 1 ,
width => 350 ,
height => 50 ,
2011-10-14 16:24:55 +02:00
serialize => sub { join '\n' , split /\R+/ , $_ [ 0 ] },
deserialize => sub { join "\n" , split /\\n/ , $_ [ 0 ] },
},
2012-02-20 12:50:05 +01:00
'post_process' => {
label => 'Post-processing scripts' ,
cli => 'post-process=s@' ,
type => 's@' ,
multiline => 1 ,
width => 350 ,
height => 60 ,
serialize => sub { join '; ' , @ { $_ [ 0 ]} },
deserialize => sub { [ split /\s*;\s*/ , $_ [ 0 ] ] },
},
2011-10-05 18:13:47 +02:00
# retraction options
'retract_length' => {
label => 'Length (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'retract-length=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
'retract_speed' => {
label => 'Speed (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'retract-speed=f' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
},
'retract_restart_extra' => {
label => 'Extra length on restart (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'retract-restart-extra=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
'retract_before_travel' => {
label => 'Minimum travel after retraction (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'retract-before-travel=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
2011-11-07 15:58:47 +01:00
'retract_lift' => {
label => 'Lift Z (mm)' ,
2011-12-01 22:03:13 +01:00
cli => 'retract-lift=f' ,
2011-11-07 15:58:47 +01:00
type => 'f' ,
},
2011-10-05 18:13:47 +02:00
2012-02-25 21:01:00 +01:00
# cooling options
2012-02-25 21:56:36 +01:00
'cooling' => {
label => 'Enable cooling' ,
cli => 'cooling' ,
type => 'bool' ,
},
2012-02-25 21:01:00 +01:00
'min_fan_speed' => {
label => 'Min fan speed (%)' ,
cli => 'min-fan-speed=i' ,
type => 'i' ,
},
'max_fan_speed' => {
label => 'Max fan speed (%)' ,
cli => 'max-fan-speed=i' ,
type => 'i' ,
},
'bridge_fan_speed' => {
label => 'Bridge fan speed (%)' ,
cli => 'bridge-fan-speed=i' ,
type => 'i' ,
},
'fan_below_layer_time' => {
label => 'Enable fan if layer print time is below (approximate seconds)' ,
cli => 'fan-below-layer-time=i' ,
type => 'i' ,
},
'slowdown_below_layer_time' => {
label => 'Slow down if layer print time is below (approximate seconds)' ,
cli => 'slowdown-below-layer-time=i' ,
type => 'i' ,
},
'min_print_speed' => {
label => 'Min print speed (mm/s)' ,
2012-03-26 15:20:59 +02:00
cli => 'min-print-speed=f' ,
2012-02-25 21:01:00 +01:00
type => 'i' ,
},
'disable_fan_first_layers' => {
label => 'Disable fan for the first N layers' ,
cli => 'disable-fan-first-layers=i' ,
type => 'i' ,
},
2012-03-03 22:21:30 +01:00
'fan_always_on' => {
label => 'Keep fan always on' ,
cli => 'fan-always-on' ,
type => 'bool' ,
},
2012-02-25 21:01:00 +01:00
2011-10-05 18:13:47 +02:00
# skirt options
'skirts' => {
label => 'Loops' ,
2011-12-01 22:03:13 +01:00
cli => 'skirts=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
},
'skirt_distance' => {
label => 'Distance from object (mm)' ,
2012-03-26 15:20:59 +02:00
cli => 'skirt-distance=f' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
},
2011-11-13 18:41:12 +01:00
'skirt_height' => {
label => 'Skirt height (layers)' ,
2011-12-01 22:03:13 +01:00
cli => 'skirt-height=i' ,
2011-11-13 18:41:12 +01:00
type => 'i' ,
},
2011-10-05 18:13:47 +02:00
# transform options
'scale' => {
label => 'Scale' ,
2011-12-01 22:03:13 +01:00
cli => 'scale=f' ,
2011-10-05 18:13:47 +02:00
type => 'f' ,
},
'rotate' => {
label => 'Rotate (°)' ,
2011-12-01 22:03:13 +01:00
cli => 'rotate=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
},
2012-03-06 14:55:21 +11:00
'duplicate' => {
label => 'Copies (auto arrange)' ,
cli => 'duplicate=i' ,
type => 'i' ,
},
2011-11-07 15:49:07 +01:00
'duplicate_x' => {
label => 'Copies along X' ,
2011-12-01 22:03:13 +01:00
cli => 'duplicate-x=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
2011-11-07 17:16:34 +01:00
aliases => [ qw(multiply_x) ],
2011-10-05 18:13:47 +02:00
},
2011-11-07 15:49:07 +01:00
'duplicate_y' => {
label => 'Copies along Y' ,
2011-12-01 22:03:13 +01:00
cli => 'duplicate-y=i' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
2011-11-07 17:16:34 +01:00
aliases => [ qw(multiply_y) ],
2011-10-05 18:13:47 +02:00
},
2011-11-07 15:49:07 +01:00
'duplicate_distance' => {
label => 'Distance between copies' ,
2012-03-26 15:20:59 +02:00
cli => 'duplicate-distance=f' ,
2011-10-05 18:13:47 +02:00
type => 'i' ,
2011-11-07 17:16:34 +01:00
aliases => [ qw(multiply_distance) ],
2011-10-05 18:13:47 +02:00
},
};
sub get {
my $class = @_ == 2 ? shift : undef ;
my ( $opt_key ) = @_ ;
no strict 'refs' ;
return $ { "Slic3r::$opt_key" };
}
sub set {
my $class = @_ == 3 ? shift : undef ;
my ( $opt_key , $value ) = @_ ;
no strict 'refs' ;
$ { "Slic3r::$opt_key" } = $value ;
}
2011-12-26 17:20:26 +01:00
sub serialize {
my $class = @_ == 2 ? shift : undef ;
my ( $opt_key ) = @_ ;
return $Options -> { $opt_key }{ serialize }
? $Options -> { $opt_key }{ serialize } -> ( get ( $opt_key ))
: get ( $opt_key );
}
2012-02-20 12:50:05 +01:00
sub deserialize {
my $class = @_ == 3 ? shift : undef ;
my ( $opt_key , $value ) = @_ ;
return $Options -> { $opt_key }{ deserialize }
? set ( $opt_key , $Options -> { $opt_key }{ deserialize } -> ( $value ))
: set ( $opt_key , $value );
}
2011-10-05 18:13:47 +02:00
sub save {
my $class = shift ;
my ( $file ) = @_ ;
open my $fh , '>' , $file ;
2012-02-12 23:33:25 +01:00
binmode $fh , ':utf8' ;
2011-10-05 18:13:47 +02:00
foreach my $opt ( sort keys %$Options ) {
my $value = get ( $opt );
$value = $Options -> { $opt }{ serialize } -> ( $value ) if $Options -> { $opt }{ serialize };
printf $fh "%s = %s\n" , $opt , $value ;
}
close $fh ;
}
sub load {
my $class = shift ;
my ( $file ) = @_ ;
2012-01-22 20:10:23 +01:00
local $/ = "\n" ;
2011-10-05 18:13:47 +02:00
open my $fh , '<' , $file ;
2012-02-12 23:33:25 +01:00
binmode $fh , ':utf8' ;
2011-10-05 18:13:47 +02:00
while ( <$fh> ) {
2012-01-22 20:10:23 +01:00
s/\R+$// ;
2011-12-04 20:41:17 +01:00
next if /^\s+/ ;
next if /^$/ ;
2011-10-05 18:13:47 +02:00
next if /^\s*#/ ;
2011-12-01 22:06:07 +01:00
/^(\w+) = (.*)/ or die "Unreadable configuration file (invalid data at line $.)\n" ;
2011-11-07 17:16:34 +01:00
my $key = $1 ;
if ( ! exists $Options -> { $key }) {
$key = + ( grep { $Options -> { $_ }{ aliases } && grep $_ eq $key , @ { $Options -> { $_ }{ aliases }} }
2011-12-10 10:39:07 +01:00
keys %$Options )[ 0 ] or warn "Unknown option $1 at line $.\n" ;
2011-11-07 17:16:34 +01:00
}
2011-12-10 10:39:07 +01:00
next unless $key ;
2011-11-07 17:16:34 +01:00
my $opt = $Options -> { $key };
set ( $key , $opt -> { deserialize } ? $opt -> { deserialize } -> ( $2 ) : $2 );
2011-10-05 18:13:47 +02:00
}
close $fh ;
}
2011-10-14 16:24:55 +02:00
sub validate_cli {
my $class = shift ;
my ( $opt ) = @_ ;
2012-03-26 12:14:15 +02:00
for ( qw(start end layer) ) {
2011-10-14 16:24:55 +02:00
if ( defined $opt -> { $_ . "_gcode" }) {
if ( $opt -> { $_ . "_gcode" } eq "" ) {
set ( $_ . "_gcode" , "" );
} else {
die "Invalid value for --${_}-gcode: file does not exist"
if !- e $opt -> { $_ . "_gcode" };
open my $fh , "<" , $opt -> { $_ . "_gcode" };
2011-12-01 22:03:13 +01:00
$opt -> { $_ . "_gcode" } = do { local $/ ; <$fh> };
2011-10-14 16:24:55 +02:00
close $fh ;
}
}
}
}
2011-10-03 11:55:32 +02:00
sub validate {
my $class = shift ;
2012-04-10 16:26:56 +02:00
# -j, --threads
die "Invalid value for --threads\n"
if defined $ Slic3r:: threads && $ Slic3r:: threads < 1 ;
die "Your perl wasn't built with multithread support\n"
if defined $ Slic3r:: threads && ! $ Slic3r:: have_threads ;
2011-10-03 11:55:32 +02:00
# --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 ;
2011-11-13 19:08:19 +01:00
# --first-layer-height-ratio
die "Invalid value for --first-layer-height-ratio\n"
if $ Slic3r:: first_layer_height_ratio < 0 ;
2011-10-03 11:55:32 +02:00
# --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 ;
2011-11-13 19:08:19 +01:00
die "First layer height can't be greater than --nozzle-diameter\n"
if ( $ Slic3r:: layer_height * $ Slic3r:: first_layer_height_ratio ) > $ Slic3r:: nozzle_diameter ;
2012-03-11 16:58:15 +01:00
die "First layer height can't be zero or negative\n"
if ( $ Slic3r:: layer_height * $ Slic3r:: first_layer_height_ratio ) <= 0 ;
2011-10-03 11:55:32 +02:00
2011-11-25 10:58:13 +01:00
if ( $ Slic3r:: extrusion_width_ratio ) {
2011-12-13 17:34:31 +01:00
$ Slic3r:: flow_width = $ Slic3r:: layer_height * $ Slic3r:: extrusion_width_ratio ;
} else {
# here we calculate a sane default by matching the flow speed (at the nozzle)
# and the feed rate
2011-12-17 19:52:34 +01:00
my $volume = ( $ Slic3r:: nozzle_diameter ** 2 ) * PI / 4 ;
my $shape_threshold = $ Slic3r:: nozzle_diameter * $ Slic3r:: layer_height
+ ( $ Slic3r:: layer_height ** 2 ) * PI / 4 ;
if ( $volume >= $shape_threshold ) {
# rectangle with semicircles at the ends
$ Slic3r:: flow_width = (( $ Slic3r:: nozzle_diameter ** 2 ) * PI + ( $ Slic3r:: layer_height ** 2 ) * ( 4 - PI )) / ( 4 * $ Slic3r:: layer_height );
} else {
# rectangle with squished semicircles at the ends
$ Slic3r:: flow_width = $ Slic3r:: nozzle_diameter * ( $ Slic3r:: nozzle_diameter /$Slic3r::layer_height - 4/ PI + 1 );
}
2011-12-13 17:34:31 +01:00
2011-12-17 19:52:34 +01:00
my $min_flow_width = $ Slic3r:: nozzle_diameter * 1.05 ;
my $max_flow_width = $ Slic3r:: nozzle_diameter * 1.4 ;
2011-12-15 12:50:02 +01:00
$ Slic3r:: flow_width = $max_flow_width if $ Slic3r:: flow_width > $max_flow_width ;
2011-12-17 19:52:34 +01:00
$ Slic3r:: flow_width = $min_flow_width if $ Slic3r:: flow_width < $min_flow_width ;
2011-11-25 10:58:13 +01:00
}
2011-10-03 11:55:32 +02:00
2011-12-17 19:52:34 +01:00
if ( $ Slic3r:: flow_width >= ( $ Slic3r:: nozzle_diameter + $ Slic3r:: layer_height )) {
2011-12-18 10:50:55 +01:00
# rectangle with semicircles at the ends
2011-12-17 19:52:34 +01:00
$ Slic3r:: min_flow_spacing = $ Slic3r:: flow_width - $ Slic3r:: layer_height * ( 1 - PI / 4 );
} else {
# rectangle with shrunk semicircles at the ends
$ Slic3r:: min_flow_spacing = $ Slic3r:: flow_width * ( 1 - PI /4) + $Slic3r::nozzle_diameter * PI/ 4 ;
}
$ Slic3r:: flow_spacing = $ Slic3r:: flow_width - $ Slic3r:: overlap_factor * ( $ Slic3r:: flow_width - $ Slic3r:: min_flow_spacing );
2011-10-03 11:55:32 +02:00
Slic3r:: debugf "Flow width = $Slic3r::flow_width\n" ;
2011-12-17 19:52:34 +01:00
Slic3r:: debugf "Flow spacing = $Slic3r::flow_spacing\n" ;
2012-02-15 12:04:10 +01:00
Slic3r:: debugf "Min flow spacing = $Slic3r::min_flow_spacing\n" ;
2011-10-03 11:55:32 +02:00
# --perimeters
die "Invalid value for --perimeters\n"
2012-03-26 11:32:59 +02:00
if $ Slic3r:: perimeters < 0 ;
2011-10-03 11:55:32 +02:00
# --solid-layers
die "Invalid value for --solid-layers\n"
2011-11-30 12:51:34 +11:00
if $ Slic3r:: solid_layers < 0 ;
2011-10-03 11:55:32 +02:00
# --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 ;
2011-11-13 18:14:02 +01:00
# --fill-pattern
die "Invalid value for --fill-pattern\n"
if ! exists $ Slic3r::Fill:: FillTypes { $ Slic3r:: fill_pattern };
# --solid-fill-pattern
die "Invalid value for --solid-fill-pattern\n"
if ! exists $ Slic3r::Fill:: FillTypes { $ Slic3r:: solid_fill_pattern };
2011-10-06 15:24:21 +02:00
2011-10-03 11:55:32 +02:00
# --fill-density
die "Invalid value for --fill-density\n"
if $ Slic3r:: fill_density < 0 || $ Slic3r:: fill_density > 1 ;
2011-10-18 15:57:53 +02:00
# --infill-every-layers
die "Invalid value for --infill-every-layers\n"
if $ Slic3r:: infill_every_layers !~ /^\d+$/ || $ Slic3r:: infill_every_layers < 1 ;
die "Maximum infill thickness can't exceed nozzle diameter\n"
if $ Slic3r:: infill_every_layers * $ Slic3r:: layer_height > $ Slic3r:: nozzle_diameter ;
2011-10-03 11:55:32 +02:00
# --scale
die "Invalid value for --scale\n"
if $ Slic3r:: scale <= 0 ;
2012-03-06 14:55:21 +11:00
# --duplicate
die "Invalid value for --duplicate\n"
if $ Slic3r:: duplicate < 1 ;
2011-11-07 15:49:07 +01:00
# --duplicate-x
die "Invalid value for --duplicate-x\n"
if $ Slic3r:: duplicate_x < 1 ;
2011-10-03 11:55:32 +02:00
2011-11-07 15:49:07 +01:00
# --duplicate-y
die "Invalid value for --duplicate-y\n"
if $ Slic3r:: duplicate_y < 1 ;
2012-03-06 14:55:21 +11:00
# reflect actual quantity in 'duplicate' setting for use with output-filename-format, ie both --duplicate 15 and --duplicate-x 3 --duplicate-y 5 will make an appropriate filename
if ( $ Slic3r:: duplicate == 1 && (( $ Slic3r:: duplicate_x > 1 ) || ( $ Slic3r:: duplicate_y > 1 ))) {
$ Slic3r:: duplicate = $ Slic3r:: duplicate_x * $ Slic3r:: duplicate_y ;
}
2011-10-03 11:55:32 +02:00
2011-11-07 15:49:07 +01:00
# --duplicate-distance
die "Invalid value for --duplicate-distance\n"
if $ Slic3r:: duplicate_distance < 1 ;
2011-11-13 18:41:12 +01:00
# --skirt-height
die "Invalid value for --skirt-height\n"
2011-12-16 09:55:13 +01:00
if $ Slic3r:: skirt_height < 0 ;
2011-11-28 18:37:53 +01:00
2012-02-19 09:32:16 +01:00
# --bridge-flow-ratio
die "Invalid value for --bridge-flow-ratio\n"
if $ Slic3r:: bridge_flow_ratio <= 0 ;
2012-03-01 14:08:07 +11:00
2012-03-06 14:55:21 +11:00
$ Slic3r:: first_layer_temperature // = $ Slic3r:: temperature ; #/
$ Slic3r:: first_layer_bed_temperature // = $ Slic3r:: bed_temperature ; #/
2012-02-19 09:32:16 +01:00
2012-02-20 11:44:30 +01:00
# G-code flavors
$ Slic3r:: extrusion_axis = 'A' if $ Slic3r:: gcode_flavor eq 'mach3' ;
2012-04-08 21:27:38 +02:00
$ Slic3r:: extrusion_axis = '' if $ Slic3r:: gcode_flavor eq 'no-extrusion' ;
2012-02-20 11:44:30 +01:00
2011-11-28 18:37:53 +01:00
# legacy with existing config files
2011-12-04 20:50:03 +01:00
$ Slic3r:: small_perimeter_speed ||= $ Slic3r:: perimeter_speed ;
2011-12-01 22:03:13 +01:00
$ Slic3r:: bridge_speed ||= $ Slic3r:: infill_speed ;
$ Slic3r:: solid_infill_speed ||= $ Slic3r:: infill_speed ;
2011-10-03 11:55:32 +02:00
}
2012-03-03 23:29:08 +01:00
sub replace_options {
my $class = shift ;
my ( $string , $more_variables ) = @_ ;
if ( $more_variables ) {
my $variables = join '|' , keys %$more_variables ;
$string =~ s/\[($variables)\]/$more_variables->{$1}/eg ;
}
# build a regexp to match the available options
my $options = join '|' ,
grep ! $ Slic3r::Config:: Options -> { $_ }{ multiline },
keys %$ Slic3r::Config:: Options ;
# use that regexp to search and replace option names with option values
$string =~ s/\[($options)\]/Slic3r::Config->serialize($1)/eg ;
return $string ;
}
2011-10-03 11:55:32 +02:00
1 ;