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 ) ;
2012-04-11 13:58:09 +00:00
# cemetery of old config settings
2012-06-28 14:22:11 +00:00
our @ Ignore = qw( duplicate_x duplicate_y multiply_x multiply_y support_material_tool ) ;
2012-04-11 13:58:09 +00:00
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-06-23 20:43:23 +00:00
width = > 400 ,
height = > 100 ,
2012-02-05 19:55:17 +00:00
serialize = > sub { join '\n' , split /\R/ , $ _ [ 0 ] } ,
deserialize = > sub { join "\n" , split /\\n/ , $ _ [ 0 ] } ,
} ,
2012-05-19 13:08:32 +00:00
'threads' = > {
label = > 'Threads (more speed, more memory usage)' ,
cli = > 'threads|j=i' ,
type = > 'i' ,
} ,
2012-02-05 19:55:17 +00:00
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
'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' ,
2012-06-18 21:39:53 +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' ,
2012-06-18 21:39:53 +00:00
cli = > 'gcode-arcs!' ,
2011-12-01 21:03:13 +00:00
type = > 'bool' ,
} ,
'g0' = > {
2012-02-06 20:17:01 +00:00
label = > 'Use G0 for travel moves' ,
2012-06-18 21:39:53 +00:00
cli = > 'g0!' ,
2011-12-01 21:03:13 +00:00
type = > 'bool' ,
} ,
2011-12-14 18:49:21 +00:00
'gcode_comments' = > {
2012-03-03 21:53:12 +00:00
label = > 'Verbose G-code' ,
2012-06-18 21:39:53 +00:00
cli = > 'gcode-comments!' ,
2011-12-14 18:49:21 +00:00
type = > 'bool' ,
} ,
2011-10-05 16:13:47 +00:00
2012-06-28 12:44:54 +00:00
# extruders options
'nozzle_diameter' = > {
label = > 'Nozzle diameter (mm)' ,
cli = > 'nozzle-diameter=f@' ,
type = > 'f' ,
important = > 1 ,
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
} ,
2011-10-05 16:13:47 +00:00
'filament_diameter' = > {
label = > 'Diameter (mm)' ,
2012-06-28 12:44:54 +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 ,
2012-06-28 12:44:54 +00:00
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
2011-10-05 16:13:47 +00:00
} ,
2011-11-25 10:15:20 +00:00
'extrusion_multiplier' = > {
label = > 'Extrusion multiplier' ,
2012-06-28 12:44:54 +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 ) ] ,
2012-06-28 12:44:54 +00:00
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
2011-10-05 16:13:47 +00:00
} ,
2012-06-28 14:22:11 +00:00
'temperature' = > {
label = > 'Temperature (°C)' ,
cli = > 'temperature=i@' ,
type = > 'i' ,
important = > 1 ,
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
} ,
2012-02-26 13:54:38 +00:00
'first_layer_temperature' = > {
label = > 'First layer temperature (°C)' ,
2012-06-28 14:22:11 +00:00
cli = > 'first-layer-temperature=i@' ,
2012-02-26 13:54:38 +00:00
type = > 'i' ,
2012-06-28 14:22:11 +00:00
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
2012-02-26 13:54:38 +00:00
} ,
2012-06-28 14:22:11 +00:00
2012-06-28 14:48:56 +00:00
# extruder mapping
2012-06-30 22:18:15 +00:00
'perimeter_extruder' = > {
label = > 'Perimeter extruder' ,
cli = > 'perimeter-extruder=i' ,
2012-06-28 14:48:56 +00:00
type = > 'i' ,
2012-06-30 22:18:15 +00:00
aliases = > [ qw( perimeters_extruder ) ] ,
2012-06-28 14:48:56 +00:00
} ,
'infill_extruder' = > {
label = > 'Infill extruder' ,
cli = > 'infill-extruder=i' ,
type = > 'i' ,
} ,
'support_material_extruder' = > {
label = > 'Extruder' ,
cli = > 'support-material-extruder=i' ,
type = > 'i' ,
} ,
2012-06-28 14:22:11 +00:00
# filament options
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' ,
} ,
'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' = > {
2012-06-06 17:57:16 +00:00
label = > 'Small perimeters (mm/s or %)' ,
2012-06-19 09:38:12 +00:00
cli = > 'small-perimeter-speed=s' ,
2012-06-27 17:37:34 +00:00
type = > 'f' ,
ratio_over = > 'perimeter_speed' ,
} ,
'external_perimeter_speed' = > {
label = > 'External perimeters (mm/s or %)' ,
cli = > 'external-perimeter-speed=s' ,
2011-12-04 19:50:03 +00:00
type = > 'f' ,
2012-06-06 17:57:16 +00:00
ratio_over = > 'perimeter_speed' ,
2011-12-04 19:50:03 +00:00
} ,
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' = > {
2012-06-06 17:57:16 +00:00
label = > 'Solid infill (mm/s or %)' ,
2012-06-19 09:38:12 +00:00
cli = > 'solid-infill-speed=s' ,
2011-10-05 16:13:47 +00:00
type = > 'f' ,
2012-06-06 17:57:16 +00:00
ratio_over = > 'infill_speed' ,
2011-12-01 21:03:13 +00:00
aliases = > [ qw( solid_infill_feed_rate ) ] ,
2011-10-05 16:13:47 +00:00
} ,
2012-06-06 17:57:16 +00:00
'top_solid_infill_speed' = > {
2012-06-11 11:45:03 +00:00
label = > 'Top solid infill (mm/s or %)' ,
2012-06-19 09:38:12 +00:00
cli = > 'top-solid-infill-speed=s' ,
2012-06-06 17:57:16 +00:00
type = > 'f' ,
ratio_over = > 'solid_infill_speed' ,
} ,
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
} ,
2012-06-06 13:52:21 +00:00
'first_layer_speed' = > {
label = > 'First layer speed (mm/s or %)' ,
2012-06-06 15:29:12 +00:00
cli = > 'first-layer-speed=s' ,
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' ,
2012-06-18 21:39:53 +00:00
cli = > 'acceleration!' ,
2012-02-10 13:53:44 +00:00
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' ,
} ,
2012-06-06 14:11:38 +00:00
'first_layer_height' = > {
label = > 'First layer height (mm or %)' ,
2012-06-06 15:29:12 +00:00
cli = > 'first-layer-height=s' ,
2011-12-07 18:33:59 +00:00
type = > 'f' ,
2012-06-06 17:57:16 +00:00
ratio_over = > 'layer_height' ,
2011-12-07 18:33:59 +00:00
} ,
'infill_every_layers' = > {
label = > 'Infill every N layers' ,
cli = > 'infill-every-layers=i' ,
type = > 'i' ,
} ,
# flow options
2012-06-06 13:23:34 +00:00
'extrusion_width' = > {
label = > 'Extrusion width (mm or %; leave zero to calculate automatically)' ,
2012-06-06 15:29:12 +00:00
cli = > 'extrusion-width=s' ,
type = > 'f' ,
} ,
'first_layer_extrusion_width' = > {
2012-06-06 16:05:03 +00:00
label = > 'First layer extrusion width (mm or % or 0 for default)' ,
2012-06-06 15:29:12 +00:00
cli = > 'first-layer-extrusion-width=s' ,
2011-11-25 09:58:13 +00:00
type = > 'f' ,
} ,
2012-06-30 22:18:15 +00:00
'perimeter_extrusion_width' = > {
label = > 'Perimeter extrusion width (mm or % or 0 for default)' ,
cli = > 'perimeter-extrusion-width=s' ,
2012-06-06 16:05:03 +00:00
type = > 'f' ,
2012-06-30 22:18:15 +00:00
aliases = > [ qw( perimeters_extrusion_width ) ] ,
2012-06-06 16:05:03 +00:00
} ,
'infill_extrusion_width' = > {
label = > 'Infill extrusion width (mm or % or 0 for default)' ,
cli = > 'infill-extrusion-width=s' ,
type = > 'f' ,
} ,
2012-06-28 14:33:07 +00:00
'support_material_extrusion_width' = > {
label = > 'Support material extrusion width (mm or % or 0 for default)' ,
cli = > 'support-material-extrusion-width=s' ,
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' = > {
2012-06-23 15:10:30 +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' ,
2012-04-16 09:55:14 +00:00
values = > [ qw( rectilinear line concentric honeycomb hilbertcurve archimedeanchords octagramspiral ) ] ,
labels = > [ qw( rectilinear line concentric honeycomb ) , '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-06-23 15:10:30 +00:00
'extra_perimeters' = > {
label = > 'Generate extra perimeters when needed' ,
cli = > 'extra-perimeters!' ,
type = > 'bool' ,
} ,
2012-05-19 20:36:29 +00:00
'randomize_start' = > {
label = > 'Randomize starting points' ,
2012-06-18 21:39:53 +00:00
cli = > 'randomize-start!' ,
2012-05-19 20:36:29 +00:00
type = > 'bool' ,
} ,
2012-02-19 11:03:36 +00:00
'support_material' = > {
label = > 'Generate support material' ,
2012-06-18 21:39:53 +00:00
cli = > 'support-material!' ,
2012-02-19 11:03:36 +00:00
type = > 'bool' ,
} ,
2012-06-23 21:54:39 +00:00
'support_material_threshold' = > {
label = > 'Overhang threshold (°)' ,
cli = > 'support-material-threshold=i' ,
type = > 'i' ,
} ,
2012-06-23 20:43:23 +00:00
'support_material_pattern' = > {
label = > 'Pattern' ,
cli = > 'support-material-pattern=s' ,
type = > 'select' ,
values = > [ qw( rectilinear honeycomb ) ] ,
labels = > [ qw( rectilinear honeycomb ) ] ,
} ,
2012-06-24 12:39:35 +00:00
'support_material_spacing' = > {
label = > 'Pattern spacing (mm)' ,
cli = > 'support-material-spacing=f' ,
type = > 'f' ,
} ,
2012-06-23 20:43:23 +00:00
'support_material_angle' = > {
2012-06-23 21:54:39 +00:00
label = > 'Pattern angle (°)' ,
2012-06-23 20:43:23 +00:00
cli = > 'support-material-angle=i' ,
type = > 'i' ,
} ,
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-06-06 15:29:12 +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' ,
2012-06-18 21:39:53 +00:00
cli = > 'cooling!' ,
2012-02-25 20:56:36 +00:00
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' ,
2012-06-18 21:39:53 +00:00
cli = > 'fan-always-on!' ,
2012-03-03 21:21:30 +00:00
type = > 'bool' ,
} ,
2012-02-25 20:01:00 +00:00
2012-06-23 19:31:29 +00:00
# skirt/brim options
2011-10-05 16:13:47 +00:00
'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' ,
2012-06-23 19:31:29 +00:00
type = > 'f' ,
2011-10-05 16:13:47 +00:00
} ,
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' ,
} ,
2012-06-23 20:27:59 +00:00
'brim_width' = > {
label = > 'Brim width (mm)' ,
cli = > 'brim-width=f' ,
2012-06-23 19:31:29 +00:00
type = > 'f' ,
} ,
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-04-11 15:38:56 +00:00
'duplicate_mode' = > {
label = > 'Duplicate' ,
gui_only = > 1 ,
type = > 'select' ,
values = > [ qw( no autoarrange grid ) ] ,
labels = > [ 'No' , 'Autoarrange' , 'Grid' ] ,
} ,
2012-03-06 03:55:21 +00:00
'duplicate' = > {
2012-04-11 14:30:58 +00:00
label = > 'Copies (autoarrange)' ,
2012-03-06 03:55:21 +00:00
cli = > 'duplicate=i' ,
type = > 'i' ,
} ,
2012-04-11 14:30:58 +00:00
'bed_size' = > {
2012-04-30 12:56:01 +00:00
label = > 'Bed size (mm)' ,
2012-04-11 14:30:58 +00:00
cli = > 'bed-size=s' ,
type = > 'point' ,
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
} ,
2012-04-11 13:58:09 +00:00
'duplicate_grid' = > {
label = > 'Copies (grid)' ,
cli = > 'duplicate-grid=s' ,
type = > 'point' ,
serialize = > sub { join ',' , @ { $ _ [ 0 ] } } ,
deserialize = > sub { [ split /,/ , $ _ [ 0 ] ] } ,
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
} ,
2012-05-23 09:47:52 +00:00
# sequential printing options
'complete_objects' = > {
label = > 'Complete individual objects (watch out for extruder collisions)' ,
2012-06-18 21:39:53 +00:00
cli = > 'complete-objects!' ,
2012-05-23 09:47:52 +00:00
type = > 'bool' ,
} ,
'extruder_clearance_radius' = > {
label = > 'Extruder clearance radius (mm)' ,
cli = > 'extruder-clearance-radius=f' ,
type = > 'i' ,
} ,
'extruder_clearance_height' = > {
label = > 'Extruder clearance height (mm)' ,
cli = > 'extruder-clearance-height=f' ,
type = > 'i' ,
} ,
2011-10-05 16:13:47 +00:00
} ;
sub get {
my $ class = @ _ == 2 ? shift : undef ;
my ( $ opt_key ) = @ _ ;
no strict 'refs' ;
2012-06-06 17:57:16 +00:00
my $ value = $ { "Slic3r::$opt_key" } ;
$ value = get ( $ Options - > { $ opt_key } { ratio_over } ) * $ 1 / 100
if $ Options - > { $ opt_key } { ratio_over } && $ value =~ /^(\d+(?:\.\d+)?)%$/ ;
return $ value ;
2011-10-05 16:13:47 +00:00
}
2012-06-19 13:32:56 +00:00
sub get_raw {
my $ class = @ _ == 2 ? shift : undef ;
my ( $ opt_key ) = @ _ ;
no strict 'refs' ;
my $ value = $ { "Slic3r::$opt_key" } ;
return $ value ;
}
2011-10-05 16:13:47 +00:00
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 }
2012-06-19 13:32:56 +00:00
? $ Options - > { $ opt_key } { serialize } - > ( get_raw ( $ opt_key ) )
: get_raw ( $ opt_key ) ;
2011-12-26 16:20:26 +00:00
}
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' ;
2012-07-01 16:53:01 +00:00
printf $ fh "# generated by Slic3r $Slic3r::VERSION\n" ;
2011-10-05 16:13:47 +00:00
foreach my $ opt ( sort keys %$ Options ) {
2012-04-11 15:38:56 +00:00
next if $ Options - > { $ opt } { gui_only } ;
2012-06-19 13:32:56 +00:00
my $ value = get_raw ( $ opt ) ;
2011-10-05 16:13:47 +00:00
$ value = $ Options - > { $ opt } { serialize } - > ( $ value ) if $ Options - > { $ opt } { serialize } ;
printf $ fh "%s = %s\n" , $ opt , $ value ;
}
close $ fh ;
}
2012-06-09 15:52:03 +00:00
sub setenv {
my $ class = shift ;
foreach my $ opt ( sort keys %$ Options ) {
next if $ Options - > { $ opt } { gui_only } ;
my $ value = get ( $ opt ) ;
$ value = $ Options - > { $ opt } { serialize } - > ( $ value ) if $ Options - > { $ opt } { serialize } ;
$ ENV { "SLIC3R_" . uc $ opt } = $ value ;
}
}
2011-10-05 16:13:47 +00:00
sub load {
my $ class = shift ;
my ( $ file ) = @ _ ;
2012-04-11 13:58:09 +00:00
my % ignore = map { $ _ = > 1 } @ Ignore ;
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" ;
2012-06-06 13:23:34 +00:00
my ( $ key , $ val ) = ( $ 1 , $ 2 ) ;
# handle legacy options
2012-04-11 13:58:09 +00:00
next if $ ignore { $ key } ;
2012-06-06 16:47:11 +00:00
if ( $ key =~ /^(extrusion_width|bottom_layer_speed|first_layer_height)_ratio$/ ) {
2012-06-06 13:48:14 +00:00
$ key = $ 1 ;
2012-06-06 13:52:21 +00:00
$ key =~ s/^bottom_layer_speed$/first_layer_speed/ ;
2012-06-07 09:24:45 +00:00
$ val = $ val =~ /^\d+(?:\.\d+)?$/ && $ val != 0 ? ( $ val * 100 ) . "%" : 0 ;
2012-06-06 13:23:34 +00:00
}
2011-11-07 16:16:34 +00:00
if ( ! exists $ Options - > { $ key } ) {
$ key = + ( grep { $ Options - > { $ _ } { aliases } && grep $ _ eq $ key , @ { $ Options - > { $ _ } { aliases } } }
2012-06-06 13:23:34 +00:00
keys %$ Options ) [ 0 ] or warn "Unknown option $key 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 } ;
2012-06-06 13:23:34 +00:00
set ( $ key , $ opt - > { deserialize } ? $ opt - > { deserialize } - > ( $ val ) : $ val ) ;
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"
2012-05-20 15:21:31 +00:00
if $ Slic3r:: threads < 1 ;
2012-04-10 14:26:56 +00:00
die "Your perl wasn't built with multithread support\n"
2012-05-20 15:21:31 +00:00
if $ Slic3r:: threads > 1 && ! $ 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"
2012-04-16 12:05:38 +00:00
if $ Slic3r:: layer_height / $ Slic3r:: scaling_factor % 1 != 0 ;
2011-10-03 09:55:32 +00:00
2012-06-06 14:11:38 +00:00
# --first-layer-height
die "Invalid value for --first-layer-height\n"
if $ Slic3r:: first_layer_height !~ /^(?:\d+(?:\.\d+)?)%?$/ ;
2012-06-06 17:57:16 +00:00
$ Slic3r:: _first_layer_height = Slic3r::Config - > get ( 'first_layer_height' ) ;
2011-11-13 18:08:19 +00:00
2011-10-03 09:55:32 +00:00
# --filament-diameter
die "Invalid value for --filament-diameter\n"
2012-06-28 12:49:20 +00:00
if grep $ _ < 1 , @$ Slic3r:: filament_diameter ;
2011-10-03 09:55:32 +00:00
# --nozzle-diameter
die "Invalid value for --nozzle-diameter\n"
2012-06-28 12:44:54 +00:00
if grep $ _ < 0 , @$ Slic3r:: nozzle_diameter ;
2011-10-03 09:55:32 +00:00
die "--layer-height can't be greater than --nozzle-diameter\n"
2012-06-28 12:44:54 +00:00
if grep $ 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"
2012-06-28 12:44:54 +00:00
if grep $ Slic3r:: _first_layer_height > $ _ , @$ Slic3r:: nozzle_diameter ;
# initialize extruder(s)
$ Slic3r:: extruders = [] ;
2012-06-30 22:18:15 +00:00
for my $ t ( 0 , map $ _ - 1 , $ Slic3r:: perimeter_extruder , $ Slic3r:: infill_extruder , $ Slic3r:: support_material_extruder ) {
2012-06-28 14:22:11 +00:00
$ Slic3r:: extruders - > [ $ t ] || = Slic3r::Extruder - > new (
map { $ _ = > Slic3r::Config - > get ( $ _ ) - > [ $ t ] // Slic3r::Config - > get ( $ _ ) - > [ 0 ] } #/
qw( nozzle_diameter filament_diameter extrusion_multiplier temperature first_layer_temperature )
) ;
}
2011-10-03 09:55:32 +00:00
2012-06-06 15:29:12 +00:00
# calculate flow
2012-06-28 12:44:54 +00:00
$ Slic3r:: flow = $ Slic3r:: extruders - > [ 0 ] - > make_flow ( width = > $ Slic3r:: extrusion_width ) ;
2012-06-07 09:17:35 +00:00
if ( $ Slic3r:: first_layer_extrusion_width ) {
2012-06-28 12:44:54 +00:00
$ Slic3r:: first_layer_flow = $ Slic3r:: extruders - > [ 0 ] - > make_flow (
layer_height = > $ Slic3r:: _first_layer_height ,
width = > $ Slic3r:: first_layer_extrusion_width ,
) ;
2012-06-07 09:17:35 +00:00
}
2012-06-30 22:18:15 +00:00
$ Slic3r:: perimeters_flow = $ Slic3r:: extruders - > [ $ Slic3r:: perimeter_extruder - 1 ]
- > make_flow ( width = > $ Slic3r:: perimeter_extrusion_width || $ Slic3r:: extrusion_width ) ;
2012-06-28 14:48:56 +00:00
$ Slic3r:: infill_flow = $ Slic3r:: extruders - > [ $ Slic3r:: infill_extruder - 1 ]
- > make_flow ( width = > $ Slic3r:: infill_extrusion_width || $ Slic3r:: extrusion_width ) ;
$ Slic3r:: support_material_flow = $ Slic3r:: extruders - > [ $ Slic3r:: support_material_extruder - 1 ]
2012-06-28 14:33:07 +00:00
- > make_flow ( width = > $ Slic3r:: support_material_extrusion_width || $ Slic3r:: extrusion_width ) ;
2012-06-27 17:49:53 +00:00
2012-07-03 16:05:31 +00:00
Slic3r:: debugf "Default flow width = %s (spacing = %s)\n" ,
$ Slic3r:: flow - > width , $ Slic3r:: flow - > spacing ;
2012-06-06 15:29:12 +00:00
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+$/ ) ;
2012-04-11 16:18:01 +00:00
$ Slic3r:: print_center = [ split /[,x]/ , $ Slic3r:: print_center ]
2011-10-03 09:55:32 +00:00
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 ;
2012-06-28 12:44:54 +00:00
# TODO: this check should be limited to the extruder used for infill
2011-10-18 13:57:53 +00:00
die "Maximum infill thickness can't exceed nozzle diameter\n"
2012-06-28 12:44:54 +00:00
if grep $ Slic3r:: infill_every_layers * $ Slic3r:: layer_height > $ _ , @$ Slic3r:: nozzle_diameter ;
2011-10-18 13:57:53 +00:00
2011-10-03 09:55:32 +00:00
# --scale
die "Invalid value for --scale\n"
if $ Slic3r:: scale <= 0 ;
2012-04-11 15:52:06 +00:00
# --bed-size
die "Invalid value for --bed-size\n"
if ! ref $ Slic3r:: bed_size
&& ( ! $ Slic3r:: bed_size || $ Slic3r:: bed_size !~ /^\d+,\d+$/ ) ;
2012-04-11 16:18:01 +00:00
$ Slic3r:: bed_size = [ split /[,x]/ , $ Slic3r:: bed_size ]
2012-04-11 15:52:06 +00:00
if ! ref $ Slic3r:: bed_size ;
# --duplicate-grid
die "Invalid value for --duplicate-grid\n"
if ! ref $ Slic3r:: duplicate_grid
&& ( ! $ Slic3r:: duplicate_grid || $ Slic3r:: duplicate_grid !~ /^\d+,\d+$/ ) ;
2012-04-11 16:18:01 +00:00
$ Slic3r:: duplicate_grid = [ split /[,x]/ , $ Slic3r:: duplicate_grid ]
2012-04-11 15:52:06 +00:00
if ! ref $ Slic3r:: duplicate_grid ;
2012-03-06 03:55:21 +00:00
# --duplicate
2012-04-11 13:58:09 +00:00
die "Invalid value for --duplicate or --duplicate-grid\n"
if ! $ Slic3r:: duplicate || $ Slic3r:: duplicate < 1 || ! $ Slic3r:: duplicate_grid
|| ( grep ! $ _ , @$ Slic3r:: duplicate_grid ) ;
die "Use either --duplicate or --duplicate-grid (using both doesn't make sense)\n"
if $ Slic3r:: duplicate > 1 && $ Slic3r:: duplicate_grid && ( grep $ _ && $ _ > 1 , @$ Slic3r:: duplicate_grid ) ;
2012-04-11 15:38:56 +00:00
$ Slic3r:: duplicate_mode = 'autoarrange' if $ Slic3r:: duplicate > 1 ;
$ Slic3r:: duplicate_mode = 'grid' if grep $ _ && $ _ > 1 , @$ Slic3r:: duplicate_grid ;
2011-10-03 09:55:32 +00:00
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-05-23 09:47:52 +00:00
# extruder clearance
die "Invalid value for --extruder-clearance-radius\n"
if $ Slic3r:: extruder_clearance_radius <= 0 ;
die "Invalid value for --extruder-clearance-height\n"
if $ Slic3r:: extruder_clearance_height <= 0 ;
2012-06-28 14:22:11 +00:00
$ _ - > first_layer_temperature ( $ _ - > temperature ) for grep ! defined $ _ - > first_layer_temperature , @$ Slic3r:: extruders ;
$ Slic3r:: first_layer_temperature - > [ $ _ ] = $ Slic3r:: extruders - > [ $ _ ] - > first_layer_temperature for 0 .. $#$ Slic3r:: extruders ; # this is needed to provide a value to the legacy GUI and for config file re-serialization
2012-03-06 03:55:21 +00:00
$ 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 ;
2012-06-06 17:57:16 +00:00
$ Slic3r:: top_solid_infill_speed || = $ Slic3r:: solid_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 ;
}
2012-05-01 13:01:56 +00:00
my @ lt = localtime ; $ lt [ 5 ] += 1900 ; $ lt [ 4 ] += 1 ;
$ string =~ s/\[timestamp\]/sprintf '%04d%02d%02d-%02d%02d%02d', @lt[5,4,3,2,1,0]/egx ;
$ string =~ s/\[year\]/$lt[5]/eg ;
$ string =~ s/\[month\]/$lt[4]/eg ;
$ string =~ s/\[day\]/$lt[3]/eg ;
$ string =~ s/\[hour\]/$lt[2]/eg ;
$ string =~ s/\[minute\]/$lt[1]/eg ;
$ string =~ s/\[second\]/$lt[0]/eg ;
$ string =~ s/\[version\]/$Slic3r::VERSION/eg ;
2012-03-03 22:29:08 +00:00
# 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 ;