Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--resources/profiles/PrusaResearch.idx9
-rw-r--r--resources/profiles/PrusaResearch.ini322
-rw-r--r--src/boost/nowide/utf8_codecvt.hpp2
-rw-r--r--src/libslic3r/Config.cpp87
-rw-r--r--src/libslic3r/Config.hpp459
-rw-r--r--src/libslic3r/GCode.cpp23
-rw-r--r--src/libslic3r/PlaceholderParser.cpp28
-rw-r--r--src/libslic3r/PlaceholderParser.hpp9
-rw-r--r--src/libslic3r/Print.cpp166
-rw-r--r--src/libslic3r/Print.hpp9
-rw-r--r--src/libslic3r/PrintBase.hpp10
-rw-r--r--src/libslic3r/PrintConfig.cpp47
-rw-r--r--src/libslic3r/PrintConfig.hpp8
-rw-r--r--src/libslic3r/SLAPrint.cpp17
-rw-r--r--src/libslic3r/SLAPrint.hpp2
-rw-r--r--src/slic3r/GUI/Field.cpp123
-rw-r--r--src/slic3r/GUI/Field.hpp22
-rw-r--r--src/slic3r/GUI/GUI.cpp7
-rw-r--r--src/slic3r/GUI/OptionsGroup.cpp54
-rw-r--r--src/slic3r/GUI/OptionsGroup.hpp3
-rw-r--r--src/slic3r/GUI/Preset.cpp4
-rw-r--r--src/slic3r/GUI/PresetBundle.cpp2
-rw-r--r--src/slic3r/GUI/Tab.cpp111
-rw-r--r--src/slic3r/GUI/Tab.hpp5
-rw-r--r--xs/xsp/Print.xsp2
25 files changed, 1110 insertions, 421 deletions
diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx
index de5e3d106..81b1ca15f 100644
--- a/resources/profiles/PrusaResearch.idx
+++ b/resources/profiles/PrusaResearch.idx
@@ -1,4 +1,7 @@
min_slic3r_version = 1.42.0-alpha6
+0.8.3 FW version and SL1 materials update
+0.8.2 FFF and SL1 settings update
+0.8.1 Output settings and SLA materials update
0.8.0 Updated for the PrusaSlicer 2.0.0 final release
0.8.0-rc2 Updated firmware versions for MK2.5/S and MK3/S
0.8.0-rc1 Updated SLA profiles
@@ -18,6 +21,8 @@ min_slic3r_version = 1.42.0-alpha
0.4.0-alpha3 Update of SLA profiles
0.4.0-alpha2 First SLA profiles
min_slic3r_version = 1.41.3-alpha
+0.4.8 MK2.5/3/S FW update
+0.4.7 MK2/S/MMU FW update
0.4.6 Updated firmware versions for MK2.5/S and MK3/S
0.4.5 Enabled remaining time support for MK2/S/MMU1
0.4.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
@@ -26,6 +31,8 @@ min_slic3r_version = 1.41.3-alpha
0.4.1 New MK2.5S and MK3S FW versions
0.4.0 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
min_slic3r_version = 1.41.1
+0.3.8 MK2.5/3/S FW update
+0.3.7 MK2/S/MMU FW update
0.3.6 Updated firmware versions for MK2.5 and MK3
0.3.5 New MK2.5 and MK3 FW versions
0.3.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
@@ -60,6 +67,8 @@ min_slic3r_version = 1.41.0-alpha
0.2.0-alpha1 added initial profiles for the i3 MK3 Multi Material Upgrade 2.0
0.2.0-alpha moved machine limits from the start G-code to the new print profile parameters
min_slic3r_version = 1.40.0
+0.1.16 MK2.5/3/S FW update
+0.1.15 MK2/S/MMU FW update
0.1.14 Updated firmware versions for MK2.5 and MK3
0.1.13 New MK2.5 and MK3 FW versions
0.1.12 New MK2.5 and MK3 FW versions
diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini
index 9db3a7a14..f17066636 100644
--- a/resources/profiles/PrusaResearch.ini
+++ b/resources/profiles/PrusaResearch.ini
@@ -4,8 +4,8 @@
# Vendor name will be shown by the Config Wizard.
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
-# This means, the server may force the Slic3r configuration to be downgraded.
-config_version = 0.8.0
+# This means, the server may force the PrusaSlicer configuration to be downgraded.
+config_version = 0.8.3
# Where to get the updates from?
config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
changelog_url = http://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@@ -105,8 +105,8 @@ external_fill_pattern = rectilinear
external_perimeters_first = 0
external_perimeter_extrusion_width = 0.45
extra_perimeters = 0
-extruder_clearance_height = 20
-extruder_clearance_radius = 20
+extruder_clearance_height = 25
+extruder_clearance_radius = 45
extrusion_width = 0.45
fill_angle = 45
fill_density = 20%
@@ -133,7 +133,7 @@ notes =
overhangs = 0
only_retract_when_crossing_perimeters = 0
ooze_prevention = 0
-output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}.gcode
+output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
perimeters = 2
perimeter_extruder = 1
perimeter_extrusion_width = 0.45
@@ -213,6 +213,7 @@ support_material_interface_layers = 0
support_material_interface_spacing = 0.15
support_material_spacing = 1
support_material_xy_spacing = 150%
+output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
[print:*0.25nozzleMK3*]
external_perimeter_extrusion_width = 0.25
@@ -245,6 +246,7 @@ max_print_speed = 80
perimeters = 3
fill_pattern = grid
fill_density = 20%
+output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
# Print parameters common to a 0.6mm diameter nozzle.
[print:*0.6nozzle*]
@@ -256,6 +258,7 @@ perimeter_extrusion_width = 0.65
solid_infill_extrusion_width = 0.65
top_infill_extrusion_width = 0.6
support_material_extrusion_width = 0.55
+output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
[print:*0.6nozzleMK3*]
external_perimeter_extrusion_width = 0.65
@@ -268,6 +271,7 @@ top_infill_extrusion_width = 0.6
support_material_extrusion_width = 0.55
bridge_flow_ratio = 0.95
bridge_speed = 25
+output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
[print:*soluble_support*]
overhangs = 1
@@ -987,7 +991,7 @@ first_layer_temperature = 215
max_fan_speed = 100
min_fan_speed = 100
temperature = 210
-start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}15{else}30{endif} ; Filament gcode"
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}18{else}30{endif} ; Filament gcode"
[filament:*PET*]
inherits = *common*
@@ -1003,7 +1007,7 @@ first_layer_bed_temperature = 85
first_layer_temperature = 230
max_fan_speed = 50
min_fan_speed = 30
-start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}22{else}45{endif} ; Filament gcode"
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}24{else}45{endif} ; Filament gcode"
temperature = 240
[filament:*PET06*]
@@ -1028,7 +1032,7 @@ first_layer_temperature = 255
max_fan_speed = 30
min_fan_speed = 20
temperature = 255
-start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}15{else}30{endif} ; Filament gcode"
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}18{else}30{endif} ; Filament gcode"
[filament:*FLEX*]
inherits = *common*
@@ -1164,11 +1168,13 @@ temperature = 260
inherits = *PET*
filament_cost = 56.9
filament_density = 1.26
+filament_type = EDGE
filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladec PETG"
[filament:E3D PC-ABS]
inherits = *ABS*
filament_cost = 0
+filament_type = PC
filament_density = 1.05
first_layer_temperature = 270
temperature = 270
@@ -1187,12 +1193,14 @@ filament_density = 1.04
fan_always_on = 1
first_layer_temperature = 265
temperature = 265
+filament_type = ASA
[filament:Fillamentum CPE HG100 HM100]
inherits = *PET*
filament_cost = 54.1
filament_density = 1.25
filament_notes = "CPE HG100 , CPE HM100"
+filament_type = CPE
first_layer_bed_temperature = 90
first_layer_temperature = 275
max_fan_speed = 50
@@ -1234,6 +1242,7 @@ filament_notes = "List of materials tested with standard PLA print settings:\n\n
inherits = *ABS*
filament_cost = 77.3
filament_density = 1.20
+filament_type = PC
bed_temperature = 115
filament_colour = #3A80CA
first_layer_bed_temperature = 100
@@ -1312,6 +1321,7 @@ first_layer_temperature = 240
temperature = 250
filament_cost = 24.99
filament_density = 1.27
+filament_type = PETG
compatible_printers_condition = nozzle_diameter[0]!=0.6 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Prusa PET 0.6 nozzle]
@@ -1326,6 +1336,7 @@ first_layer_temperature = 240
temperature = 250
filament_cost = 24.99
filament_density = 1.27
+filament_type = PETG
[filament:*PET MMU2*]
inherits = Prusa PET
@@ -1352,12 +1363,13 @@ inherits = *PET MMU2*
[filament:Prusament PETG MMU2]
inherits = *PET MMU2*
+filament_type = PETG
[filament:Prusa PLA]
inherits = *PLA*
filament_cost = 25.4
filament_density = 1.24
-filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFiberlogy PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nAmazonBasics PLA"
[filament:Prusament PLA]
inherits = *PLA*
@@ -1409,7 +1421,7 @@ fan_below_layer_time = 20
filament_colour = #DEE0E6
filament_max_volumetric_speed = 10
filament_soluble = 0
-filament_type = PET
+filament_type = NYLON
first_layer_bed_temperature = 60
first_layer_temperature = 240
max_fan_speed = 5
@@ -1524,7 +1536,7 @@ fan_below_layer_time = 100
filament_colour = #DEE0E6
filament_max_volumetric_speed = 5
filament_notes = "List of materials tested with standard PLA print settings:\n\nEsun PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nEUMAKERS PLA"
-filament_type = PLA
+filament_type = PP
first_layer_bed_temperature = 100
first_layer_temperature = 220
max_fan_speed = 100
@@ -1575,6 +1587,9 @@ layer_height = 0.05
[sla_print:0.1 Fast]
inherits = *common*
layer_height = 0.1
+support_head_front_diameter = 0.5
+support_head_penetration = 0.5
+support_pillar_diameter = 1.3
########### Materials 0.025
@@ -1605,82 +1620,117 @@ initial_layer_height = 0.035
inherits = *common 0.05*
compatible_prints_condition = layer_height == 0.1
exposure_time = 20
-initial_exposure_time = 90
+initial_exposure_time = 45
initial_layer_height = 0.1
########### Materials 0.025
-[sla_material:Bluecast Phrozen Wax 0.025]
+[sla_material:BlueCast Phrozen Wax 0.025]
inherits = *common 0.025*
-exposure_time = 8
+exposure_time = 15
+initial_exposure_time = 50
+
+[sla_material:BlueCast EcoGray 0.025]
+inherits = *common 0.025*
+exposure_time = 6
+initial_exposure_time = 40
+
+[sla_material:BlueCast Keramaster Dental 0.025]
+inherits = *common 0.025*
+exposure_time = 6
initial_exposure_time = 45
+[sla_material:BlueCast X10 0.025]
+inherits = *common 0.025*
+exposure_time = 4
+initial_exposure_time = 100
+
[sla_material:Prusa Orange Tough 0.025]
inherits = *common 0.025*
exposure_time = 6
initial_exposure_time = 30
-########### Materials 0.05
+[sla_material:Prusa Grey Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 7
+initial_exposure_time = 30
-[sla_material:3DM-HTR140 (high temperature) 0.05]
-inherits = *common 0.05*
+[sla_material:Prusa Azure Blue Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 7
+initial_exposure_time = 30
+
+[sla_material:Prusa Maroon Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 6
+initial_exposure_time = 30
+
+[sla_material:Prusa Beige Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 6
+initial_exposure_time = 30
+
+[sla_material:Prusa Pink Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 7
+initial_exposure_time = 30
+
+[sla_material:Prusa White Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 6.5
+initial_exposure_time = 30
+
+[sla_material:Prusa Transparent Tough 0.025]
+inherits = *common 0.025*
+exposure_time = 6
+initial_exposure_time = 15
+
+[sla_material:Prusa Green Casting 0.025]
+inherits = *common 0.025*
exposure_time = 12
-initial_exposure_time = 45
+initial_exposure_time = 35
+
+## [sla_material:Prusa Transparent Green Tough 0.025]
+## inherits = *common 0.025*
+## exposure_time = 5
+## initial_exposure_time = 30
+
+########### Materials 0.05
-[sla_material:Bluecast Ecogray 0.05]
+[sla_material:BlueCast EcoGray 0.05]
inherits = *common 0.05*
-exposure_time = 8
-initial_exposure_time = 45
+exposure_time = 7
+initial_exposure_time = 35
-[sla_material:Bluecast Keramaster 0.05]
+[sla_material:BlueCast Keramaster 0.05]
inherits = *common 0.05*
exposure_time = 8
initial_exposure_time = 45
-[sla_material:Bluecast Keramaster Dental 0.05]
+[sla_material:BlueCast Keramaster Dental 0.05]
inherits = *common 0.05*
exposure_time = 7
-initial_exposure_time = 45
+initial_exposure_time = 50
-[sla_material:Bluecast LCD-DLP Original 0.05]
+[sla_material:BlueCast LCD-DLP Original 0.05]
inherits = *common 0.05*
exposure_time = 10
initial_exposure_time = 60
-[sla_material:Bluecast Phrozen Wax 0.05]
+[sla_material:BlueCast Phrozen Wax 0.05]
inherits = *common 0.05*
-exposure_time = 10
-initial_exposure_time = 55
+exposure_time = 16
+initial_exposure_time = 50
-[sla_material:Bluecast S+ 0.05]
+[sla_material:BlueCast S+ 0.05]
inherits = *common 0.05*
exposure_time = 9
initial_exposure_time = 45
-[sla_material:Bluecast X2 0.05]
-inherits = *common 0.05*
-exposure_time = 10
-initial_exposure_time = 60
-
-[sla_material:Prusa Skin Tough 0.05]
+[sla_material:BlueCast X10 0.05]
inherits = *common 0.05*
exposure_time = 6
-initial_exposure_time = 30
-
-[sla_material:Prusa Orange Tough 0.05]
-inherits = *common 0.05*
-exposure_time = 7.5
-initial_exposure_time = 30
-
-[sla_material:Prusa Grey Tough 0.05]
-inherits = *common 0.05*
-exposure_time = 8.5
-initial_exposure_time = 30
-
-[sla_material:Prusa Black Tough 0.05]
-inherits = *common 0.05*
-exposure_time = 6
-initial_exposure_time = 30
+initial_exposure_time = 100
[sla_material:Monocure 3D Black Rapid Resin 0.05]
inherits = *common 0.05*
@@ -1697,20 +1747,30 @@ inherits = *common 0.05*
exposure_time = 8
initial_exposure_time = 40
-[sla_material:Monocure 3D Gray Rapid Resin 0.05]
+[sla_material:Monocure 3D Grey Rapid Resin 0.05]
inherits = *common 0.05*
-exposure_time = 7
-initial_exposure_time = 40
+exposure_time = 10
+initial_exposure_time = 30
[sla_material:Monocure 3D White Rapid Resin 0.05]
inherits = *common 0.05*
exposure_time = 7
initial_exposure_time = 40
+[sla_material:3DM-HTR140 (high temperature) 0.05]
+inherits = *common 0.05*
+exposure_time = 12
+initial_exposure_time = 45
+
[sla_material:3DM-ABS 0.05]
inherits = *common 0.05*
-exposure_time = 9
-initial_exposure_time = 35
+exposure_time = 13
+initial_exposure_time = 25
+
+[sla_material:3DM-BLACK 0.05]
+inherits = *common 0.05*
+exposure_time = 20
+initial_exposure_time = 40
[sla_material:3DM-DENT 0.05]
inherits = *common 0.05*
@@ -1737,7 +1797,39 @@ inherits = *common 0.05*
exposure_time = 9
initial_exposure_time = 40
-## [sla_material:Prusa Skin Super Low Odor 0.05]
+[sla_material:Harz Labs Model Resin Cherry 0.05]
+inherits = *common 0.05*
+exposure_time = 8
+initial_exposure_time = 45
+
+[sla_material:Photocentric Hard Grey 0.05]
+inherits = *common 0.05*
+exposure_time = 15
+initial_exposure_time = 30
+
+## Prusa
+
+[sla_material:Prusa Beige Tough 0.05]
+inherits = *common 0.05*
+exposure_time = 7
+initial_exposure_time = 30
+
+[sla_material:Prusa Orange Tough 0.05]
+inherits = *common 0.05*
+exposure_time = 7.5
+initial_exposure_time = 30
+
+[sla_material:Prusa Grey Tough 0.05]
+inherits = *common 0.05*
+exposure_time = 8.5
+initial_exposure_time = 30
+
+[sla_material:Prusa Black Tough 0.05]
+inherits = *common 0.05*
+exposure_time = 6
+initial_exposure_time = 30
+
+## [sla_material:Prusa Beige Super Low Odor 0.05]
## inherits = *common 0.05*
## exposure_time = 7.5
## initial_exposure_time = 30
@@ -1752,11 +1844,6 @@ initial_exposure_time = 40
## exposure_time = 6.5
## initial_exposure_time = 30
-[sla_material:Harz Labs Model Resin Cherry 0.05]
-inherits = *common 0.05*
-exposure_time = 8
-initial_exposure_time = 45
-
## [sla_material:Prusa Black High Tenacity 0.05]
## inherits = *common 0.05*
## exposure_time = 7
@@ -1765,7 +1852,7 @@ initial_exposure_time = 45
[sla_material:Prusa Green Casting 0.05]
inherits = *common 0.05*
exposure_time = 13
-initial_exposure_time = 30
+initial_exposure_time = 40
## [sla_material:Prusa Yellow Solid 0.05]
## inherits = *common 0.05*
@@ -1774,10 +1861,10 @@ initial_exposure_time = 30
[sla_material:Prusa White Tough 0.05]
inherits = *common 0.05*
-exposure_time = 7
+exposure_time = 7.5
initial_exposure_time = 30
-## [sla_material:Prusa Green Transparent 0.05]
+## [sla_material:Prusa Transparent Green Tough 0.05]
## inherits = *common 0.05*
## exposure_time = 6
## initial_exposure_time = 30
@@ -1789,12 +1876,12 @@ initial_exposure_time = 30
[sla_material:Prusa Maroon Tough 0.05]
inherits = *common 0.05*
-exposure_time = 9
+exposure_time = 7.5
initial_exposure_time = 30
[sla_material:Prusa Pink Tough 0.05]
inherits = *common 0.05*
-exposure_time = 7
+exposure_time = 8
initial_exposure_time = 30
[sla_material:Prusa Azure Blue Tough 0.05]
@@ -1802,6 +1889,11 @@ inherits = *common 0.05*
exposure_time = 8
initial_exposure_time = 30
+[sla_material:Prusa Transparent Tough 0.05]
+inherits = *common 0.05*
+exposure_time = 7
+initial_exposure_time = 15
+
## [sla_material:Prusa Yellow Flexible 0.05]
## inherits = *common 0.05*
## exposure_time = 9
@@ -1809,8 +1901,8 @@ initial_exposure_time = 30
## [sla_material:Prusa Clear Flexible 0.05]
## inherits = *common 0.05*
-## exposure_time = 9
-## initial_exposure_time = 30
+## exposure_time = 5
+## initial_exposure_time = 15
## [sla_material:Prusa White Flexible 0.05]
## inherits = *common 0.05*
@@ -1843,9 +1935,49 @@ initial_exposure_time = 30
[sla_material:Prusa Orange Tough 0.1]
inherits = *common 0.1*
-exposure_time = 10
+exposure_time = 13
+initial_exposure_time = 45
+
+[sla_material:Prusa Beige Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+
+[sla_material:Prusa Pink Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+
+[sla_material:Prusa Azure Blue Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+
+[sla_material:Prusa Maroon Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+
+[sla_material:Prusa White Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+
+[sla_material:Prusa Black Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 55
+
+[sla_material:Prusa Transparent Tough 0.1]
+inherits = *common 0.1*
+exposure_time = 8
initial_exposure_time = 30
+[sla_material:Prusa Green Casting 0.1]
+inherits = *common 0.1*
+exposure_time = 15
+initial_exposure_time = 50
+
[printer:*common*]
printer_technology = FFF
bed_shape = 0x0,250x0,250x210,0x210
@@ -1897,7 +2029,7 @@ retract_speed = 35
serial_port =
serial_speed = 250000
single_extruder_multi_material = 0
-start_gcode = M115 U3.1.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.2.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
toolchange_gcode =
use_firmware_retraction = 0
use_relative_e_distances = 1
@@ -1934,7 +2066,7 @@ printer_model = MK2SMM
inherits = *multimaterial*
end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
-start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG92 E0.0
+start_gcode = M115 U3.2.3 ; tell printer latest fw version\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG92 E0.0
default_print_profile = 0.15mm OPTIMAL
[printer:*mm-multi*]
@@ -1944,7 +2076,7 @@ end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes.
extruder_colour = #FFAA55;#E37BA0;#4ECDD3;#FB7259
nozzle_diameter = 0.4,0.4,0.4,0.4
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
-start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_single_extruder_multi_material_priming}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\n{endif}\nG92 E0.0
+start_gcode = M115 U3.2.3 ; tell printer latest fw version\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_single_extruder_multi_material_priming}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\n{endif}\nG92 E0.0
default_print_profile = 0.15mm OPTIMAL
# XXXXXXXXXXXXXXXXX
@@ -2012,19 +2144,19 @@ min_layer_height = 0.1
inherits = Original Prusa i3 MK2S
printer_model = MK2.5
remaining_times = 1
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
[printer:Original Prusa i3 MK2.5 0.25 nozzle]
inherits = Original Prusa i3 MK2S 0.25 nozzle
printer_model = MK2.5
remaining_times = 1
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
[printer:Original Prusa i3 MK2.5 0.6 nozzle]
inherits = Original Prusa i3 MK2S 0.6 nozzle
printer_model = MK2.5
remaining_times = 1
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
[printer:Original Prusa i3 MK2.5 MMU2 Single]
inherits = Original Prusa i3 MK2.5; *mm2*
@@ -2053,7 +2185,7 @@ machine_min_travel_rate = 0
default_print_profile = 0.15mm OPTIMAL MK2.5
default_filament_profile = Prusament PLA
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2.5\n
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; load to nozzle\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; load to nozzle\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n
end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors
[printer:Original Prusa i3 MK2.5 MMU2 Single 0.6 nozzle]
@@ -2095,23 +2227,23 @@ single_extruder_multi_material = 1
# to be defined explicitely.
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n
[printer:Original Prusa i3 MK2.5S]
inherits = Original Prusa i3 MK2.5
printer_model = MK2.5S
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
[printer:Original Prusa i3 MK2.5S 0.25 nozzle]
inherits = Original Prusa i3 MK2.5 0.25 nozzle
printer_model = MK2.5S
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
[printer:Original Prusa i3 MK2.5S 0.6 nozzle]
inherits = Original Prusa i3 MK2.5 0.6 nozzle
printer_model = MK2.5S
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
[printer:Original Prusa i3 MK2.5S MMU2S Single]
inherits = Original Prusa i3 MK2.5; *mm2s*
@@ -2140,7 +2272,7 @@ machine_min_travel_rate = 0
default_print_profile = 0.15mm OPTIMAL MK2.5
default_filament_profile = Prusament PLA
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2.5\n
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n
end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors
[printer:Original Prusa i3 MK2.5S MMU2S Single 0.6 nozzle]
@@ -2160,7 +2292,7 @@ min_layer_height = 0.05
nozzle_diameter = 0.25
printer_variant = 0.25
default_print_profile = 0.10mm DETAIL 0.25 nozzle
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n
[printer:Original Prusa i3 MK2.5S MMU2S]
inherits = Original Prusa i3 MK2.5; *mm2s*
@@ -2193,7 +2325,7 @@ single_extruder_multi_material = 1
# to be defined explicitely.
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n
@@ -2225,7 +2357,7 @@ remaining_times = 1
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
retract_lift_below = 209
max_print_height = 210
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
printer_model = MK3
default_print_profile = 0.15mm QUALITY MK3
@@ -2235,7 +2367,7 @@ nozzle_diameter = 0.25
max_layer_height = 0.15
min_layer_height = 0.05
printer_variant = 0.25
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3
[printer:Original Prusa i3 MK3 0.6 nozzle]
@@ -2249,17 +2381,17 @@ default_print_profile = 0.30mm QUALITY 0.6 nozzle MK3
[printer:Original Prusa i3 MK3S]
inherits = Original Prusa i3 MK3
printer_model = MK3S
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
[printer:Original Prusa i3 MK3S 0.25 nozzle]
inherits = Original Prusa i3 MK3 0.25 nozzle
printer_model = MK3S
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
[printer:Original Prusa i3 MK3S 0.6 nozzle]
inherits = Original Prusa i3 MK3 0.6 nozzle
printer_model = MK3S
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
[printer:*mm2*]
inherits = Original Prusa i3 MK3
@@ -2289,7 +2421,7 @@ default_filament_profile = Prusament PLA MMU2
inherits = *mm2*
single_extruder_multi_material = 0
default_filament_profile = Prusament PLA
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors
[printer:Original Prusa i3 MK3 MMU2 Single 0.6 nozzle]
@@ -2308,7 +2440,7 @@ nozzle_diameter = 0.25
max_layer_height = 0.15
min_layer_height = 0.05
printer_variant = 0.25
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F1000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F1000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3
[printer:Original Prusa i3 MK3 MMU2]
@@ -2319,14 +2451,14 @@ inherits = *mm2*
machine_max_acceleration_e = 8000,8000
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n
[printer:Original Prusa i3 MK3S MMU2S Single]
inherits = *mm2s*
single_extruder_multi_material = 0
default_filament_profile = Prusament PLA
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors
[printer:Original Prusa i3 MK3S MMU2S Single 0.6 nozzle]
@@ -2345,7 +2477,7 @@ nozzle_diameter = 0.25
max_layer_height = 0.15
min_layer_height = 0.05
printer_variant = 0.25
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3
[printer:Original Prusa i3 MK3S MMU2S]
@@ -2353,7 +2485,7 @@ inherits = *mm2s*
machine_max_acceleration_e = 8000,8000
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F
-start_gcode = M115 U3.7.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
+start_gcode = M115 U3.7.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n
end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n
# 0.6 nozzle MMU printer profile - only for single mode for now
diff --git a/src/boost/nowide/utf8_codecvt.hpp b/src/boost/nowide/utf8_codecvt.hpp
index cc5046fc8..877c9f0e0 100644
--- a/src/boost/nowide/utf8_codecvt.hpp
+++ b/src/boost/nowide/utf8_codecvt.hpp
@@ -102,7 +102,7 @@ protected:
#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
return from - save_from;
#else
- return save_max - max;
+ return int(save_max - max);
#endif
}
diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp
index 9d0649a1f..577698071 100644
--- a/src/libslic3r/Config.cpp
+++ b/src/libslic3r/Config.cpp
@@ -211,25 +211,35 @@ std::vector<std::string> ConfigOptionDef::cli_args(const std::string &key) const
ConfigOption* ConfigOptionDef::create_empty_option() const
{
- switch (this->type) {
- case coFloat: return new ConfigOptionFloat();
- case coFloats: return new ConfigOptionFloats();
- case coInt: return new ConfigOptionInt();
- case coInts: return new ConfigOptionInts();
- case coString: return new ConfigOptionString();
- case coStrings: return new ConfigOptionStrings();
- case coPercent: return new ConfigOptionPercent();
- case coPercents: return new ConfigOptionPercents();
- case coFloatOrPercent: return new ConfigOptionFloatOrPercent();
- case coPoint: return new ConfigOptionPoint();
- case coPoints: return new ConfigOptionPoints();
- case coPoint3: return new ConfigOptionPoint3();
-// case coPoint3s: return new ConfigOptionPoint3s();
- case coBool: return new ConfigOptionBool();
- case coBools: return new ConfigOptionBools();
- case coEnum: return new ConfigOptionEnumGeneric(this->enum_keys_map);
- default: throw std::runtime_error(std::string("Unknown option type for option ") + this->label);
- }
+ if (this->nullable) {
+ switch (this->type) {
+ case coFloats: return new ConfigOptionFloatsNullable();
+ case coInts: return new ConfigOptionIntsNullable();
+ case coPercents: return new ConfigOptionPercentsNullable();
+ case coBools: return new ConfigOptionBoolsNullable();
+ default: throw std::runtime_error(std::string("Unknown option type for nullable option ") + this->label);
+ }
+ } else {
+ switch (this->type) {
+ case coFloat: return new ConfigOptionFloat();
+ case coFloats: return new ConfigOptionFloats();
+ case coInt: return new ConfigOptionInt();
+ case coInts: return new ConfigOptionInts();
+ case coString: return new ConfigOptionString();
+ case coStrings: return new ConfigOptionStrings();
+ case coPercent: return new ConfigOptionPercent();
+ case coPercents: return new ConfigOptionPercents();
+ case coFloatOrPercent: return new ConfigOptionFloatOrPercent();
+ case coPoint: return new ConfigOptionPoint();
+ case coPoints: return new ConfigOptionPoints();
+ case coPoint3: return new ConfigOptionPoint3();
+ // case coPoint3s: return new ConfigOptionPoint3s();
+ case coBool: return new ConfigOptionBool();
+ case coBools: return new ConfigOptionBools();
+ case coEnum: return new ConfigOptionEnumGeneric(this->enum_keys_map);
+ default: throw std::runtime_error(std::string("Unknown option type for option ") + this->label);
+ }
+ }
}
ConfigOption* ConfigOptionDef::create_default_option() const
@@ -254,6 +264,13 @@ ConfigOptionDef* ConfigDef::add(const t_config_option_key &opt_key, ConfigOption
return opt;
}
+ConfigOptionDef* ConfigDef::add_nullable(const t_config_option_key &opt_key, ConfigOptionType type)
+{
+ ConfigOptionDef *def = this->add(opt_key, type);
+ def->nullable = true;
+ return def;
+}
+
std::string ConfigOptionDef::nocli = "~~~noCLI";
std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, std::function<bool(const ConfigOptionDef &)> filter) const
@@ -642,6 +659,17 @@ void ConfigBase::save(const std::string &file) const
c.close();
}
+// Set all the nullable values to nils.
+void ConfigBase::null_nullables()
+{
+ for (const std::string &opt_key : this->keys()) {
+ ConfigOption *opt = this->optptr(opt_key, false);
+ assert(opt != nullptr);
+ if (opt->nullable())
+ opt->deserialize("nil");
+ }
+}
+
bool DynamicConfig::operator==(const DynamicConfig &rhs) const
{
auto it1 = this->options.begin();
@@ -655,6 +683,19 @@ bool DynamicConfig::operator==(const DynamicConfig &rhs) const
return it1 == it1_end && it2 == it2_end;
}
+// Remove options with all nil values, those are optional and it does not help to hold them.
+size_t DynamicConfig::remove_nil_options()
+{
+ size_t cnt_removed = 0;
+ for (auto it = options.begin(); it != options.end();)
+ if (it->second->is_nil()) {
+ it = options.erase(it);
+ ++ cnt_removed;
+ } else
+ ++ it;
+ return cnt_removed;
+}
+
ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool create)
{
auto it = options.find(opt_key);
@@ -838,18 +879,22 @@ CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionVector<Slic3r::Vec2d>)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionVector<unsigned char>)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionFloat)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionFloats)
+CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionFloatsNullable)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionInt)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionInts)
+CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionIntsNullable)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionString)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionStrings)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionPercent)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionPercents)
+CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionPercentsNullable)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionFloatOrPercent)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionPoint)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionPoints)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionPoint3)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionBool)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionBools)
+CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionBoolsNullable)
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionEnumGeneric)
CEREAL_REGISTER_TYPE(Slic3r::ConfigBase)
CEREAL_REGISTER_TYPE(Slic3r::DynamicConfig)
@@ -868,17 +913,21 @@ CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVectorBase, Slic3r::Con
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVectorBase, Slic3r::ConfigOptionVector<unsigned char>)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<double>, Slic3r::ConfigOptionFloat)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<double>, Slic3r::ConfigOptionFloats)
+CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<double>, Slic3r::ConfigOptionFloatsNullable)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<int>, Slic3r::ConfigOptionInt)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<int>, Slic3r::ConfigOptionInts)
+CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<int>, Slic3r::ConfigOptionIntsNullable)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<std::string>, Slic3r::ConfigOptionString)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<std::string>, Slic3r::ConfigOptionStrings)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionFloat, Slic3r::ConfigOptionPercent)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionFloats, Slic3r::ConfigOptionPercents)
+CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionFloats, Slic3r::ConfigOptionPercentsNullable)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionPercent, Slic3r::ConfigOptionFloatOrPercent)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<Slic3r::Vec2d>, Slic3r::ConfigOptionPoint)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<Slic3r::Vec2d>, Slic3r::ConfigOptionPoints)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<Slic3r::Vec3d>, Slic3r::ConfigOptionPoint3)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<bool>, Slic3r::ConfigOptionBool)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<unsigned char>, Slic3r::ConfigOptionBools)
+CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<unsigned char>, Slic3r::ConfigOptionBoolsNullable)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionInt, Slic3r::ConfigOptionEnumGeneric)
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigBase, Slic3r::DynamicConfig)
diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp
index 7d96f6cf3..2850f1cb9 100644
--- a/src/libslic3r/Config.hpp
+++ b/src/libslic3r/Config.hpp
@@ -15,6 +15,7 @@
#include "clonable_ptr.hpp"
#include "Point.hpp"
+#include <boost/algorithm/string/trim.hpp>
#include <boost/format.hpp>
#include <boost/property_tree/ptree.hpp>
@@ -124,6 +125,23 @@ public:
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
bool is_vector() const { return ! this->is_scalar(); }
+ // If this option is nullable, then it may have its value or values set to nil.
+ virtual bool nullable() const { return false; }
+ // A scalar is nil, or all values of a vector are nil.
+ virtual bool is_nil() const { return false; }
+ // Is this option overridden by another option?
+ // An option overrides another option if it is not nil and not equal.
+ virtual bool overriden_by(const ConfigOption *rhs) const {
+ assert(! this->nullable() && ! rhs->nullable());
+ return *this != *rhs;
+ }
+ // Apply an override option, possibly a nullable one.
+ virtual bool apply_override(const ConfigOption *rhs) {
+ if (*this == *rhs)
+ return false;
+ *this = *rhs;
+ return true;
+ }
};
typedef ConfigOption* ConfigOptionPtr;
@@ -183,6 +201,8 @@ public:
virtual size_t size() const = 0;
// Is this vector empty?
virtual bool empty() const = 0;
+ // Is the value nil? That should only be possible if this->nullable().
+ virtual bool is_nil(size_t idx) const = 0;
protected:
// Used to verify type compatibility when assigning to / from a scalar ConfigOption.
@@ -302,6 +322,62 @@ public:
bool operator==(const std::vector<T> &rhs) const { return this->values == rhs; }
bool operator!=(const std::vector<T> &rhs) const { return this->values != rhs; }
+ // Is this option overridden by another option?
+ // An option overrides another option if it is not nil and not equal.
+ bool overriden_by(const ConfigOption *rhs) const override {
+ if (this->nullable())
+ throw std::runtime_error("Cannot override a nullable ConfigOption.");
+ if (rhs->type() != this->type())
+ throw std::runtime_error("ConfigOptionVector.overriden_by() applied to different types.");
+ auto rhs_vec = static_cast<const ConfigOptionVector<T>*>(rhs);
+ if (! rhs->nullable())
+ // Overridding a non-nullable object with another non-nullable object.
+ return this->values != rhs_vec->values;
+ size_t i = 0;
+ size_t cnt = std::min(this->size(), rhs_vec->size());
+ for (; i < cnt; ++ i)
+ if (! rhs_vec->is_nil(i) && this->values[i] != rhs_vec->values[i])
+ return true;
+ for (; i < rhs_vec->size(); ++ i)
+ if (! rhs_vec->is_nil(i))
+ return true;
+ return false;
+ }
+ // Apply an override option, possibly a nullable one.
+ bool apply_override(const ConfigOption *rhs) override {
+ if (this->nullable())
+ throw std::runtime_error("Cannot override a nullable ConfigOption.");
+ if (rhs->type() != this->type())
+ throw std::runtime_error("ConfigOptionVector.apply_override() applied to different types.");
+ auto rhs_vec = static_cast<const ConfigOptionVector<T>*>(rhs);
+ if (! rhs->nullable()) {
+ // Overridding a non-nullable object with another non-nullable object.
+ if (this->values != rhs_vec->values) {
+ this->values = rhs_vec->values;
+ return true;
+ }
+ return false;
+ }
+ size_t i = 0;
+ size_t cnt = std::min(this->size(), rhs_vec->size());
+ bool modified = false;
+ for (; i < cnt; ++ i)
+ if (! rhs_vec->is_nil(i) && this->values[i] != rhs_vec->values[i]) {
+ this->values[i] = rhs_vec->values[i];
+ modified = true;
+ }
+ for (; i < rhs_vec->size(); ++ i)
+ if (! rhs_vec->is_nil(i)) {
+ if (this->values.empty())
+ this->values.resize(i + 1);
+ else
+ this->values.resize(i + 1, this->values.front());
+ this->values[i] = rhs_vec->values[i];
+ modified = true;
+ }
+ return false;
+ }
+
private:
friend class cereal::access;
template<class Archive> void serialize(Archive & ar) { ar(this->values); }
@@ -345,26 +421,41 @@ private:
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<double>>(this)); }
};
-class ConfigOptionFloats : public ConfigOptionVector<double>
+template<bool NULLABLE>
+class ConfigOptionFloatsTempl : public ConfigOptionVector<double>
{
public:
- ConfigOptionFloats() : ConfigOptionVector<double>() {}
- explicit ConfigOptionFloats(size_t n, double value) : ConfigOptionVector<double>(n, value) {}
- explicit ConfigOptionFloats(std::initializer_list<double> il) : ConfigOptionVector<double>(std::move(il)) {}
- explicit ConfigOptionFloats(const std::vector<double> &vec) : ConfigOptionVector<double>(vec) {}
- explicit ConfigOptionFloats(std::vector<double> &&vec) : ConfigOptionVector<double>(std::move(vec)) {}
+ ConfigOptionFloatsTempl() : ConfigOptionVector<double>() {}
+ explicit ConfigOptionFloatsTempl(size_t n, double value) : ConfigOptionVector<double>(n, value) {}
+ explicit ConfigOptionFloatsTempl(std::initializer_list<double> il) : ConfigOptionVector<double>(std::move(il)) {}
+ explicit ConfigOptionFloatsTempl(const std::vector<double> &vec) : ConfigOptionVector<double>(vec) {}
+ explicit ConfigOptionFloatsTempl(std::vector<double> &&vec) : ConfigOptionVector<double>(std::move(vec)) {}
static ConfigOptionType static_type() { return coFloats; }
ConfigOptionType type() const override { return static_type(); }
- ConfigOption* clone() const override { return new ConfigOptionFloats(*this); }
- bool operator==(const ConfigOptionFloats &rhs) const { return this->values == rhs.values; }
+ ConfigOption* clone() const override { return new ConfigOptionFloatsTempl(*this); }
+ bool operator==(const ConfigOptionFloatsTempl &rhs) const { return vectors_equal(this->values, rhs.values); }
+ bool operator==(const ConfigOption &rhs) const override {
+ if (rhs.type() != this->type())
+ throw std::runtime_error("ConfigOptionFloatsTempl: Comparing incompatible types");
+ assert(dynamic_cast<const ConfigOptionVector<double>*>(&rhs));
+ return vectors_equal(this->values, static_cast<const ConfigOptionVector<double>*>(&rhs)->values);
+ }
+ // Could a special "nil" value be stored inside the vector, indicating undefined value?
+ bool nullable() const override { return NULLABLE; }
+ // Special "nil" value to be stored into the vector if this->supports_nil().
+ static double nil_value() { return std::numeric_limits<double>::quiet_NaN(); }
+ // A scalar is nil, or all values of a vector are nil.
+ bool is_nil() const override { for (auto v : this->values) if (! std::isnan(v)) return false; return true; }
+ bool is_nil(size_t idx) const override { return std::isnan(this->values[idx]); }
std::string serialize() const override
{
std::ostringstream ss;
- for (std::vector<double>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
- if (it - this->values.begin() != 0) ss << ",";
- ss << *it;
+ for (const double &v : this->values) {
+ if (&v != &this->values.front())
+ ss << ",";
+ serialize_single_value(ss, v);
}
return ss.str();
}
@@ -373,14 +464,14 @@ public:
{
std::vector<std::string> vv;
vv.reserve(this->values.size());
- for (std::vector<double>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
+ for (const double v : this->values) {
std::ostringstream ss;
- ss << *it;
+ serialize_single_value(ss, v);
vv.push_back(ss.str());
}
return vv;
}
-
+
bool deserialize(const std::string &str, bool append = false) override
{
if (! append)
@@ -388,25 +479,61 @@ public:
std::istringstream is(str);
std::string item_str;
while (std::getline(is, item_str, ',')) {
- std::istringstream iss(item_str);
- double value;
- iss >> value;
- this->values.push_back(value);
+ boost::trim(item_str);
+ if (item_str == "nil") {
+ if (NULLABLE)
+ this->values.push_back(nil_value());
+ else
+ std::runtime_error("Deserializing nil into a non-nullable object");
+ } else {
+ std::istringstream iss(item_str);
+ double value;
+ iss >> value;
+ this->values.push_back(value);
+ }
}
return true;
}
- ConfigOptionFloats& operator=(const ConfigOption *opt)
+ ConfigOptionFloatsTempl& operator=(const ConfigOption *opt)
{
this->set(opt);
return *this;
}
+protected:
+ void serialize_single_value(std::ostringstream &ss, const double v) const {
+ if (std::isfinite(v))
+ ss << v;
+ else if (std::isnan(v)) {
+ if (NULLABLE)
+ ss << "nil";
+ else
+ std::runtime_error("Serializing NaN");
+ } else
+ std::runtime_error("Serializing invalid number");
+ }
+ static bool vectors_equal(const std::vector<double> &v1, const std::vector<double> &v2) {
+ if (NULLABLE) {
+ if (v1.size() != v2.size())
+ return false;
+ for (auto it1 = v1.begin(), it2 = v2.begin(); it1 != v1.end(); ++ it1, ++ it2)
+ if (! ((std::isnan(*it1) && std::isnan(*it2)) || *it1 == *it2))
+ return false;
+ return true;
+ } else
+ // Not supporting nullable values, the default vector compare is cheaper.
+ return v1 == v2;
+ }
+
private:
friend class cereal::access;
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionVector<double>>(this)); }
};
+using ConfigOptionFloats = ConfigOptionFloatsTempl<false>;
+using ConfigOptionFloatsNullable = ConfigOptionFloatsTempl<true>;
+
class ConfigOptionInt : public ConfigOptionSingle<int>
{
public:
@@ -447,35 +574,45 @@ private:
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<int>>(this)); }
};
-class ConfigOptionInts : public ConfigOptionVector<int>
+template<bool NULLABLE>
+class ConfigOptionIntsTempl : public ConfigOptionVector<int>
{
public:
- ConfigOptionInts() : ConfigOptionVector<int>() {}
- explicit ConfigOptionInts(size_t n, int value) : ConfigOptionVector<int>(n, value) {}
- explicit ConfigOptionInts(std::initializer_list<int> il) : ConfigOptionVector<int>(std::move(il)) {}
+ ConfigOptionIntsTempl() : ConfigOptionVector<int>() {}
+ explicit ConfigOptionIntsTempl(size_t n, int value) : ConfigOptionVector<int>(n, value) {}
+ explicit ConfigOptionIntsTempl(std::initializer_list<int> il) : ConfigOptionVector<int>(std::move(il)) {}
static ConfigOptionType static_type() { return coInts; }
ConfigOptionType type() const override { return static_type(); }
- ConfigOption* clone() const override { return new ConfigOptionInts(*this); }
- ConfigOptionInts& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
- bool operator==(const ConfigOptionInts &rhs) const { return this->values == rhs.values; }
+ ConfigOption* clone() const override { return new ConfigOptionIntsTempl(*this); }
+ ConfigOptionIntsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
+ bool operator==(const ConfigOptionIntsTempl &rhs) const { return this->values == rhs.values; }
+ // Could a special "nil" value be stored inside the vector, indicating undefined value?
+ bool nullable() const override { return NULLABLE; }
+ // Special "nil" value to be stored into the vector if this->supports_nil().
+ static int nil_value() { return std::numeric_limits<int>::max(); }
+ // A scalar is nil, or all values of a vector are nil.
+ bool is_nil() const override { for (auto v : this->values) if (v != nil_value()) return false; return true; }
+ bool is_nil(size_t idx) const override { return this->values[idx] == nil_value(); }
- std::string serialize() const override {
+ std::string serialize() const override
+ {
std::ostringstream ss;
- for (std::vector<int>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
- if (it - this->values.begin() != 0) ss << ",";
- ss << *it;
+ for (const int &v : this->values) {
+ if (&v != &this->values.front())
+ ss << ",";
+ serialize_single_value(ss, v);
}
return ss.str();
}
- std::vector<std::string> vserialize() const override
+ std::vector<std::string> vserialize() const override
{
std::vector<std::string> vv;
vv.reserve(this->values.size());
- for (std::vector<int>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
+ for (const int v : this->values) {
std::ostringstream ss;
- ss << *it;
+ serialize_single_value(ss, v);
vv.push_back(ss.str());
}
return vv;
@@ -488,19 +625,40 @@ public:
std::istringstream is(str);
std::string item_str;
while (std::getline(is, item_str, ',')) {
- std::istringstream iss(item_str);
- int value;
- iss >> value;
- this->values.push_back(value);
+ boost::trim(item_str);
+ if (item_str == "nil") {
+ if (NULLABLE)
+ this->values.push_back(nil_value());
+ else
+ std::runtime_error("Deserializing nil into a non-nullable object");
+ } else {
+ std::istringstream iss(item_str);
+ int value;
+ iss >> value;
+ this->values.push_back(value);
+ }
}
return true;
}
private:
+ void serialize_single_value(std::ostringstream &ss, const int v) const {
+ if (v == nil_value()) {
+ if (NULLABLE)
+ ss << "nil";
+ else
+ std::runtime_error("Serializing NaN");
+ } else
+ ss << v;
+ }
+
friend class cereal::access;
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionVector<int>>(this)); }
};
+using ConfigOptionInts = ConfigOptionIntsTempl<false>;
+using ConfigOptionIntsNullable = ConfigOptionIntsTempl<true>;
+
class ConfigOptionString : public ConfigOptionSingle<std::string>
{
public:
@@ -544,6 +702,7 @@ public:
ConfigOption* clone() const override { return new ConfigOptionStrings(*this); }
ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
bool operator==(const ConfigOptionStrings &rhs) const { return this->values == rhs.values; }
+ bool is_nil(size_t idx) const override { return false; }
std::string serialize() const override
{
@@ -603,64 +762,61 @@ private:
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionFloat>(this)); }
};
-class ConfigOptionPercents : public ConfigOptionFloats
+template<bool NULLABLE>
+class ConfigOptionPercentsTempl : public ConfigOptionFloatsTempl<NULLABLE>
{
public:
- ConfigOptionPercents() : ConfigOptionFloats() {}
- explicit ConfigOptionPercents(size_t n, double value) : ConfigOptionFloats(n, value) {}
- explicit ConfigOptionPercents(std::initializer_list<double> il) : ConfigOptionFloats(std::move(il)) {}
+ ConfigOptionPercentsTempl() : ConfigOptionFloatsTempl<NULLABLE>() {}
+ explicit ConfigOptionPercentsTempl(size_t n, double value) : ConfigOptionFloatsTempl<NULLABLE>(n, value) {}
+ explicit ConfigOptionPercentsTempl(std::initializer_list<double> il) : ConfigOptionFloatsTempl<NULLABLE>(std::move(il)) {}
+ explicit ConfigOptionPercentsTempl(const std::vector<double>& vec) : ConfigOptionFloatsTempl<NULLABLE>(vec) {}
+ explicit ConfigOptionPercentsTempl(std::vector<double>&& vec) : ConfigOptionFloatsTempl<NULLABLE>(std::move(vec)) {}
static ConfigOptionType static_type() { return coPercents; }
ConfigOptionType type() const override { return static_type(); }
- ConfigOption* clone() const override { return new ConfigOptionPercents(*this); }
- ConfigOptionPercents& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
- bool operator==(const ConfigOptionPercents &rhs) const { return this->values == rhs.values; }
+ ConfigOption* clone() const override { return new ConfigOptionPercentsTempl(*this); }
+ ConfigOptionPercentsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
+ bool operator==(const ConfigOptionPercentsTempl &rhs) const { return this->values == rhs.values; }
std::string serialize() const override
{
std::ostringstream ss;
- for (const auto &v : this->values) {
- if (&v != &this->values.front()) ss << ",";
- ss << v << "%";
+ for (const double &v : this->values) {
+ if (&v != &this->values.front())
+ ss << ",";
+ this->serialize_single_value(ss, v);
+ if (! std::isnan(v))
+ ss << "%";
}
std::string str = ss.str();
return str;
}
-
+
std::vector<std::string> vserialize() const override
{
std::vector<std::string> vv;
vv.reserve(this->values.size());
- for (const auto v : this->values) {
+ for (const double v : this->values) {
std::ostringstream ss;
- ss << v;
- std::string sout = ss.str() + "%";
- vv.push_back(sout);
+ this->serialize_single_value(ss, v);
+ if (! std::isnan(v))
+ ss << "%";
+ vv.push_back(ss.str());
}
return vv;
}
- bool deserialize(const std::string &str, bool append = false) override
- {
- if (! append)
- this->values.clear();
- std::istringstream is(str);
- std::string item_str;
- while (std::getline(is, item_str, ',')) {
- std::istringstream iss(item_str);
- double value;
- // don't try to parse the trailing % since it's optional
- iss >> value;
- this->values.push_back(value);
- }
- return true;
- }
+ // The float's deserialize function shall ignore the trailing optional %.
+ // bool deserialize(const std::string &str, bool append = false) override;
private:
friend class cereal::access;
- template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionFloats>(this)); }
+ template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionFloatsTempl<NULLABLE>>(this)); }
};
+using ConfigOptionPercents = ConfigOptionPercentsTempl<false>;
+using ConfigOptionPercentsNullable = ConfigOptionPercentsTempl<true>;
+
class ConfigOptionFloatOrPercent : public ConfigOptionPercent
{
public:
@@ -761,6 +917,7 @@ public:
ConfigOption* clone() const override { return new ConfigOptionPoints(*this); }
ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
bool operator==(const ConfigOptionPoints &rhs) const { return this->values == rhs.values; }
+ bool is_nil(size_t idx) const override { return false; }
std::string serialize() const override
{
@@ -887,18 +1044,29 @@ private:
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<bool>>(this)); }
};
-class ConfigOptionBools : public ConfigOptionVector<unsigned char>
+template<bool NULLABLE>
+class ConfigOptionBoolsTempl : public ConfigOptionVector<unsigned char>
{
public:
- ConfigOptionBools() : ConfigOptionVector<unsigned char>() {}
- explicit ConfigOptionBools(size_t n, bool value) : ConfigOptionVector<unsigned char>(n, (unsigned char)value) {}
- explicit ConfigOptionBools(std::initializer_list<bool> il) { values.reserve(il.size()); for (bool b : il) values.emplace_back((unsigned char)b); }
+ ConfigOptionBoolsTempl() : ConfigOptionVector<unsigned char>() {}
+ explicit ConfigOptionBoolsTempl(size_t n, bool value) : ConfigOptionVector<unsigned char>(n, (unsigned char)value) {}
+ explicit ConfigOptionBoolsTempl(std::initializer_list<bool> il) { values.reserve(il.size()); for (bool b : il) values.emplace_back((unsigned char)b); }
+ explicit ConfigOptionBoolsTempl(std::initializer_list<unsigned char> il) { values.reserve(il.size()); for (unsigned char b : il) values.emplace_back(b); }
+ explicit ConfigOptionBoolsTempl(const std::vector<unsigned char>& vec) : ConfigOptionVector<unsigned char>(vec) {}
+ explicit ConfigOptionBoolsTempl(std::vector<unsigned char>&& vec) : ConfigOptionVector<unsigned char>(std::move(vec)) {}
static ConfigOptionType static_type() { return coBools; }
ConfigOptionType type() const override { return static_type(); }
- ConfigOption* clone() const override { return new ConfigOptionBools(*this); }
- ConfigOptionBools& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
- bool operator==(const ConfigOptionBools &rhs) const { return this->values == rhs.values; }
+ ConfigOption* clone() const override { return new ConfigOptionBoolsTempl(*this); }
+ ConfigOptionBoolsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
+ bool operator==(const ConfigOptionBoolsTempl &rhs) const { return this->values == rhs.values; }
+ // Could a special "nil" value be stored inside the vector, indicating undefined value?
+ bool nullable() const override { return NULLABLE; }
+ // Special "nil" value to be stored into the vector if this->supports_nil().
+ static unsigned char nil_value() { return std::numeric_limits<unsigned char>::max(); }
+ // A scalar is nil, or all values of a vector are nil.
+ bool is_nil() const override { for (auto v : this->values) if (v != nil_value()) return false; return true; }
+ bool is_nil(size_t idx) const override { return this->values[idx] == nil_value(); }
bool& get_at(size_t i) {
assert(! this->values.empty());
@@ -911,19 +1079,20 @@ public:
std::string serialize() const override
{
std::ostringstream ss;
- for (std::vector<unsigned char>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
- if (it - this->values.begin() != 0) ss << ",";
- ss << (*it ? "1" : "0");
- }
+ for (const unsigned char &v : this->values) {
+ if (&v != &this->values.front())
+ ss << ",";
+ this->serialize_single_value(ss, v);
+ }
return ss.str();
}
std::vector<std::string> vserialize() const override
{
std::vector<std::string> vv;
- for (std::vector<unsigned char>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
- std::ostringstream ss;
- ss << (*it ? "1" : "0");
+ for (const unsigned char v : this->values) {
+ std::ostringstream ss;
+ this->serialize_single_value(ss, v);
vv.push_back(ss.str());
}
return vv;
@@ -936,16 +1105,37 @@ public:
std::istringstream is(str);
std::string item_str;
while (std::getline(is, item_str, ',')) {
- this->values.push_back(item_str.compare("1") == 0);
+ boost::trim(item_str);
+ if (item_str == "nil") {
+ if (NULLABLE)
+ this->values.push_back(nil_value());
+ else
+ std::runtime_error("Deserializing nil into a non-nullable object");
+ } else
+ this->values.push_back(item_str.compare("1") == 0);
}
return true;
}
+protected:
+ void serialize_single_value(std::ostringstream &ss, const unsigned char v) const {
+ if (v == nil_value()) {
+ if (NULLABLE)
+ ss << "nil";
+ else
+ std::runtime_error("Serializing NaN");
+ } else
+ ss << (v ? "1" : "0");
+ }
+
private:
friend class cereal::access;
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionVector<unsigned char>>(this)); }
};
+using ConfigOptionBools = ConfigOptionBoolsTempl<false>;
+using ConfigOptionBoolsNullable = ConfigOptionBoolsTempl<true>;
+
// Map from an enum integer value to an enum name.
typedef std::vector<std::string> t_config_enum_names;
// Map from an enum name to an enum integer value.
@@ -1096,6 +1286,8 @@ public:
t_config_option_key opt_key;
// What type? bool, int, string etc.
ConfigOptionType type = coNone;
+ // If a type is nullable, then it accepts a "nil" value (scalar) or "nil" values (vector).
+ bool nullable = false;
// Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor.
Slic3r::clonable_ptr<const ConfigOption> default_value;
void set_default_value(const ConfigOption* ptr) { this->default_value = Slic3r::clonable_ptr<const ConfigOption>(ptr); }
@@ -1107,45 +1299,65 @@ public:
ConfigOption* create_default_option() const;
template<class Archive> ConfigOption* load_option_from_archive(Archive &archive) const {
- switch (this->type) {
- case coFloat: { auto opt = new ConfigOptionFloat(); archive(*opt); return opt; }
- case coFloats: { auto opt = new ConfigOptionFloats(); archive(*opt); return opt; }
- case coInt: { auto opt = new ConfigOptionInt(); archive(*opt); return opt; }
- case coInts: { auto opt = new ConfigOptionInts(); archive(*opt); return opt; }
- case coString: { auto opt = new ConfigOptionString(); archive(*opt); return opt; }
- case coStrings: { auto opt = new ConfigOptionStrings(); archive(*opt); return opt; }
- case coPercent: { auto opt = new ConfigOptionPercent(); archive(*opt); return opt; }
- case coPercents: { auto opt = new ConfigOptionPercents(); archive(*opt); return opt; }
- case coFloatOrPercent: { auto opt = new ConfigOptionFloatOrPercent(); archive(*opt); return opt; }
- case coPoint: { auto opt = new ConfigOptionPoint(); archive(*opt); return opt; }
- case coPoints: { auto opt = new ConfigOptionPoints(); archive(*opt); return opt; }
- case coPoint3: { auto opt = new ConfigOptionPoint3(); archive(*opt); return opt; }
- case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
- case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
- case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_keys_map); archive(*opt); return opt; }
- default: throw std::runtime_error(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
- }
+ if (this->nullable) {
+ switch (this->type) {
+ case coFloats: { auto opt = new ConfigOptionFloatsNullable(); archive(*opt); return opt; }
+ case coInts: { auto opt = new ConfigOptionIntsNullable(); archive(*opt); return opt; }
+ case coPercents: { auto opt = new ConfigOptionPercentsNullable();archive(*opt); return opt; }
+ case coBools: { auto opt = new ConfigOptionBoolsNullable(); archive(*opt); return opt; }
+ default: throw std::runtime_error(std::string("ConfigOptionDef::load_option_from_archive(): Unknown nullable option type for option ") + this->opt_key);
+ }
+ } else {
+ switch (this->type) {
+ case coFloat: { auto opt = new ConfigOptionFloat(); archive(*opt); return opt; }
+ case coFloats: { auto opt = new ConfigOptionFloats(); archive(*opt); return opt; }
+ case coInt: { auto opt = new ConfigOptionInt(); archive(*opt); return opt; }
+ case coInts: { auto opt = new ConfigOptionInts(); archive(*opt); return opt; }
+ case coString: { auto opt = new ConfigOptionString(); archive(*opt); return opt; }
+ case coStrings: { auto opt = new ConfigOptionStrings(); archive(*opt); return opt; }
+ case coPercent: { auto opt = new ConfigOptionPercent(); archive(*opt); return opt; }
+ case coPercents: { auto opt = new ConfigOptionPercents(); archive(*opt); return opt; }
+ case coFloatOrPercent: { auto opt = new ConfigOptionFloatOrPercent(); archive(*opt); return opt; }
+ case coPoint: { auto opt = new ConfigOptionPoint(); archive(*opt); return opt; }
+ case coPoints: { auto opt = new ConfigOptionPoints(); archive(*opt); return opt; }
+ case coPoint3: { auto opt = new ConfigOptionPoint3(); archive(*opt); return opt; }
+ case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
+ case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
+ case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_keys_map); archive(*opt); return opt; }
+ default: throw std::runtime_error(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
+ }
+ }
}
template<class Archive> ConfigOption* save_option_to_archive(Archive &archive, const ConfigOption *opt) const {
- switch (this->type) {
- case coFloat: archive(*static_cast<const ConfigOptionFloat*>(opt)); break;
- case coFloats: archive(*static_cast<const ConfigOptionFloats*>(opt)); break;
- case coInt: archive(*static_cast<const ConfigOptionInt*>(opt)); break;
- case coInts: archive(*static_cast<const ConfigOptionInts*>(opt)); break;
- case coString: archive(*static_cast<const ConfigOptionString*>(opt)); break;
- case coStrings: archive(*static_cast<const ConfigOptionStrings*>(opt)); break;
- case coPercent: archive(*static_cast<const ConfigOptionPercent*>(opt)); break;
- case coPercents: archive(*static_cast<const ConfigOptionPercents*>(opt)); break;
- case coFloatOrPercent: archive(*static_cast<const ConfigOptionFloatOrPercent*>(opt)); break;
- case coPoint: archive(*static_cast<const ConfigOptionPoint*>(opt)); break;
- case coPoints: archive(*static_cast<const ConfigOptionPoints*>(opt)); break;
- case coPoint3: archive(*static_cast<const ConfigOptionPoint3*>(opt)); break;
- case coBool: archive(*static_cast<const ConfigOptionBool*>(opt)); break;
- case coBools: archive(*static_cast<const ConfigOptionBools*>(opt)); break;
- case coEnum: archive(*static_cast<const ConfigOptionEnumGeneric*>(opt)); break;
- default: throw std::runtime_error(std::string("ConfigOptionDef::save_option_to_archive(): Unknown option type for option ") + this->opt_key);
- }
+ if (this->nullable) {
+ switch (this->type) {
+ case coFloats: archive(*static_cast<const ConfigOptionFloatsNullable*>(opt)); break;
+ case coInts: archive(*static_cast<const ConfigOptionIntsNullable*>(opt)); break;
+ case coPercents: archive(*static_cast<const ConfigOptionPercentsNullable*>(opt));break;
+ case coBools: archive(*static_cast<const ConfigOptionBoolsNullable*>(opt)); break;
+ default: throw std::runtime_error(std::string("ConfigOptionDef::save_option_to_archive(): Unknown nullable option type for option ") + this->opt_key);
+ }
+ } else {
+ switch (this->type) {
+ case coFloat: archive(*static_cast<const ConfigOptionFloat*>(opt)); break;
+ case coFloats: archive(*static_cast<const ConfigOptionFloats*>(opt)); break;
+ case coInt: archive(*static_cast<const ConfigOptionInt*>(opt)); break;
+ case coInts: archive(*static_cast<const ConfigOptionInts*>(opt)); break;
+ case coString: archive(*static_cast<const ConfigOptionString*>(opt)); break;
+ case coStrings: archive(*static_cast<const ConfigOptionStrings*>(opt)); break;
+ case coPercent: archive(*static_cast<const ConfigOptionPercent*>(opt)); break;
+ case coPercents: archive(*static_cast<const ConfigOptionPercents*>(opt)); break;
+ case coFloatOrPercent: archive(*static_cast<const ConfigOptionFloatOrPercent*>(opt)); break;
+ case coPoint: archive(*static_cast<const ConfigOptionPoint*>(opt)); break;
+ case coPoints: archive(*static_cast<const ConfigOptionPoints*>(opt)); break;
+ case coPoint3: archive(*static_cast<const ConfigOptionPoint3*>(opt)); break;
+ case coBool: archive(*static_cast<const ConfigOptionBool*>(opt)); break;
+ case coBools: archive(*static_cast<const ConfigOptionBools*>(opt)); break;
+ case coEnum: archive(*static_cast<const ConfigOptionEnumGeneric*>(opt)); break;
+ default: throw std::runtime_error(std::string("ConfigOptionDef::save_option_to_archive(): Unknown option type for option ") + this->opt_key);
+ }
+ }
// Make the compiler happy, shut up the warnings.
return nullptr;
}
@@ -1263,6 +1475,7 @@ public:
protected:
ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type);
+ ConfigOptionDef* add_nullable(const t_config_option_key &opt_key, ConfigOptionType type);
};
// An abstract configuration store.
@@ -1347,6 +1560,9 @@ public:
void load(const boost::property_tree::ptree &tree);
void save(const std::string &file) const;
+ // Set all the nullable values to nils.
+ void null_nullables();
+
private:
// Set a configuration value from a string.
bool set_deserialize_raw(const t_config_option_key &opt_key_src, const std::string &str, bool append);
@@ -1444,9 +1660,12 @@ public:
return true;
}
+ // Remove options with all nil values, those are optional and it does not help to hold them.
+ size_t remove_nil_options();
+
// Allow DynamicConfig to be instantiated on ints own without a definition.
// If the definition is not defined, the method requiring the definition will throw NoDefinitionException.
- const ConfigDef* def() const override { return nullptr; };
+ const ConfigDef* def() const override { return nullptr; }
template<class T> T* opt(const t_config_option_key &opt_key, bool create = false)
{ return dynamic_cast<T*>(this->option(opt_key, create)); }
template<class T> const T* opt(const t_config_option_key &opt_key) const
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 81880831f..bc3730026 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1829,25 +1829,12 @@ void GCode::apply_print_config(const PrintConfig &print_config)
m_config.apply(print_config);
}
-void GCode::append_full_config(const Print& print, std::string& str)
+void GCode::append_full_config(const Print &print, std::string &str)
{
- const StaticPrintConfig *configs[] = { static_cast<const GCodeConfig*>(&print.config()), &print.default_object_config(), &print.default_region_config() };
- for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++i) {
- const StaticPrintConfig *cfg = configs[i];
- for (const std::string &key : cfg->keys())
- if (key != "compatible_printers")
- str += "; " + key + " = " + cfg->opt_serialize(key) + "\n";
- }
- const DynamicConfig &full_config = print.placeholder_parser().config();
- for (const char *key : {
- "print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id",
- "printer_model", "printer_variant",
- "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile",
- "compatible_prints_condition_cummulative", "compatible_printers_condition_cummulative", "inherits_cummulative" }) {
- const ConfigOption *opt = full_config.option(key);
- if (opt != nullptr)
- str += std::string("; ") + key + " = " + opt->serialize() + "\n";
- }
+ const DynamicPrintConfig &cfg = print.full_print_config();
+ for (const std::string &key : cfg.keys())
+ if (key != "compatible_prints" && key != "compatible_printers" && ! cfg.option(key)->is_nil())
+ str += "; " + key + " = " + cfg.opt_serialize(key) + "\n";
}
void GCode::set_extruders(const std::vector<unsigned int> &extruder_ids)
diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp
index 2bfe9b745..c3ac22e96 100644
--- a/src/libslic3r/PlaceholderParser.cpp
+++ b/src/libslic3r/PlaceholderParser.cpp
@@ -62,7 +62,7 @@
namespace Slic3r {
-PlaceholderParser::PlaceholderParser()
+PlaceholderParser::PlaceholderParser(const DynamicConfig *external_config) : m_external_config(external_config)
{
this->set("version", std::string(SLIC3R_VERSION));
this->apply_env_variables();
@@ -94,14 +94,6 @@ void PlaceholderParser::update_timestamp(DynamicConfig &config)
config.set_key_value("second", new ConfigOptionInt(timeinfo->tm_sec));
}
-// Ignore this key by the placeholder parser.
-static inline bool placeholder_parser_ignore(const ConfigDef *def, const std::string &opt_key)
-{
- const ConfigOptionDef *opt_def = def->get(opt_key);
- assert(opt_def != nullptr);
- return (opt_def->multiline && boost::ends_with(opt_key, "_gcode")) || opt_key == "post_process";
-}
-
static inline bool opts_equal(const DynamicConfig &config_old, const DynamicConfig &config_new, const std::string &opt_key)
{
const ConfigOption *opt_old = config_old.option(opt_key);
@@ -119,7 +111,7 @@ std::vector<std::string> PlaceholderParser::config_diff(const DynamicPrintConfig
const ConfigDef *def = rhs.def();
std::vector<std::string> diff_keys;
for (const t_config_option_key &opt_key : rhs.keys())
- if (! placeholder_parser_ignore(def, opt_key) && ! opts_equal(m_config, rhs, opt_key))
+ if (! opts_equal(m_config, rhs, opt_key))
diff_keys.emplace_back(opt_key);
return diff_keys;
}
@@ -135,8 +127,6 @@ bool PlaceholderParser::apply_config(const DynamicPrintConfig &rhs)
const ConfigDef *def = rhs.def();
bool modified = false;
for (const t_config_option_key &opt_key : rhs.keys()) {
- if (placeholder_parser_ignore(def, opt_key))
- continue;
if (! opts_equal(m_config, rhs, opt_key)) {
// Store a copy of the config option.
// Convert FloatOrPercent values to floats first.
@@ -155,7 +145,6 @@ bool PlaceholderParser::apply_config(const DynamicPrintConfig &rhs)
void PlaceholderParser::apply_only(const DynamicPrintConfig &rhs, const std::vector<std::string> &keys)
{
for (const t_config_option_key &opt_key : keys) {
- assert(! placeholder_parser_ignore(rhs.def(), opt_key));
// Store a copy of the config option.
// Convert FloatOrPercent values to floats first.
//FIXME there are some ratio_over chains, which end with empty ratio_with.
@@ -167,6 +156,11 @@ void PlaceholderParser::apply_only(const DynamicPrintConfig &rhs, const std::vec
}
}
+void PlaceholderParser::apply_config(DynamicPrintConfig &&rhs)
+{
+ m_config += std::move(rhs);
+}
+
void PlaceholderParser::apply_env_variables()
{
for (char** env = environ; *env; ++ env) {
@@ -608,6 +602,7 @@ namespace client
}
struct MyContext {
+ const DynamicConfig *external_config = nullptr;
const DynamicConfig *config = nullptr;
const DynamicConfig *config_override = nullptr;
size_t current_extruder_id = 0;
@@ -628,6 +623,8 @@ namespace client
opt = config_override->option(opt_key);
if (opt == nullptr)
opt = config->option(opt_key);
+ if (opt == nullptr && external_config != nullptr)
+ opt = external_config->option(opt_key);
return opt;
}
@@ -1255,6 +1252,7 @@ static std::string process_macro(const std::string &templ, client::MyContext &co
std::string PlaceholderParser::process(const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override) const
{
client::MyContext context;
+ context.external_config = this->external_config();
context.config = &this->config();
context.config_override = config_override;
context.current_extruder_id = current_extruder_id;
@@ -1266,8 +1264,8 @@ std::string PlaceholderParser::process(const std::string &templ, unsigned int cu
bool PlaceholderParser::evaluate_boolean_expression(const std::string &templ, const DynamicConfig &config, const DynamicConfig *config_override)
{
client::MyContext context;
- context.config = &config;
- context.config_override = config_override;
+ context.config = &config;
+ context.config_override = config_override;
// Let the macro processor parse just a boolean expression, not the full macro language.
context.just_boolean_expression = true;
return process_macro(templ, context) == "true";
diff --git a/src/libslic3r/PlaceholderParser.hpp b/src/libslic3r/PlaceholderParser.hpp
index 22c790e6b..14fdc5c28 100644
--- a/src/libslic3r/PlaceholderParser.hpp
+++ b/src/libslic3r/PlaceholderParser.hpp
@@ -12,13 +12,14 @@ namespace Slic3r {
class PlaceholderParser
{
public:
- PlaceholderParser();
+ PlaceholderParser(const DynamicConfig *external_config = nullptr);
// Return a list of keys, which should be changed in m_config from rhs.
// This contains keys, which are found in rhs, but not in m_config.
std::vector<std::string> config_diff(const DynamicPrintConfig &rhs);
// Return true if modified.
bool apply_config(const DynamicPrintConfig &config);
+ void apply_config(DynamicPrintConfig &&config);
// To be called on the values returned by PlaceholderParser::config_diff().
// The keys should already be valid.
void apply_only(const DynamicPrintConfig &config, const std::vector<std::string> &keys);
@@ -35,6 +36,8 @@ public:
DynamicConfig& config_writable() { return m_config; }
const DynamicConfig& config() const { return m_config; }
const ConfigOption* option(const std::string &key) const { return m_config.option(key); }
+ // External config is not owned by PlaceholderParser. It has a lowest priority when looking up an option.
+ const DynamicConfig* external_config() const { return m_external_config; }
// Fill in the template using a macro processing language.
// Throws std::runtime_error on syntax or runtime error.
@@ -50,7 +53,9 @@ public:
void update_timestamp() { update_timestamp(m_config); }
private:
- DynamicConfig m_config;
+ // config has a higher priority than external_config when looking up a symbol.
+ DynamicConfig m_config;
+ const DynamicConfig *m_external_config;
};
}
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 5702f49e3..c423afeb9 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -485,25 +485,82 @@ bool layer_height_ranges_equal(const t_layer_config_ranges &lr1, const t_layer_c
return true;
}
-Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &config_in)
+// Collect diffs of configuration values at various containers,
+// resolve the filament rectract overrides of extruder retract values.
+void Print::config_diffs(
+ const DynamicPrintConfig &new_full_config,
+ t_config_option_keys &print_diff, t_config_option_keys &object_diff, t_config_option_keys &region_diff,
+ t_config_option_keys &full_config_diff,
+ DynamicPrintConfig &placeholder_parser_overrides,
+ DynamicPrintConfig &filament_overrides) const
+{
+ // Collect changes to print config, account for overrides of extruder retract values by filament presets.
+ {
+ const std::vector<std::string> &extruder_retract_keys = print_config_def.extruder_retract_keys();
+ const std::string filament_prefix = "filament_";
+ for (const t_config_option_key &opt_key : m_config.keys()) {
+ const ConfigOption *opt_old = m_config.option(opt_key);
+ assert(opt_old != nullptr);
+ const ConfigOption *opt_new = new_full_config.option(opt_key);
+ // assert(opt_new != nullptr);
+ if (opt_new == nullptr)
+ //FIXME This may happen when executing some test cases.
+ continue;
+ const ConfigOption *opt_new_filament = std::binary_search(extruder_retract_keys.begin(), extruder_retract_keys.end(), opt_key) ? new_full_config.option(filament_prefix + opt_key) : nullptr;
+ if (opt_new_filament != nullptr && ! opt_new_filament->is_nil()) {
+ // An extruder retract override is available at some of the filament presets.
+ if (*opt_old != *opt_new || opt_new->overriden_by(opt_new_filament)) {
+ auto opt_copy = opt_new->clone();
+ opt_copy->apply_override(opt_new_filament);
+ if (*opt_old == *opt_copy)
+ delete opt_copy;
+ else {
+ filament_overrides.set_key_value(opt_key, opt_copy);
+ print_diff.emplace_back(opt_key);
+ }
+ }
+ } else if (*opt_new != *opt_old)
+ print_diff.emplace_back(opt_key);
+ }
+ }
+ // Collect changes to object and region configs.
+ object_diff = m_default_object_config.diff(new_full_config);
+ region_diff = m_default_region_config.diff(new_full_config);
+ // Prepare for storing of the full print config into new_full_config to be exported into the G-code and to be used by the PlaceholderParser.
+ // As the PlaceholderParser does not interpret the FloatOrPercent values itself, these values are stored into the PlaceholderParser converted to floats.
+ for (const t_config_option_key &opt_key : new_full_config.keys()) {
+ const ConfigOption *opt_old = m_full_print_config.option(opt_key);
+ const ConfigOption *opt_new = new_full_config.option(opt_key);
+ if (opt_old == nullptr || *opt_new != *opt_old)
+ full_config_diff.emplace_back(opt_key);
+ if (opt_new->type() == coFloatOrPercent) {
+ // The m_placeholder_parser is never modified by the background processing, GCode.cpp/hpp makes a copy.
+ const ConfigOption *opt_old_pp = this->placeholder_parser().config().option(opt_key);
+ double new_value = new_full_config.get_abs_value(opt_key);
+ if (opt_old_pp == nullptr || static_cast<const ConfigOptionFloat*>(opt_old_pp)->value != new_value)
+ placeholder_parser_overrides.set_key_value(opt_key, new ConfigOptionFloat(new_value));
+ }
+ }
+}
+
+Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_config)
{
#ifdef _DEBUG
check_model_ids_validity(model);
#endif /* _DEBUG */
- // Make a copy of the config, normalize it.
- DynamicPrintConfig config(config_in);
- config.option("print_settings_id", true);
- config.option("filament_settings_id", true);
- config.option("printer_settings_id", true);
- config.normalize();
- // Collect changes to print config.
- t_config_option_keys print_diff = m_config.diff(config);
- t_config_option_keys object_diff = m_default_object_config.diff(config);
- t_config_option_keys region_diff = m_default_region_config.diff(config);
- t_config_option_keys placeholder_parser_diff = this->placeholder_parser().config_diff(config);
-
- // Do not use the ApplyStatus as we will use the max function when updating apply_status.
+ // Normalize the config.
+ new_full_config.option("print_settings_id", true);
+ new_full_config.option("filament_settings_id", true);
+ new_full_config.option("printer_settings_id", true);
+ new_full_config.normalize();
+
+ // Find modified keys of the various configs. Resolve overrides extruder retract values by filament profiles.
+ t_config_option_keys print_diff, object_diff, region_diff, full_config_diff;
+ DynamicPrintConfig placeholder_parser_overrides, filament_overrides;
+ this->config_diffs(new_full_config, print_diff, object_diff, region_diff, full_config_diff, placeholder_parser_overrides, filament_overrides);
+
+ // Do not use the ApplyStatus as we will use the max function when updating apply_status.
unsigned int apply_status = APPLY_STATUS_UNCHANGED;
auto update_apply_status = [&apply_status](bool invalidated)
{ apply_status = std::max<unsigned int>(apply_status, invalidated ? APPLY_STATUS_INVALIDATED : APPLY_STATUS_CHANGED); };
@@ -516,24 +573,25 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
// The following call may stop the background processing.
if (! print_diff.empty())
update_apply_status(this->invalidate_state_by_config_options(print_diff));
+
// Apply variables to placeholder parser. The placeholder parser is used by G-code export,
// which should be stopped if print_diff is not empty.
- if (! placeholder_parser_diff.empty()) {
+ if (! full_config_diff.empty() || ! placeholder_parser_overrides.empty()) {
update_apply_status(this->invalidate_step(psGCodeExport));
- PlaceholderParser &pp = this->placeholder_parser();
- pp.apply_only(config, placeholder_parser_diff);
+ m_placeholder_parser.apply_config(std::move(placeholder_parser_overrides));
// Set the profile aliases for the PrintBase::output_filename()
- pp.set("print_preset", config.option("print_settings_id")->clone());
- pp.set("filament_preset", config.option("filament_settings_id")->clone());
- pp.set("printer_preset", config.option("printer_settings_id")->clone());
+ m_placeholder_parser.set("print_preset", new_full_config.option("print_settings_id")->clone());
+ m_placeholder_parser.set("filament_preset", new_full_config.option("filament_settings_id")->clone());
+ m_placeholder_parser.set("printer_preset", new_full_config.option("printer_settings_id")->clone());
+ // It is also safe to change m_config now after this->invalidate_state_by_config_options() call.
+ m_config.apply_only(new_full_config, print_diff, true);
+ m_config.apply(filament_overrides);
+ // Handle changes to object config defaults
+ m_default_object_config.apply_only(new_full_config, object_diff, true);
+ // Handle changes to regions config defaults
+ m_default_region_config.apply_only(new_full_config, region_diff, true);
+ m_full_print_config = std::move(new_full_config);
}
-
- // It is also safe to change m_config now after this->invalidate_state_by_config_options() call.
- m_config.apply_only(config, print_diff, true);
- // Handle changes to object config defaults
- m_default_object_config.apply_only(config, object_diff, true);
- // Handle changes to regions config defaults
- m_default_region_config.apply_only(config, region_diff, true);
class LayerRanges
{
@@ -545,9 +603,8 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
m_ranges.reserve(in.size());
// Input ranges are sorted lexicographically. First range trims the other ranges.
coordf_t last_z = 0;
- for (const std::pair<const t_layer_height_range, DynamicPrintConfig> &range : in) {
-// for (auto &range : in) {
- if (range.first.second > last_z) {
+ for (const std::pair<const t_layer_height_range, DynamicPrintConfig> &range : in)
+ if (range.first.second > last_z) {
coordf_t min_z = std::max(range.first.first, 0.);
if (min_z > last_z + EPSILON) {
m_ranges.emplace_back(t_layer_height_range(last_z, min_z), nullptr);
@@ -559,7 +616,6 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
last_z = range.first.second;
}
}
- }
if (m_ranges.empty())
m_ranges.emplace_back(t_layer_height_range(0, DBL_MAX), nullptr);
else if (m_ranges.back().second == nullptr)
@@ -1707,9 +1763,9 @@ void Print::_make_wipe_tower()
(float)m_config.filament_cooling_initial_speed.get_at(i),
(float)m_config.filament_cooling_final_speed.get_at(i),
m_config.filament_ramming_parameters.get_at(i),
- m_config.filament_max_volumetric_speed.get_at(i),
- m_config.nozzle_diameter.get_at(i),
- m_config.filament_diameter.get_at(i));
+ (float)m_config.filament_max_volumetric_speed.get_at(i),
+ (float)m_config.nozzle_diameter.get_at(i),
+ (float)m_config.filament_diameter.get_at(i));
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
@@ -1791,47 +1847,7 @@ std::string Print::output_filename(const std::string &filename_base) const
DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders();
return this->PrintBase::output_filename(m_config.output_filename_format.value, ".gcode", filename_base, &config);
}
-/*
-// Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
-// and removing spaces.
-static std::string short_time(const std::string &time)
-{
- // Parse the dhms time format.
- int days = 0;
- int hours = 0;
- int minutes = 0;
- int seconds = 0;
- if (time.find('d') != std::string::npos)
- ::sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds);
- else if (time.find('h') != std::string::npos)
- ::sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds);
- else if (time.find('m') != std::string::npos)
- ::sscanf(time.c_str(), "%dm %ds", &minutes, &seconds);
- else if (time.find('s') != std::string::npos)
- ::sscanf(time.c_str(), "%ds", &seconds);
- // Round to full minutes.
- if (days + hours + minutes > 0 && seconds >= 30) {
- if (++ minutes == 60) {
- minutes = 0;
- if (++ hours == 24) {
- hours = 0;
- ++ days;
- }
- }
- }
- // Format the dhm time.
- char buffer[64];
- if (days > 0)
- ::sprintf(buffer, "%dd%dh%dm", days, hours, minutes);
- else if (hours > 0)
- ::sprintf(buffer, "%dh%dm", hours, minutes);
- else if (minutes > 0)
- ::sprintf(buffer, "%dm", minutes);
- else
- ::sprintf(buffer, "%ds", seconds);
- return buffer;
-}
-*/
+
DynamicConfig PrintStatistics::config() const
{
DynamicConfig config;
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 368bf4ee8..b6d7b678d 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -296,7 +296,7 @@ public:
void clear() override;
bool empty() const override { return m_objects.empty(); }
- ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) override;
+ ApplyStatus apply(const Model &model, DynamicPrintConfig config) override;
void process() override;
// Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file.
@@ -368,6 +368,13 @@ protected:
bool invalidate_step(PrintStep step);
private:
+ void config_diffs(
+ const DynamicPrintConfig &new_full_config,
+ t_config_option_keys &print_diff, t_config_option_keys &object_diff, t_config_option_keys &region_diff,
+ t_config_option_keys &full_config_diff,
+ DynamicPrintConfig &placeholder_parser_overrides,
+ DynamicPrintConfig &filament_overrides) const;
+
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
void _make_skirt();
diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp
index d84d492a0..aebc87904 100644
--- a/src/libslic3r/PrintBase.hpp
+++ b/src/libslic3r/PrintBase.hpp
@@ -217,7 +217,7 @@ protected:
class PrintBase
{
public:
- PrintBase() { this->restart(); }
+ PrintBase() : m_placeholder_parser(&m_full_print_config) { this->restart(); }
inline virtual ~PrintBase() {}
virtual PrinterTechnology technology() const noexcept = 0;
@@ -240,7 +240,7 @@ public:
// Some data was changed, which in turn invalidated already calculated steps.
APPLY_STATUS_INVALIDATED,
};
- virtual ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) = 0;
+ virtual ApplyStatus apply(const Model &model, DynamicPrintConfig config) = 0;
const Model& model() const { return m_model; }
struct TaskParams {
@@ -316,7 +316,7 @@ public:
virtual bool finished() const = 0;
const PlaceholderParser& placeholder_parser() const { return m_placeholder_parser; }
- PlaceholderParser& placeholder_parser() { return m_placeholder_parser; }
+ const DynamicPrintConfig& full_print_config() const { return m_full_print_config; }
virtual std::string output_filename(const std::string &filename_base = std::string()) const = 0;
// If the filename_base is set, it is used as the input for the template processing. In that case the path is expected to be the directory (may be empty).
@@ -341,6 +341,8 @@ protected:
void update_object_placeholders(DynamicConfig &config, const std::string &default_ext) const;
Model m_model;
+ DynamicPrintConfig m_full_print_config;
+ PlaceholderParser m_placeholder_parser;
private:
tbb::atomic<CancelStatus> m_cancel_status;
@@ -354,8 +356,6 @@ private:
// The mutex will be used to guard the worker thread against entering a stage
// while the data influencing the stage is modified.
mutable tbb::mutex m_state_mutex;
-
- PlaceholderParser m_placeholder_parser;
};
template<typename PrintStepEnum, const size_t COUNT>
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 8e091fb80..304f6f749 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -29,6 +29,7 @@ PrintConfigDef::PrintConfigDef()
this->init_common_params();
assign_printer_technology_to_unknown(this->options, ptAny);
this->init_fff_params();
+ this->init_extruder_retract_keys();
assign_printer_technology_to_unknown(this->options, ptFFF);
this->init_sla_params();
assign_printer_technology_to_unknown(this->options, ptSLA);
@@ -2238,6 +2239,48 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("mm");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));
+
+ // Declare retract values for filament profile, overriding the printer's extruder profile.
+ for (const char *opt_key : {
+ // floats
+ "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_restart_extra", "retract_before_travel",
+ // bools
+ "retract_layer_change", "wipe",
+ // percents
+ "retract_before_wipe"}) {
+ auto it_opt = options.find(opt_key);
+ assert(it_opt != options.end());
+ def = this->add_nullable(std::string("filament_") + opt_key, it_opt->second.type);
+ def->label = it_opt->second.label;
+ def->full_label = it_opt->second.full_label;
+ def->tooltip = it_opt->second.tooltip;
+ def->sidetext = it_opt->second.sidetext;
+ def->mode = it_opt->second.mode;
+ switch (def->type) {
+ case coFloats : def->set_default_value(new ConfigOptionFloatsNullable (static_cast<const ConfigOptionFloats* >(it_opt->second.default_value.get())->values)); break;
+ case coPercents : def->set_default_value(new ConfigOptionPercentsNullable(static_cast<const ConfigOptionPercents*>(it_opt->second.default_value.get())->values)); break;
+ case coBools : def->set_default_value(new ConfigOptionBoolsNullable (static_cast<const ConfigOptionBools* >(it_opt->second.default_value.get())->values)); break;
+ default: assert(false);
+ }
+ }
+}
+
+void PrintConfigDef::init_extruder_retract_keys()
+{
+ m_extruder_retract_keys = {
+ "deretract_speed",
+ "retract_before_travel",
+ "retract_before_wipe",
+ "retract_layer_change",
+ "retract_length",
+ "retract_lift",
+ "retract_lift_above",
+ "retract_lift_below",
+ "retract_restart_extra",
+ "retract_speed",
+ "wipe"
+ };
+ assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end()));
}
void PrintConfigDef::init_sla_params()
@@ -2997,7 +3040,7 @@ std::string FullPrintConfig::validate()
}
case coFloats:
case coPercents:
- for (double v : static_cast<const ConfigOptionFloats*>(opt)->values)
+ for (double v : static_cast<const ConfigOptionVector<double>*>(opt)->values)
if (v < optdef->min || v > optdef->max) {
out_of_range = true;
break;
@@ -3010,7 +3053,7 @@ std::string FullPrintConfig::validate()
break;
}
case coInts:
- for (int v : static_cast<const ConfigOptionInts*>(opt)->values)
+ for (int v : static_cast<const ConfigOptionVector<int>*>(opt)->values)
if (v < optdef->min || v > optdef->max) {
out_of_range = true;
break;
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 5731bef00..f2d0775fa 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -185,10 +185,18 @@ public:
static void handle_legacy(t_config_option_key &opt_key, std::string &value);
+ // Options defining the extruder retract properties. These keys are sorted lexicographically.
+ // The extruder retract keys could be overidden by the same values defined at the Filament level
+ // (then the key is further prefixed with the "filament_" prefix).
+ const std::vector<std::string>& extruder_retract_keys() const { return m_extruder_retract_keys; }
+
private:
void init_common_params();
void init_fff_params();
+ void init_extruder_retract_keys();
void init_sla_params();
+
+ std::vector<std::string> m_extruder_retract_keys;
};
// The one and only global definition of SLic3r configuration options.
diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp
index 5669307ac..45f8a0c83 100644
--- a/src/libslic3r/SLAPrint.cpp
+++ b/src/libslic3r/SLAPrint.cpp
@@ -145,14 +145,13 @@ static std::vector<SLAPrintObject::Instance> sla_instances(const ModelObject &mo
return instances;
}
-SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConfig &config_in)
+SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig config)
{
#ifdef _DEBUG
check_model_ids_validity(model);
#endif /* _DEBUG */
- // Make a copy of the config, normalize it.
- DynamicPrintConfig config(config_in);
+ // Normalize the config.
config.option("sla_print_settings_id", true);
config.option("sla_material_settings_id", true);
config.option("printer_settings_id", true);
@@ -162,7 +161,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
t_config_option_keys printer_diff = m_printer_config.diff(config);
t_config_option_keys material_diff = m_material_config.diff(config);
t_config_option_keys object_diff = m_default_object_config.diff(config);
- t_config_option_keys placeholder_parser_diff = this->placeholder_parser().config_diff(config);
+ t_config_option_keys placeholder_parser_diff = m_placeholder_parser.config_diff(config);
// Do not use the ApplyStatus as we will use the max function when updating apply_status.
unsigned int apply_status = APPLY_STATUS_UNCHANGED;
@@ -187,12 +186,11 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
// only to generate the output file name.
if (! placeholder_parser_diff.empty()) {
// update_apply_status(this->invalidate_step(slapsRasterize));
- PlaceholderParser &pp = this->placeholder_parser();
- pp.apply_config(config);
+ m_placeholder_parser.apply_config(config);
// Set the profile aliases for the PrintBase::output_filename()
- pp.set("print_preset", config.option("sla_print_settings_id")->clone());
- pp.set("material_preset", config.option("sla_material_settings_id")->clone());
- pp.set("printer_preset", config.option("printer_settings_id")->clone());
+ m_placeholder_parser.set("print_preset", config.option("sla_print_settings_id")->clone());
+ m_placeholder_parser.set("material_preset", config.option("sla_material_settings_id")->clone());
+ m_placeholder_parser.set("printer_preset", config.option("printer_settings_id")->clone());
}
// It is also safe to change m_config now after this->invalidate_state_by_config_options() call.
@@ -459,6 +457,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
check_model_ids_equal(m_model, model);
#endif /* _DEBUG */
+ m_full_print_config = std::move(config);
return static_cast<ApplyStatus>(apply_status);
}
diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp
index c4e58ab39..e8cdac1b8 100644
--- a/src/libslic3r/SLAPrint.hpp
+++ b/src/libslic3r/SLAPrint.hpp
@@ -349,7 +349,7 @@ public:
void clear() override;
bool empty() const override { return m_objects.empty(); }
- ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) override;
+ ApplyStatus apply(const Model &model, DynamicPrintConfig config) override;
void set_task(const TaskParams &params) override;
void process() override;
void finalize() override;
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index db935cc05..39fa9c54b 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -136,6 +136,8 @@ bool Field::is_matched(const std::string& string, const std::string& pattern)
return std::regex_match(string, regex_pattern);
}
+static wxString na_value() { return _(L("N/A")); }
+
void Field::get_value_by_opt_type(wxString& str)
{
switch (m_opt.type) {
@@ -165,7 +167,9 @@ void Field::get_value_by_opt_type(wxString& str)
val = 0.0;
else
{
- if (!str.ToCDouble(&val))
+ if (m_opt.nullable && str == na_value())
+ val = ConfigOptionFloatsNullable::nil_value();
+ else if (!str.ToCDouble(&val))
{
show_error(m_parent, _(L("Invalid numeric input.")));
set_value(double_to_string(val), true);
@@ -256,6 +260,7 @@ void TextCtrl::BUILD() {
m_opt.default_value->getFloat() :
m_opt.get_default_value<ConfigOptionPercents>()->get_at(m_opt_idx);
text_value = double_to_string(val);
+ m_last_meaningful_value = text_value;
break;
}
case coString:
@@ -325,24 +330,7 @@ void TextCtrl::BUILD() {
}
propagate_value();
}), temp->GetId());
- /*
- temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt)
- {
-#ifdef __WXGTK__
- if (bChangedValueEvent)
-#endif //__WXGTK__
- if(is_defined_input_value())
- on_change_field();
- }), temp->GetId());
-#ifdef __WXGTK__
- // to correct value updating on GTK we should:
- // call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT
- // and prevent value updating on wxEVT_KEY_DOWN
- temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this);
- temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this);
-#endif //__WXGTK__
-*/
// select all text using Ctrl+A
temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event)
{
@@ -355,14 +343,70 @@ void TextCtrl::BUILD() {
window = dynamic_cast<wxWindow*>(temp);
}
+bool TextCtrl::value_was_changed()
+{
+ if (m_value.empty())
+ return true;
+
+ boost::any val = m_value;
+ wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
+ // update m_value!
+ get_value_by_opt_type(ret_str);
+
+ switch (m_opt.type) {
+ case coInt:
+ return boost::any_cast<int>(m_value) != boost::any_cast<int>(val);
+ case coPercent:
+ case coPercents:
+ case coFloats:
+ case coFloat: {
+ if (m_opt.nullable && std::isnan(boost::any_cast<double>(m_value)) &&
+ std::isnan(boost::any_cast<double>(val)))
+ return false;
+ return boost::any_cast<double>(m_value) != boost::any_cast<double>(val);
+ }
+ case coString:
+ case coStrings:
+ case coFloatOrPercent:
+ return boost::any_cast<std::string>(m_value) != boost::any_cast<std::string>(val);
+ default:
+ return true;
+ }
+}
+
void TextCtrl::propagate_value()
{
- if (is_defined_input_value<wxTextCtrl>(window, m_opt.type))
+ if (is_defined_input_value<wxTextCtrl>(window, m_opt.type) && value_was_changed())
on_change_field();
else
on_kill_focus();
}
+void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) {
+ m_disable_change_event = !change_event;
+ if (m_opt.nullable) {
+ const bool m_is_na_val = boost::any_cast<wxString>(value) == na_value();
+ if (!m_is_na_val)
+ m_last_meaningful_value = value;
+ dynamic_cast<wxTextCtrl*>(window)->SetValue(m_is_na_val ? na_value() : boost::any_cast<wxString>(value));
+ }
+ else
+ dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(value));
+ m_disable_change_event = false;
+}
+
+void TextCtrl::set_last_meaningful_value()
+{
+ dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(m_last_meaningful_value));
+ propagate_value();
+}
+
+void TextCtrl::set_na_value()
+{
+ dynamic_cast<wxTextCtrl*>(window)->SetValue(na_value());
+ propagate_value();
+}
+
boost::any& TextCtrl::get_value()
{
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
@@ -409,6 +453,8 @@ void CheckBox::BUILD() {
m_opt.get_default_value<ConfigOptionBools>()->get_at(m_opt_idx) :
false;
+ m_last_meaningful_value = static_cast<unsigned char>(check_value);
+
// Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size);
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@@ -416,7 +462,10 @@ void CheckBox::BUILD() {
temp->SetValue(check_value);
if (m_opt.readonly) temp->Disable();
- temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId());
+ temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) {
+ m_is_na_val = false;
+ on_change_field();
+ }), temp->GetId());
temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false"));
@@ -424,6 +473,38 @@ void CheckBox::BUILD() {
window = dynamic_cast<wxWindow*>(temp);
}
+void CheckBox::set_value(const boost::any& value, bool change_event)
+{
+ m_disable_change_event = !change_event;
+ if (m_opt.nullable) {
+ m_is_na_val = boost::any_cast<unsigned char>(value) == ConfigOptionBoolsNullable::nil_value();
+ if (!m_is_na_val)
+ m_last_meaningful_value = value;
+ dynamic_cast<wxCheckBox*>(window)->SetValue(m_is_na_val ? false : boost::any_cast<unsigned char>(value) != 0);
+ }
+ else
+ dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<bool>(value));
+ m_disable_change_event = false;
+}
+
+void CheckBox::set_last_meaningful_value()
+{
+ if (m_opt.nullable) {
+ m_is_na_val = false;
+ dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<unsigned char>(m_last_meaningful_value) != 0);
+ on_change_field();
+ }
+}
+
+void CheckBox::set_na_value()
+{
+ if (m_opt.nullable) {
+ m_is_na_val = true;
+ dynamic_cast<wxCheckBox*>(window)->SetValue(false);
+ on_change_field();
+ }
+}
+
boost::any& CheckBox::get_value()
{
// boost::any m_value;
@@ -431,7 +512,7 @@ boost::any& CheckBox::get_value()
if (m_opt.type == coBool)
m_value = static_cast<bool>(value);
else
- m_value = static_cast<unsigned char>(value);
+ m_value = m_is_na_val ? ConfigOptionBoolsNullable::nil_value() : static_cast<unsigned char>(value);
return m_value;
}
diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp
index 990c40e6f..6c16f90f2 100644
--- a/src/slic3r/GUI/Field.hpp
+++ b/src/slic3r/GUI/Field.hpp
@@ -123,6 +123,8 @@ public:
/// subclasses should overload with a specific version
/// Postcondition: Method does not fire the on_change event.
virtual void set_value(const boost::any& value, bool change_event) = 0;
+ virtual void set_last_meaningful_value() {}
+ virtual void set_na_value() {}
/// Gets a boost::any representing this control.
/// subclasses should overload with a specific version
@@ -247,6 +249,8 @@ protected:
// current value
boost::any m_value;
+ // last maeningful value
+ boost::any m_last_meaningful_value;
int m_em_unit;
@@ -277,6 +281,7 @@ public:
~TextCtrl() {}
void BUILD();
+ bool value_was_changed();
// Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER
void propagate_value();
wxWindow* window {nullptr};
@@ -286,11 +291,9 @@ public:
dynamic_cast<wxTextCtrl*>(window)->SetValue(wxString(value));
m_disable_change_event = false;
}
- virtual void set_value(const boost::any& value, bool change_event = false) {
- m_disable_change_event = !change_event;
- dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(value));
- m_disable_change_event = false;
- }
+ virtual void set_value(const boost::any& value, bool change_event = false) override;
+ virtual void set_last_meaningful_value() override;
+ virtual void set_na_value() override;
boost::any& get_value() override;
@@ -303,6 +306,7 @@ public:
class CheckBox : public Field {
using Field::Field;
+ bool m_is_na_val {false};
public:
CheckBox(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
CheckBox(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
@@ -316,11 +320,9 @@ public:
dynamic_cast<wxCheckBox*>(window)->SetValue(value);
m_disable_change_event = false;
}
- void set_value(const boost::any& value, bool change_event = false) {
- m_disable_change_event = !change_event;
- dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<bool>(value));
- m_disable_change_event = false;
- }
+ void set_value(const boost::any& value, bool change_event = false) override;
+ void set_last_meaningful_value() override;
+ void set_na_value() override;
boost::any& get_value() override;
void msw_rescale() override;
diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp
index 8f41ed5a3..826f2d6fc 100644
--- a/src/slic3r/GUI/GUI.cpp
+++ b/src/slic3r/GUI/GUI.cpp
@@ -148,6 +148,13 @@ void config_wizard(int reason)
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
{
try{
+
+ if (config.def()->get(opt_key)->type == coBools && config.def()->get(opt_key)->nullable) {
+ ConfigOptionBoolsNullable* vec_new = new ConfigOptionBoolsNullable{ boost::any_cast<unsigned char>(value) };
+ config.option<ConfigOptionBoolsNullable>(opt_key)->set_at(vec_new, opt_index, 0);
+ return;
+ }
+
switch (config.def()->get(opt_key)->type) {
case coFloatOrPercent:{
std::string str = boost::any_cast<std::string>(value);
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 9feca2f3d..656e07a0e 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -202,7 +202,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
// so we need a horizontal sizer to arrange these things
auto sizer = new wxBoxSizer(wxHORIZONTAL);
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
- sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT, 7);
+ sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
}
}
@@ -372,30 +372,10 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
auto option = m_options.at(opt_id).opt;
- // get value
-//! auto field_value = get_value(opt_id);
- if (option.gui_flags.compare("serialized")==0) {
- if (opt_index != -1) {
- // die "Can't set serialized option indexed value" ;
- }
- change_opt_value(*m_config, opt_key, value);
- }
- else {
- if (opt_index == -1) {
- // change_opt_value(*m_config, opt_key, field_value);
- //!? why field_value?? in this case changed value will be lose! No?
- change_opt_value(*m_config, opt_key, value);
- }
- else {
- change_opt_value(*m_config, opt_key, value, opt_index);
-// auto value = m_config->get($opt_key);
-// $value->[$opt_index] = $field_value;
-// $self->config->set($opt_key, $value);
- }
- }
+ change_opt_value(*m_config, opt_key, value, opt_index == -1 ? 0 : opt_index);
}
- OptionsGroup::on_change_OG(opt_id, value); //!? Why doing this
+ OptionsGroup::on_change_OG(opt_id, value);
}
void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key)
@@ -578,6 +558,34 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
boost::any ret;
wxString text_value = wxString("");
const ConfigOptionDef* opt = config.def()->get(opt_key);
+
+ if (opt->nullable)
+ {
+ switch (opt->type)
+ {
+ case coPercents:
+ case coFloats: {
+ if (config.option(opt_key)->is_nil())
+ ret = _(L("N/A"));
+ else {
+ double val = opt->type == coFloats ?
+ config.option<ConfigOptionFloatsNullable>(opt_key)->get_at(idx) :
+ config.option<ConfigOptionPercentsNullable>(opt_key)->get_at(idx);
+ ret = double_to_string(val); }
+ }
+ break;
+ case coBools:
+ ret = config.option<ConfigOptionBoolsNullable>(opt_key)->values[idx];
+ break;
+ case coInts:
+ ret = config.option<ConfigOptionIntsNullable>(opt_key)->get_at(idx);
+ break;
+ default:
+ break;
+ }
+ return ret;
+ }
+
switch (opt->type) {
case coFloatOrPercent:{
const auto &value = *config.option<ConfigOptionFloatOrPercent>(opt_key);
diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp
index d720787b6..cc3d89b1f 100644
--- a/src/slic3r/GUI/OptionsGroup.hpp
+++ b/src/slic3r/GUI/OptionsGroup.hpp
@@ -252,6 +252,9 @@ public:
Option option = get_option(title, idx);
return OptionsGroup::create_single_option_line(option);
}
+ Line create_single_option_line(const Option& option) const {
+ return OptionsGroup::create_single_option_line(option);
+ }
void append_single_option_line(const Option& option) {
OptionsGroup::append_single_option_line(option);
}
diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp
index e34c9be28..fa8b5baee 100644
--- a/src/slic3r/GUI/Preset.cpp
+++ b/src/slic3r/GUI/Preset.cpp
@@ -400,6 +400,10 @@ const std::vector<std::string>& Preset::filament_options()
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
"max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
"start_filament_gcode", "end_filament_gcode",
+ // Retract overrides
+ "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
+ "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe",
+ // Profile compatibility
"compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
};
return s_opts;
diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp
index 00c1f8168..7c9f7af4e 100644
--- a/src/slic3r/GUI/PresetBundle.cpp
+++ b/src/slic3r/GUI/PresetBundle.cpp
@@ -72,6 +72,8 @@ PresetBundle::PresetBundle() :
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values = { "" };
this->filaments.default_preset().compatible_printers_condition();
this->filaments.default_preset().inherits();
+ // Set all the nullable values to nils.
+ this->filaments.default_preset().config.null_nullables();
this->sla_materials.default_preset().config.optptr("sla_material_settings_id", true);
this->sla_materials.default_preset().compatible_printers_condition();
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index a00f7902f..9d7fc20a3 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1497,6 +1497,105 @@ void TabPrint::OnActivate()
Tab::OnActivate();
}
+void TabFilament::add_filament_overrides_page()
+{
+ PageShp page = add_options_page(_(L("Filament Overrides")), "wrench");
+ ConfigOptionsGroupShp optgroup = page->new_optgroup(_(L("Retraction")));
+
+ auto append_single_option_line = [optgroup, this](const std::string& opt_key, int opt_index)
+ {
+ Line line {"",""};
+ if (opt_key == "filament_retract_lift_above" || opt_key == "filament_retract_lift_below") {
+ Option opt = optgroup->get_option(opt_key);
+ opt.opt.label = opt.opt.full_label;
+ line = optgroup->create_single_option_line(opt);
+ }
+ else
+ line = optgroup->create_single_option_line(optgroup->get_option(opt_key));
+
+ line.near_label_widget = [this, optgroup, opt_key, opt_index](wxWindow* parent) {
+ wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, "");
+
+ check_box->Bind(wxEVT_CHECKBOX, [this, optgroup, opt_key, opt_index](wxCommandEvent& evt) {
+ const bool is_checked = evt.IsChecked();
+ Field* field = optgroup->get_fieldc(opt_key, opt_index);
+ if (field != nullptr) {
+ field->toggle(is_checked);
+ if (is_checked)
+ field->set_last_meaningful_value();
+ else
+ field->set_na_value();
+ }
+ }, check_box->GetId());
+
+ m_overrides_options[opt_key] = check_box;
+ return check_box;
+ };
+
+ optgroup->append_line(line);
+ };
+
+ const int extruder_idx = 0; // #ys_FIXME
+
+ for (const std::string opt_key : { "filament_retract_length",
+ "filament_retract_lift",
+ "filament_retract_lift_above",
+ "filament_retract_lift_below",
+ "filament_retract_speed",
+ "filament_deretract_speed",
+ "filament_retract_restart_extra",
+ "filament_retract_before_travel",
+ "filament_retract_layer_change",
+ "filament_wipe",
+ "filament_retract_before_wipe"
+ })
+ append_single_option_line(opt_key, extruder_idx);
+}
+
+void TabFilament::update_filament_overrides_page()
+{
+ const auto page_it = std::find_if(m_pages.begin(), m_pages.end(), [](const PageShp page) {return page->title() == _(L("Filament Overrides")); });
+ if (page_it == m_pages.end())
+ return;
+ PageShp page = *page_it;
+
+ const auto og_it = std::find_if(page->m_optgroups.begin(), page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) {return og->title == _(L("Retraction")); });
+ if (og_it == page->m_optgroups.end())
+ return;
+ ConfigOptionsGroupShp optgroup = *og_it;
+
+ std::vector<std::string> opt_keys = { "filament_retract_length",
+ "filament_retract_lift",
+ "filament_retract_lift_above",
+ "filament_retract_lift_below",
+ "filament_retract_speed",
+ "filament_deretract_speed",
+ "filament_retract_restart_extra",
+ "filament_retract_before_travel",
+ "filament_retract_layer_change",
+ "filament_wipe",
+ "filament_retract_before_wipe"
+ };
+
+ const int extruder_idx = 0; // #ys_FIXME
+
+ const bool have_retract_length = m_config->option("filament_retract_length")->is_nil() ||
+ m_config->opt_float("filament_retract_length", extruder_idx) > 0;
+
+ for (const std::string& opt_key : opt_keys)
+ {
+ bool is_checked = opt_key=="filament_retract_length" ? true : have_retract_length;
+ m_overrides_options[opt_key]->Enable(is_checked);
+
+ is_checked &= !m_config->option(opt_key)->is_nil();
+ m_overrides_options[opt_key]->SetValue(is_checked);
+
+ Field* field = optgroup->get_fieldc(opt_key, extruder_idx);
+ if (field != nullptr)
+ field->toggle(is_checked);
+ }
+}
+
void TabFilament::build()
{
m_presets = &m_preset_bundle->filaments;
@@ -1594,10 +1693,14 @@ void TabFilament::build()
};
optgroup->append_line(line);
+
+ add_filament_overrides_page();
+
+
const int gcode_field_height = 15; // 150
const int notes_field_height = 25; // 250
- page = add_options_page(_(L("Custom G-code")), "cog");
+ page = add_options_page(_(L("Custom G-code")), "cog");
optgroup = page->new_optgroup(_(L("Start G-code")), 0);
Option option = optgroup->get_option("start_filament_gcode");
option.opt.full_width = true;
@@ -1661,7 +1764,7 @@ void TabFilament::update()
return; // ys_FIXME
m_update_cnt++;
-// Freeze();
+
wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
m_cooling_description_line->SetText(text);
text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle));
@@ -1676,7 +1779,9 @@ void TabFilament::update()
for (auto el : { "min_fan_speed", "disable_fan_first_layers" })
get_field(el)->toggle(fan_always_on);
-// Thaw();
+
+ update_filament_overrides_page();
+
m_update_cnt--;
if (m_update_cnt == 0)
diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp
index 73b6bb08d..6ff76f5c4 100644
--- a/src/slic3r/GUI/Tab.hpp
+++ b/src/slic3r/GUI/Tab.hpp
@@ -337,6 +337,11 @@ class TabFilament : public Tab
{
ogStaticText* m_volumetric_speed_description_line;
ogStaticText* m_cooling_description_line;
+
+ void add_filament_overrides_page();
+ void update_filament_overrides_page();
+
+ std::map<std::string, wxCheckBox*> m_overrides_options;
public:
TabFilament(wxNotebook* parent) :
// Tab(parent, _(L("Filament Settings")), L("filament")) {}
diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp
index df5f48587..74c0f4b0c 100644
--- a/xs/xsp/Print.xsp
+++ b/xs/xsp/Print.xsp
@@ -75,7 +75,7 @@ _constant()
Ref<StaticPrintConfig> config()
%code%{ RETVAL = const_cast<GCodeConfig*>(static_cast<const GCodeConfig*>(&THIS->config())); %};
Ref<PlaceholderParser> placeholder_parser()
- %code%{ RETVAL = &THIS->placeholder_parser(); %};
+ %code%{ RETVAL = const_cast<PlaceholderParser*>(&THIS->placeholder_parser()); %};
Ref<ExtrusionEntityCollection> skirt()
%code%{ RETVAL = const_cast<ExtrusionEntityCollection*>(&THIS->skirt()); %};
Ref<ExtrusionEntityCollection> brim()