2011-10-03 09:55:32 +00:00
package Slic3r::Config ;
use strict ;
use warnings ;
2011-10-09 20:29:13 +00:00
use utf8 ;
2011-10-03 09:55:32 +00:00
use constant PI = > 4 * atan2 ( 1 , 1 ) ;
2011-10-05 16:13:47 +00:00
our $ Options = {
2012-02-05 19:55:17 +00:00
# miscellaneous options
'notes' = > {
2012-03-03 21:53:12 +00:00
label = > 'Configuration notes' ,
2012-03-06 03:55:21 +00:00
cli = > 'notes=s' ,
2012-02-05 19:55:17 +00:00
type = > 's' ,
multiline = > 1 ,
2012-03-03 21:50:08 +00:00
width = > 350 ,
height = > 300 ,
2012-02-05 19:55:17 +00:00
serialize = > sub { join '\n' , split /\R/ , $ _ [ 0 ] } ,
deserialize = > sub { join "\n" , split /\\n/ , $ _ [ 0 ] } ,
} ,
2011-12-26 09:20:45 +00:00
# output options
'output_filename_format' = > {
label = > 'Output filename format' ,
2011-12-26 16:20:26 +00:00
cli = > 'output-filename-format=s' ,
2011-12-26 09:20:45 +00:00
type = > 's' ,
} ,
2011-10-05 16:13:47 +00:00
# printer options
'nozzle_diameter' = > {
2012-02-12 21:42:03 +00:00
label = > 'Nozzle diameter (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'nozzle-diameter=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
2011-12-02 16:02:36 +00:00
important = > 1 ,
2011-10-05 16:13:47 +00:00
} ,
'print_center' = > {
2012-02-12 21:42:03 +00:00
label = > 'Print center (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'print-center=s' ,
2011-10-05 16:13:47 +00:00
type = > 'point' ,
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
} ,
2012-02-20 10:44:30 +00: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 16:13:47 +00:00
'use_relative_e_distances' = > {
label = > 'Use relative E distances' ,
2011-12-01 21:03:13 +00:00
cli = > 'use-relative-e-distances' ,
2011-11-13 17:26:31 +00:00
type = > 'bool' ,
} ,
2011-12-01 21:34:21 +00:00
'extrusion_axis' = > {
label = > 'Extrusion axis' ,
2012-02-26 10:33:58 +00:00
cli = > 'extrusion-axis=s' ,
2011-12-01 21:34:21 +00:00
type = > 's' ,
2011-10-05 16:13:47 +00:00
} ,
'z_offset' = > {
2012-02-12 21:42:03 +00:00
label = > 'Z offset (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'z-offset=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
2011-12-01 21:03:13 +00:00
'gcode_arcs' = > {
2012-03-26 20:33:43 +00:00
label = > 'Use native G-code arcs' ,
2011-12-01 21:03:13 +00:00
cli = > 'gcode-arcs' ,
type = > 'bool' ,
} ,
'g0' = > {
2012-02-06 20:17:01 +00:00
label = > 'Use G0 for travel moves' ,
2011-12-01 21:03:13 +00:00
cli = > 'g0' ,
type = > 'bool' ,
} ,
2011-12-14 18:49:21 +00:00
'gcode_comments' = > {
2012-03-03 21:53:12 +00:00
label = > 'Verbose G-code' ,
2011-12-14 18:49:21 +00:00
cli = > 'gcode-comments' ,
type = > 'bool' ,
} ,
2011-10-05 16:13:47 +00:00
# filament options
'filament_diameter' = > {
label = > 'Diameter (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'filament-diameter=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
2011-12-02 16:02:36 +00:00
important = > 1 ,
2011-10-05 16:13:47 +00:00
} ,
2011-11-25 10:15:20 +00:00
'extrusion_multiplier' = > {
label = > 'Extrusion multiplier' ,
2011-12-01 21:03:13 +00:00
cli = > 'extrusion-multiplier=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
2011-11-25 10:15:20 +00:00
aliases = > [ qw( filament_packing_density ) ] ,
2011-10-05 16:13:47 +00:00
} ,
2012-02-26 13:54:38 +00:00
'first_layer_temperature' = > {
label = > 'First layer temperature (°C)' ,
2012-02-28 21:04:48 +00:00
cli = > 'first-layer-temperature=i' ,
2012-02-26 13:54:38 +00:00
type = > 'i' ,
} ,
2012-03-01 03:08:07 +00:00
'first_layer_bed_temperature' = > {
label = > 'First layer bed temperature (°C)' ,
cli = > 'first-layer-bed-temperature=i' ,
type = > 'i' ,
} ,
2011-10-09 20:29:13 +00:00
'temperature' = > {
label = > 'Temperature (°C)' ,
2011-12-01 21:03:13 +00:00
cli = > 'temperature=i' ,
2011-10-09 20:29:13 +00:00
type = > 'i' ,
2011-12-02 16:02:36 +00:00
important = > 1 ,
2011-10-09 20:29:13 +00:00
} ,
2012-03-01 03:08:07 +00:00
'bed_temperature' = > {
label = > 'Bed Temperature (°C)' ,
cli = > 'bed-temperature=i' ,
type = > 'i' ,
} ,
2011-10-05 16:13:47 +00:00
# speed options
2011-12-01 21:03:13 +00:00
'travel_speed' = > {
2011-11-28 18:11:26 +00:00
label = > 'Travel (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'travel-speed=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
2011-12-01 21:03:13 +00:00
aliases = > [ qw( travel_feed_rate ) ] ,
2011-10-05 16:13:47 +00:00
} ,
2011-12-01 21:03:13 +00:00
'perimeter_speed' = > {
2011-11-28 18:11:26 +00:00
label = > 'Perimeters (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'perimeter-speed=f' ,
2011-11-28 18:11:26 +00:00
type = > 'f' ,
2011-12-01 21:03:13 +00:00
aliases = > [ qw( perimeter_feed_rate ) ] ,
2011-11-28 18:11:26 +00:00
} ,
2011-12-04 19:50:03 +00:00
'small_perimeter_speed' = > {
label = > 'Small perimeters (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'small-perimeter-speed=f' ,
2011-12-04 19:50:03 +00:00
type = > 'f' ,
} ,
2011-12-01 21:03:13 +00:00
'infill_speed' = > {
2011-11-28 18:11:26 +00:00
label = > 'Infill (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'infill-speed=f' ,
2011-11-28 18:11:26 +00:00
type = > 'f' ,
2011-12-01 21:03:13 +00:00
aliases = > [ qw( print_feed_rate infill_feed_rate ) ] ,
2011-11-28 18:11:26 +00:00
} ,
2011-12-01 21:03:13 +00:00
'solid_infill_speed' = > {
2011-11-28 18:11:26 +00:00
label = > 'Solid infill (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'solid-infill-speed=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
2011-12-01 21:03:13 +00:00
aliases = > [ qw( solid_infill_feed_rate ) ] ,
2011-10-05 16:13:47 +00:00
} ,
2011-12-01 21:03:13 +00:00
'bridge_speed' = > {
2011-11-28 18:11:26 +00:00
label = > 'Bridges (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'bridge-speed=f' ,
2011-11-28 17:37:53 +00:00
type = > 'f' ,
2011-12-01 21:03:13 +00:00
aliases = > [ qw( bridge_feed_rate ) ] ,
2011-11-28 17:37:53 +00:00
} ,
2011-10-05 16:13:47 +00:00
'bottom_layer_speed_ratio' = > {
2011-11-28 18:11:26 +00:00
label = > 'Bottom layer speed ratio' ,
2011-12-01 21:03:13 +00:00
cli = > 'bottom-layer-speed-ratio=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
2012-02-10 13:53:44 +00:00
# acceleration options
'acceleration' = > {
label = > 'Enable acceleration control' ,
cli = > 'acceleration' ,
type = > 'bool' ,
} ,
'perimeter_acceleration' = > {
2012-02-18 21:36:13 +00:00
label = > 'Perimeters (mm/s²)' ,
2012-02-10 13:53:44 +00:00
cli = > 'perimeter-acceleration' ,
type = > 'f' ,
} ,
'infill_acceleration' = > {
2012-02-18 21:36:13 +00:00
label = > 'Infill (mm/s²)' ,
2012-02-10 13:53:44 +00:00
cli = > 'infill-acceleration' ,
type = > 'f' ,
} ,
2011-10-05 16:13:47 +00:00
# accuracy options
'layer_height' = > {
label = > 'Layer height (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'layer-height=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
2011-12-07 18:33:59 +00: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 09:58:13 +00:00
'extrusion_width_ratio' = > {
2011-11-26 19:51:04 +00:00
label = > 'Extrusion width (ratio over layer height; leave zero to calculate automatically)' ,
2011-12-01 21:03:13 +00:00
cli = > 'extrusion-width-ratio=f' ,
2011-11-25 09:58:13 +00:00
type = > 'f' ,
} ,
2011-12-04 19:29:21 +00:00
'bridge_flow_ratio' = > {
label = > 'Bridge flow ratio' ,
cli = > 'bridge-flow-ratio=f' ,
type = > 'f' ,
} ,
2011-10-05 16:13:47 +00:00
# print options
2011-11-17 09:38:23 +00:00
'perimeters' = > {
2011-10-05 16:13:47 +00:00
label = > 'Perimeters' ,
2011-12-01 21:03:13 +00:00
cli = > 'perimeters=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
2011-11-17 09:38:23 +00:00
aliases = > [ qw( perimeter_offsets ) ] ,
2011-10-05 16:13:47 +00:00
} ,
'solid_layers' = > {
label = > 'Solid layers' ,
2011-12-01 21:03:13 +00:00
cli = > 'solid-layers=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
} ,
2011-11-13 17:14:02 +00:00
'fill_pattern' = > {
label = > 'Fill pattern' ,
2011-12-01 21:03:13 +00:00
cli = > 'fill-pattern=s' ,
2011-11-13 17:14:02 +00:00
type = > 'select' ,
2011-11-26 09:38:05 +00:00
values = > [ qw( rectilinear line concentric hilbertcurve archimedeanchords octagramspiral ) ] ,
2011-11-26 21:41:23 +00:00
labels = > [ qw( rectilinear line concentric ) , 'hilbertcurve (slow)' , 'archimedeanchords (slow)' , 'octagramspiral (slow)' ] ,
2011-11-13 17:14:02 +00:00
} ,
'solid_fill_pattern' = > {
label = > 'Solid fill pattern' ,
2011-12-01 21:03:13 +00:00
cli = > 'solid-fill-pattern=s' ,
2011-11-13 17:14:02 +00:00
type = > 'select' ,
2011-11-26 09:38:05 +00:00
values = > [ qw( rectilinear concentric hilbertcurve archimedeanchords octagramspiral ) ] ,
2011-11-26 21:41:23 +00:00
labels = > [ qw( rectilinear concentric ) , 'hilbertcurve (slow)' , 'archimedeanchords (slow)' , 'octagramspiral (slow)' ] ,
2011-11-13 17:14:02 +00:00
} ,
2011-10-05 16:13:47 +00:00
'fill_density' = > {
label = > 'Fill density' ,
2011-12-01 21:03:13 +00:00
cli = > 'fill-density=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
'fill_angle' = > {
label = > 'Fill angle (°)' ,
2011-12-01 21:03:13 +00:00
cli = > 'fill-angle=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
} ,
2012-02-19 11:03:36 +00:00
'support_material' = > {
label = > 'Generate support material' ,
cli = > 'support-material' ,
type = > 'bool' ,
} ,
2012-02-19 16:02:49 +00: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 14:24:55 +00:00
'start_gcode' = > {
2012-03-26 20:33:43 +00:00
label = > 'Start G-code' ,
2011-12-01 21:03:13 +00:00
cli = > 'start-gcode=s' ,
2011-10-14 14:24:55 +00:00
type = > 's' ,
2011-11-13 21:48:21 +00:00
multiline = > 1 ,
width = > 350 ,
2012-03-26 10:14:15 +00:00
height = > 120 ,
2011-10-14 14:24:55 +00:00
serialize = > sub { join '\n' , split /\R+/ , $ _ [ 0 ] } ,
deserialize = > sub { join "\n" , split /\\n/ , $ _ [ 0 ] } ,
} ,
'end_gcode' = > {
2012-03-26 20:33:43 +00:00
label = > 'End G-code' ,
2011-12-01 21:03:13 +00:00
cli = > 'end-gcode=s' ,
2011-10-14 14:24:55 +00:00
type = > 's' ,
2011-11-13 21:48:21 +00:00
multiline = > 1 ,
width = > 350 ,
2012-03-26 10:14:15 +00:00
height = > 120 ,
serialize = > sub { join '\n' , split /\R+/ , $ _ [ 0 ] } ,
deserialize = > sub { join "\n" , split /\\n/ , $ _ [ 0 ] } ,
} ,
'layer_gcode' = > {
2012-03-26 20:33:43 +00:00
label = > 'Layer Change G-code' ,
2012-03-26 10:14:15 +00:00
cli = > 'layer-gcode=s' ,
type = > 's' ,
multiline = > 1 ,
width = > 350 ,
height = > 50 ,
2011-10-14 14:24:55 +00:00
serialize = > sub { join '\n' , split /\R+/ , $ _ [ 0 ] } ,
deserialize = > sub { join "\n" , split /\\n/ , $ _ [ 0 ] } ,
} ,
2012-02-20 11:50:05 +00: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 16:13:47 +00:00
# retraction options
'retract_length' = > {
label = > 'Length (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'retract-length=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
'retract_speed' = > {
label = > 'Speed (mm/s)' ,
2012-03-26 13:20:59 +00:00
cli = > 'retract-speed=f' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
} ,
'retract_restart_extra' = > {
label = > 'Extra length on restart (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'retract-restart-extra=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
'retract_before_travel' = > {
label = > 'Minimum travel after retraction (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'retract-before-travel=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
2011-11-07 14:58:47 +00:00
'retract_lift' = > {
label = > 'Lift Z (mm)' ,
2011-12-01 21:03:13 +00:00
cli = > 'retract-lift=f' ,
2011-11-07 14:58:47 +00:00
type = > 'f' ,
} ,
2011-10-05 16:13:47 +00:00
2012-02-25 20:01:00 +00:00
# cooling options
2012-02-25 20:56:36 +00:00
'cooling' = > {
label = > 'Enable cooling' ,
cli = > 'cooling' ,
type = > 'bool' ,
} ,
2012-02-25 20:01:00 +00: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 13:20:59 +00:00
cli = > 'min-print-speed=f' ,
2012-02-25 20:01:00 +00: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 21:21:30 +00:00
'fan_always_on' = > {
label = > 'Keep fan always on' ,
cli = > 'fan-always-on' ,
type = > 'bool' ,
} ,
2012-02-25 20:01:00 +00:00
2011-10-05 16:13:47 +00:00
# skirt options
'skirts' = > {
label = > 'Loops' ,
2011-12-01 21:03:13 +00:00
cli = > 'skirts=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
} ,
'skirt_distance' = > {
label = > 'Distance from object (mm)' ,
2012-03-26 13:20:59 +00:00
cli = > 'skirt-distance=f' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
} ,
2011-11-13 17:41:12 +00:00
'skirt_height' = > {
label = > 'Skirt height (layers)' ,
2011-12-01 21:03:13 +00:00
cli = > 'skirt-height=i' ,
2011-11-13 17:41:12 +00:00
type = > 'i' ,
} ,
2011-10-05 16:13:47 +00:00
# transform options
'scale' = > {
label = > 'Scale' ,
2011-12-01 21:03:13 +00:00
cli = > 'scale=f' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
} ,
'rotate' = > {
label = > 'Rotate (°)' ,
2011-12-01 21:03:13 +00:00
cli = > 'rotate=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
} ,
2012-03-06 03:55:21 +00:00
'duplicate' = > {
label = > 'Copies (auto arrange)' ,
cli = > 'duplicate=i' ,
type = > 'i' ,
} ,
2011-11-07 14:49:07 +00:00
'duplicate_x' = > {
label = > 'Copies along X' ,
2011-12-01 21:03:13 +00:00
cli = > 'duplicate-x=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
2011-11-07 16:16:34 +00:00
aliases = > [ qw( multiply_x ) ] ,
2011-10-05 16:13:47 +00:00
} ,
2011-11-07 14:49:07 +00:00
'duplicate_y' = > {
label = > 'Copies along Y' ,
2011-12-01 21:03:13 +00:00
cli = > 'duplicate-y=i' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
2011-11-07 16:16:34 +00:00
aliases = > [ qw( multiply_y ) ] ,
2011-10-05 16:13:47 +00:00
} ,
2011-11-07 14:49:07 +00:00
'duplicate_distance' = > {
label = > 'Distance between copies' ,
2012-03-26 13:20:59 +00:00
cli = > 'duplicate-distance=f' ,
2011-10-05 16:13:47 +00:00
type = > 'i' ,
2011-11-07 16:16:34 +00:00
aliases = > [ qw( multiply_distance ) ] ,
2011-10-05 16:13:47 +00: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 16:20:26 +00: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 11:50:05 +00: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 16:13:47 +00:00
sub save {
my $ class = shift ;
my ( $ file ) = @ _ ;
open my $ fh , '>' , $ file ;
2012-02-12 22:33:25 +00:00
binmode $ fh , ':utf8' ;
2011-10-05 16:13:47 +00: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 19:10:23 +00:00
local $/ = "\n" ;
2011-10-05 16:13:47 +00:00
open my $ fh , '<' , $ file ;
2012-02-12 22:33:25 +00:00
binmode $ fh , ':utf8' ;
2011-10-05 16:13:47 +00:00
while ( <$fh> ) {
2012-01-22 19:10:23 +00:00
s/\R+$// ;
2011-12-04 19:41:17 +00:00
next if /^\s+/ ;
next if /^$/ ;
2011-10-05 16:13:47 +00:00
next if /^\s*#/ ;
2011-12-01 21:06:07 +00:00
/^(\w+) = (.*)/ or die "Unreadable configuration file (invalid data at line $.)\n" ;
2011-11-07 16:16:34 +00:00
my $ key = $ 1 ;
if ( ! exists $ Options - > { $ key } ) {
$ key = + ( grep { $ Options - > { $ _ } { aliases } && grep $ _ eq $ key , @ { $ Options - > { $ _ } { aliases } } }
2011-12-10 09:39:07 +00:00
keys %$ Options ) [ 0 ] or warn "Unknown option $1 at line $.\n" ;
2011-11-07 16:16:34 +00:00
}
2011-12-10 09:39:07 +00:00
next unless $ key ;
2011-11-07 16:16:34 +00:00
my $ opt = $ Options - > { $ key } ;
set ( $ key , $ opt - > { deserialize } ? $ opt - > { deserialize } - > ( $ 2 ) : $ 2 ) ;
2011-10-05 16:13:47 +00:00
}
close $ fh ;
}
2011-10-14 14:24:55 +00:00
sub validate_cli {
my $ class = shift ;
my ( $ opt ) = @ _ ;
2012-03-26 10:14:15 +00:00
for ( qw( start end layer ) ) {
2011-10-14 14:24:55 +00: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 21:03:13 +00:00
$ opt - > { $ _ . "_gcode" } = do { local $/ ; <$fh> } ;
2011-10-14 14:24:55 +00:00
close $ fh ;
}
}
}
}
2011-10-03 09:55:32 +00:00
sub validate {
my $ class = shift ;
2012-04-10 14:26:56 +00: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 09:55:32 +00: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 18:08:19 +00:00
# --first-layer-height-ratio
die "Invalid value for --first-layer-height-ratio\n"
if $ Slic3r:: first_layer_height_ratio < 0 ;
2011-10-03 09:55:32 +00: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 18:08:19 +00: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 15:58:15 +00: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 09:55:32 +00:00
2011-11-25 09:58:13 +00:00
if ( $ Slic3r:: extrusion_width_ratio ) {
2011-12-13 16:34:31 +00: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 18:52:34 +00: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 16:34:31 +00:00
2011-12-17 18:52:34 +00:00
my $ min_flow_width = $ Slic3r:: nozzle_diameter * 1.05 ;
my $ max_flow_width = $ Slic3r:: nozzle_diameter * 1.4 ;
2011-12-15 11:50:02 +00:00
$ Slic3r:: flow_width = $ max_flow_width if $ Slic3r:: flow_width > $ max_flow_width ;
2011-12-17 18:52:34 +00:00
$ Slic3r:: flow_width = $ min_flow_width if $ Slic3r:: flow_width < $ min_flow_width ;
}
if ( $ Slic3r:: flow_width >= ( $ Slic3r:: nozzle_diameter + $ Slic3r:: layer_height ) ) {
2011-12-18 09:50:55 +00:00
# rectangle with semicircles at the ends
2011-12-17 18:52:34 +00: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 ;
2011-11-25 09:58:13 +00:00
}
2011-12-17 18:52:34 +00:00
$ Slic3r:: flow_spacing = $ Slic3r:: flow_width - $ Slic3r:: overlap_factor * ( $ Slic3r:: flow_width - $ Slic3r:: min_flow_spacing ) ;
2011-10-03 09:55:32 +00:00
Slic3r:: debugf "Flow width = $Slic3r::flow_width\n" ;
2011-12-17 18:52:34 +00:00
Slic3r:: debugf "Flow spacing = $Slic3r::flow_spacing\n" ;
2012-02-15 11:04:10 +00:00
Slic3r:: debugf "Min flow spacing = $Slic3r::min_flow_spacing\n" ;
2011-10-03 09:55:32 +00:00
# --perimeters
die "Invalid value for --perimeters\n"
2012-03-26 09:32:59 +00:00
if $ Slic3r:: perimeters < 0 ;
2011-10-03 09:55:32 +00:00
# --solid-layers
die "Invalid value for --solid-layers\n"
2011-11-30 01:51:34 +00:00
if $ Slic3r:: solid_layers < 0 ;
2011-10-03 09:55:32 +00: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 17:14:02 +00: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 13:24:21 +00:00
2011-10-03 09:55:32 +00:00
# --fill-density
die "Invalid value for --fill-density\n"
if $ Slic3r:: fill_density < 0 || $ Slic3r:: fill_density > 1 ;
2011-10-18 13:57:53 +00: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 09:55:32 +00:00
# --scale
die "Invalid value for --scale\n"
if $ Slic3r:: scale <= 0 ;
2012-03-06 03:55:21 +00:00
# --duplicate
die "Invalid value for --duplicate\n"
if $ Slic3r:: duplicate < 1 ;
2011-11-07 14:49:07 +00:00
# --duplicate-x
die "Invalid value for --duplicate-x\n"
if $ Slic3r:: duplicate_x < 1 ;
2011-10-03 09:55:32 +00:00
2011-11-07 14:49:07 +00:00
# --duplicate-y
die "Invalid value for --duplicate-y\n"
if $ Slic3r:: duplicate_y < 1 ;
2012-03-06 03:55:21 +00: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 09:55:32 +00:00
2011-11-07 14:49:07 +00:00
# --duplicate-distance
die "Invalid value for --duplicate-distance\n"
if $ Slic3r:: duplicate_distance < 1 ;
2011-11-13 17:41:12 +00:00
# --skirt-height
die "Invalid value for --skirt-height\n"
2011-12-16 08:55:13 +00:00
if $ Slic3r:: skirt_height < 0 ;
2011-11-28 17:37:53 +00:00
2012-02-19 08:32:16 +00:00
# --bridge-flow-ratio
die "Invalid value for --bridge-flow-ratio\n"
if $ Slic3r:: bridge_flow_ratio <= 0 ;
2012-03-01 03:08:07 +00:00
2012-03-06 03:55:21 +00:00
$ Slic3r:: first_layer_temperature // = $ Slic3r:: temperature ; #/
$ Slic3r:: first_layer_bed_temperature // = $ Slic3r:: bed_temperature ; #/
2012-02-19 08:32:16 +00:00
2012-02-20 10:44:30 +00:00
# G-code flavors
$ Slic3r:: extrusion_axis = 'A' if $ Slic3r:: gcode_flavor eq 'mach3' ;
2012-04-08 19:27:38 +00:00
$ Slic3r:: extrusion_axis = '' if $ Slic3r:: gcode_flavor eq 'no-extrusion' ;
2012-02-20 10:44:30 +00:00
2011-11-28 17:37:53 +00:00
# legacy with existing config files
2011-12-04 19:50:03 +00:00
$ Slic3r:: small_perimeter_speed || = $ Slic3r:: perimeter_speed ;
2011-12-01 21:03:13 +00:00
$ Slic3r:: bridge_speed || = $ Slic3r:: infill_speed ;
$ Slic3r:: solid_infill_speed || = $ Slic3r:: infill_speed ;
2011-10-03 09:55:32 +00:00
}
2012-03-03 22:29:08 +00: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 09:55:32 +00:00
1 ;