ENABLE_3DCONNEXION_DEVICES -> Hack for filtering out mouse wheel events coming from 3Dconnexion driver

This commit is contained in:
Enrico Turri 2019-10-08 08:44:50 +02:00
commit 8aa33a9e05
39 changed files with 1608 additions and 486 deletions

View file

@ -82,6 +82,29 @@ variants = default
technology = SLA technology = SLA
family = SL1 family = SL1
[default_filaments]
Generic PLA = 1
Generic PLA MMU2 = 1
Prusa PLA = 1
Prusa PLA MMU2 = 1
Prusament PLA = 1
Prusament PLA MMU2 = 1
[default_sla_materials]
Prusa Azure Blue Tough 0.05 = 1
Prusa Black Tough 0.05 = 1
Prusa Green Casting 0.05 = 1
Prusa Grey Tough 0.05 = 1
Prusa Maroon Tough 0.05 = 1
Prusa Orange Tough 0.025 = 1
Prusa Orange Tough 0.035 = 1
Prusa Orange Tough 0.05 = 1
Prusa Orange Tough 0.1 = 1
Prusa Pink Tough 0.05 = 1
Prusa Skin Tough 0.05 = 1
Prusa Transparent Red Tough 0.05 = 1
Prusa White Tough 0.05 = 1
# All presets starting with asterisk, for example *common*, are intermediate and they will # All presets starting with asterisk, for example *common*, are intermediate and they will
# not make it into the user interface. # not make it into the user interface.
@ -1128,6 +1151,7 @@ filament_density = 3.9
filament_colour = #804040 filament_colour = #804040
filament_max_volumetric_speed = 9 filament_max_volumetric_speed = 9
filament_notes = "List of materials tested with standard print settings:\n\nColorFabb bronzeFill\nColorFabb brassFill\nColorFabb steelFill\nColorFabb copperFill" filament_notes = "List of materials tested with standard print settings:\n\nColorFabb bronzeFill\nColorFabb brassFill\nColorFabb steelFill\nColorFabb copperFill"
filament_vendor = ColorFabb
[filament:ColorFabb HT] [filament:ColorFabb HT]
inherits = *PET* inherits = *PET*
@ -1145,11 +1169,13 @@ max_fan_speed = 20
min_fan_speed = 10 min_fan_speed = 10
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode"
temperature = 270 temperature = 270
filament_vendor = ColorFabb
[filament:ColorFabb PLA-PHA] [filament:ColorFabb PLA-PHA]
inherits = *PLA* inherits = *PLA*
filament_cost = 55.5 filament_cost = 55.5
filament_density = 1.24 filament_density = 1.24
filament_vendor = ColorFabb
[filament:ColorFabb woodFill] [filament:ColorFabb woodFill]
inherits = *PLA* inherits = *PLA*
@ -1163,6 +1189,7 @@ filament_max_volumetric_speed = 10
first_layer_temperature = 200 first_layer_temperature = 200
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 200 temperature = 200
filament_vendor = ColorFabb
[filament:ColorFabb corkFill] [filament:ColorFabb corkFill]
inherits = *PLA* inherits = *PLA*
@ -1175,6 +1202,7 @@ filament_max_volumetric_speed = 6
first_layer_temperature = 220 first_layer_temperature = 220
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 220 temperature = 220
filament_vendor = ColorFabb
[filament:ColorFabb XT] [filament:ColorFabb XT]
inherits = *PET* inherits = *PET*
@ -1184,6 +1212,7 @@ filament_density = 1.27
first_layer_bed_temperature = 90 first_layer_bed_temperature = 90
first_layer_temperature = 260 first_layer_temperature = 260
temperature = 270 temperature = 270
filament_vendor = ColorFabb
[filament:ColorFabb XT-CF20] [filament:ColorFabb XT-CF20]
inherits = *PET* inherits = *PET*
@ -1199,6 +1228,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el
temperature = 260 temperature = 260
filament_retract_length = nil filament_retract_length = nil
filament_retract_lift = 0.2 filament_retract_lift = 0.2
filament_vendor = ColorFabb
[filament:ColorFabb nGen] [filament:ColorFabb nGen]
inherits = *PET* inherits = *PET*
@ -1211,6 +1241,7 @@ filament_type = NGEN
first_layer_temperature = 240 first_layer_temperature = 240
max_fan_speed = 35 max_fan_speed = 35
min_fan_speed = 20 min_fan_speed = 20
filament_vendor = ColorFabb
[filament:ColorFabb nGen flex] [filament:ColorFabb nGen flex]
inherits = *FLEX* inherits = *FLEX*
@ -1231,12 +1262,14 @@ temperature = 260
filament_retract_length = nil filament_retract_length = nil
filament_retract_lift = 0 filament_retract_lift = 0
compatible_printers_condition = nozzle_diameter[0]>0.35 and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) compatible_printers_condition = nozzle_diameter[0]>0.35 and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material)
filament_vendor = ColorFabb
[filament:E3D Edge] [filament:E3D Edge]
inherits = *PET* inherits = *PET*
filament_cost = 56.9 filament_cost = 56.9
filament_density = 1.26 filament_density = 1.26
filament_type = EDGE filament_type = EDGE
filament_vendor = E3D
[filament:E3D PC-ABS] [filament:E3D PC-ABS]
inherits = *ABS* inherits = *ABS*
@ -1245,6 +1278,7 @@ filament_type = PC
filament_density = 1.05 filament_density = 1.05
first_layer_temperature = 270 first_layer_temperature = 270
temperature = 270 temperature = 270
filament_vendor = E3D
[filament:Fillamentum ABS] [filament:Fillamentum ABS]
inherits = *ABS* inherits = *ABS*
@ -1252,6 +1286,7 @@ filament_cost = 32.4
filament_density = 1.04 filament_density = 1.04
first_layer_temperature = 240 first_layer_temperature = 240
temperature = 240 temperature = 240
filament_vendor = Fillamentum
[filament:Fillamentum ASA] [filament:Fillamentum ASA]
inherits = *ABS* inherits = *ABS*
@ -1266,6 +1301,7 @@ slowdown_below_layer_time = 15
first_layer_temperature = 265 first_layer_temperature = 265
temperature = 265 temperature = 265
filament_type = ASA filament_type = ASA
filament_vendor = Fillamentum
[filament:Prusament ASA] [filament:Prusament ASA]
inherits = *ABS* inherits = *ABS*
@ -1296,6 +1332,7 @@ first_layer_temperature = 275
max_fan_speed = 50 max_fan_speed = 50
min_fan_speed = 50 min_fan_speed = 50
temperature = 275 temperature = 275
filament_vendor = Fillamentum
[filament:Fillamentum Timberfill] [filament:Fillamentum Timberfill]
inherits = *PLA* inherits = *PLA*
@ -1309,24 +1346,28 @@ filament_max_volumetric_speed = 10
first_layer_temperature = 190 first_layer_temperature = 190
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 190 temperature = 190
filament_vendor = Fillamentum
[filament:Generic ABS] [filament:Generic ABS]
inherits = *ABS* inherits = *ABS*
filament_cost = 27.82 filament_cost = 27.82
filament_density = 1.04 filament_density = 1.04
filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS" filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS"
filament_vendor = Generic
[filament:Generic PET] [filament:Generic PET]
inherits = *PET* inherits = *PET*
filament_cost = 27.82 filament_cost = 27.82
filament_density = 1.27 filament_density = 1.27
filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladec PETG" filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladec PETG"
filament_vendor = Generic
[filament:Generic PLA] [filament:Generic PLA]
inherits = *PLA* inherits = *PLA*
filament_cost = 25.4 filament_cost = 25.4
filament_density = 1.24 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\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
filament_vendor = Generic
[filament:Generic FLEX] [filament:Generic FLEX]
inherits = *FLEX* inherits = *FLEX*
@ -1347,6 +1388,7 @@ filament_colour = #3A80CA
first_layer_bed_temperature = 100 first_layer_bed_temperature = 100
first_layer_temperature = 270 first_layer_temperature = 270
temperature = 270 temperature = 270
filament_vendor = Polymaker
[filament:PrimaSelect PVA+] [filament:PrimaSelect PVA+]
inherits = *PLA* inherits = *PLA*
@ -1363,12 +1405,14 @@ filament_type = PVA
first_layer_temperature = 195 first_layer_temperature = 195
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 195 temperature = 195
filament_vendor = PrimaSelect
[filament:Prusa ABS] [filament:Prusa ABS]
inherits = *ABS* inherits = *ABS*
filament_cost = 27.82 filament_cost = 27.82
filament_density = 1.08 filament_density = 1.08
filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS" filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS"
filament_vendor = Prusa
[filament:*ABS MMU2*] [filament:*ABS MMU2*]
inherits = Prusa ABS inherits = Prusa ABS
@ -1385,6 +1429,7 @@ filament_unloading_speed = 20
[filament:Generic ABS MMU2] [filament:Generic ABS MMU2]
inherits = *ABS MMU2* inherits = *ABS MMU2*
filament_vendor = Generic
[filament:Prusament ASA MMU2] [filament:Prusament ASA MMU2]
inherits = *ABS MMU2* inherits = *ABS MMU2*
@ -1410,6 +1455,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el
[filament:Prusa ABS MMU2] [filament:Prusa ABS MMU2]
inherits = *ABS MMU2* inherits = *ABS MMU2*
filament_vendor = Prusa
[filament:Prusa HIPS] [filament:Prusa HIPS]
inherits = *ABS* inherits = *ABS*
@ -1428,6 +1474,7 @@ max_fan_speed = 20
min_fan_speed = 20 min_fan_speed = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 220 temperature = 220
filament_vendor = Prusa
[filament:Prusa PET] [filament:Prusa PET]
inherits = *PET* inherits = *PET*
@ -1435,6 +1482,7 @@ filament_cost = 27.82
filament_density = 1.27 filament_density = 1.27
filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG"
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
filament_vendor = Prusa
[filament:Prusament PETG] [filament:Prusament PETG]
inherits = *PET* inherits = *PET*
@ -1444,12 +1492,14 @@ filament_cost = 24.99
filament_density = 1.27 filament_density = 1.27
filament_type = PETG filament_type = PETG
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
filament_vendor = Prusa
[filament:Prusa PET 0.6 nozzle] [filament:Prusa PET 0.6 nozzle]
inherits = *PET06* inherits = *PET06*
filament_cost = 27.82 filament_cost = 27.82
filament_density = 1.27 filament_density = 1.27
filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG"
filament_vendor = Prusa
[filament:Prusament PETG 0.6 nozzle] [filament:Prusament PETG 0.6 nozzle]
inherits = *PET06* inherits = *PET06*
@ -1458,6 +1508,7 @@ temperature = 250
filament_cost = 24.99 filament_cost = 24.99
filament_density = 1.27 filament_density = 1.27
filament_type = PETG filament_type = PETG
filament_vendor = Prusa
[filament:*PET MMU2*] [filament:*PET MMU2*]
inherits = Prusa PET inherits = Prusa PET
@ -1485,9 +1536,11 @@ filament_max_volumetric_speed = 13
[filament:Generic PET MMU2] [filament:Generic PET MMU2]
inherits = *PET MMU2* inherits = *PET MMU2*
filament_vendor = Generic
[filament:Prusa PET MMU2] [filament:Prusa PET MMU2]
inherits = *PET MMU2* inherits = *PET MMU2*
filament_vendor = Prusa
[filament:Prusament PETG MMU2] [filament:Prusament PETG MMU2]
inherits = *PET MMU2* inherits = *PET MMU2*
@ -1498,16 +1551,19 @@ inherits = *PET MMU2 06*
[filament:Prusa PET MMU2 0.6 nozzle] [filament:Prusa PET MMU2 0.6 nozzle]
inherits = *PET MMU2 06* inherits = *PET MMU2 06*
filament_vendor = Prusa
[filament:Prusament PETG MMU2 0.6 nozzle] [filament:Prusament PETG MMU2 0.6 nozzle]
inherits = *PET MMU2 06* inherits = *PET MMU2 06*
filament_type = PETG filament_type = PETG
filament_vendor = Prusa
[filament:Prusa PLA] [filament:Prusa PLA]
inherits = *PLA* inherits = *PLA*
filament_cost = 25.4 filament_cost = 25.4
filament_density = 1.24 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\nFiberlogy PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nAmazonBasics PLA" 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_vendor = Prusa
[filament:Prusament PLA] [filament:Prusament PLA]
inherits = *PLA* inherits = *PLA*
@ -1515,6 +1571,7 @@ temperature = 215
filament_cost = 24.99 filament_cost = 24.99
filament_density = 1.24 filament_density = 1.24
filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa" filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa"
filament_vendor = Prusa
[filament:*PLA MMU2*] [filament:*PLA MMU2*]
inherits = Prusa PLA inherits = Prusa PLA
@ -1534,18 +1591,22 @@ filament_unloading_speed_start = 100
[filament:Generic PLA MMU2] [filament:Generic PLA MMU2]
inherits = *PLA MMU2* inherits = *PLA MMU2*
filament_vendor = Generic
[filament:Prusa PLA MMU2] [filament:Prusa PLA MMU2]
inherits = *PLA MMU2* inherits = *PLA MMU2*
filament_vendor = Prusa
[filament:Prusament PLA MMU2] [filament:Prusament PLA MMU2]
inherits = *PLA MMU2* inherits = *PLA MMU2*
filament_vendor = Prusa
[filament:SemiFlex or Flexfill 98A] [filament:SemiFlex or Flexfill 98A]
inherits = *FLEX* inherits = *FLEX*
filament_cost = 82 filament_cost = 82
filament_density = 1.22 filament_density = 1.22
filament_max_volumetric_speed = 1.35 filament_max_volumetric_speed = 1.35
filament_vendor = Flexfill
[filament:Taulman Bridge] [filament:Taulman Bridge]
inherits = *common* inherits = *common*
@ -1567,6 +1628,7 @@ max_fan_speed = 5
min_fan_speed = 0 min_fan_speed = 0
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 250 temperature = 250
filament_vendor = Taulman
[filament:Taulman T-Glase] [filament:Taulman T-Glase]
inherits = *PET* inherits = *PET*
@ -1580,6 +1642,7 @@ first_layer_temperature = 240
max_fan_speed = 5 max_fan_speed = 5
min_fan_speed = 0 min_fan_speed = 0
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
filament_vendor = Taulman
[filament:Verbatim BVOH] [filament:Verbatim BVOH]
inherits = *common* inherits = *common*
@ -1603,6 +1666,7 @@ max_fan_speed = 100
min_fan_speed = 100 min_fan_speed = 100
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 210 temperature = 210
filament_vendor = Verbatim
[filament:Verbatim BVOH MMU2] [filament:Verbatim BVOH MMU2]
inherits = Verbatim BVOH inherits = Verbatim BVOH
@ -1622,6 +1686,7 @@ filament_unload_time = 12
filament_unloading_speed = 20 filament_unloading_speed = 20
filament_unloading_speed_start = 100 filament_unloading_speed_start = 100
filament_loading_speed_start = 19 filament_loading_speed_start = 19
filament_vendor = Verbatim
[filament:PrimaSelect PVA+ MMU2] [filament:PrimaSelect PVA+ MMU2]
inherits = *common* inherits = *common*
@ -1660,6 +1725,7 @@ min_print_speed = 15
slowdown_below_layer_time = 20 slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
temperature = 195 temperature = 195
filament_vendor = PrimaSelect
[filament:Verbatim PP] [filament:Verbatim PP]
inherits = *common* inherits = *common*
@ -1682,6 +1748,7 @@ max_fan_speed = 100
min_fan_speed = 100 min_fan_speed = 100
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 220 temperature = 220
filament_vendor = Verbatim
## Filaments MMU1 ## Filaments MMU1
@ -1899,9 +1966,11 @@ exposure_time = 6
initial_exposure_time = 40 initial_exposure_time = 40
[sla_material:BlueCast Keramaster Dental 0.025] [sla_material:BlueCast Keramaster Dental 0.025]
material_type = Dental
inherits = *common 0.025* inherits = *common 0.025*
exposure_time = 6 exposure_time = 6
initial_exposure_time = 45 initial_exposure_time = 45
material_vendor = Bluecast
[sla_material:BlueCast X10 0.025] [sla_material:BlueCast X10 0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -1912,6 +1981,7 @@ initial_exposure_time = 100
inherits = *common 0.025* inherits = *common 0.025*
exposure_time = 6 exposure_time = 6
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
[sla_material:Prusa Grey Tough 0.025] [sla_material:Prusa Grey Tough 0.025]
inherits = *common 0.025* inherits = *common 0.025*
@ -1964,31 +2034,38 @@ initial_exposure_time = 35
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7 exposure_time = 7
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Bluecast
[sla_material:BlueCast Keramaster 0.05] [sla_material:BlueCast Keramaster 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 8 exposure_time = 8
initial_exposure_time = 45 initial_exposure_time = 45
material_vendor = Bluecast
[sla_material:BlueCast Keramaster Dental 0.05] [sla_material:BlueCast Keramaster Dental 0.05]
material_type = Dental
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7 exposure_time = 7
initial_exposure_time = 50 initial_exposure_time = 50
material_vendor = Bluecast
[sla_material:BlueCast LCD-DLP Original 0.05] [sla_material:BlueCast LCD-DLP Original 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 10 exposure_time = 10
initial_exposure_time = 60 initial_exposure_time = 60
material_vendor = Bluecast
[sla_material:BlueCast Phrozen Wax 0.05] [sla_material:BlueCast Phrozen Wax 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 16 exposure_time = 16
initial_exposure_time = 50 initial_exposure_time = 50
material_vendor = Bluecast
[sla_material:BlueCast S+ 0.05] [sla_material:BlueCast S+ 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 9 exposure_time = 9
initial_exposure_time = 45 initial_exposure_time = 45
material_vendor = Bluecast
[sla_material:BlueCast X10 0.05] [sla_material:BlueCast X10 0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -1999,26 +2076,31 @@ initial_exposure_time = 100
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 6 exposure_time = 6
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = Monocure
[sla_material:Monocure 3D Blue Rapid Resin 0.05] [sla_material:Monocure 3D Blue Rapid Resin 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7 exposure_time = 7
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = Monocure
[sla_material:Monocure 3D Clear Rapid Resin 0.05] [sla_material:Monocure 3D Clear Rapid Resin 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 8 exposure_time = 8
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = Monocure
[sla_material:Monocure 3D Grey Rapid Resin 0.05] [sla_material:Monocure 3D Grey Rapid Resin 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 10 exposure_time = 10
initial_exposure_time = 30 initial_exposure_time = 30
material_vendor = Monocure
[sla_material:Monocure 3D White Rapid Resin 0.05] [sla_material:Monocure 3D White Rapid Resin 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7 exposure_time = 7
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = Monocure
[sla_material:3DM-HTR140 (high temperature) 0.05] [sla_material:3DM-HTR140 (high temperature) 0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -2034,36 +2116,43 @@ initial_exposure_time = 25
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 20 exposure_time = 20
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = 3DM
[sla_material:3DM-DENT 0.05] [sla_material:3DM-DENT 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7 exposure_time = 7
initial_exposure_time = 45 initial_exposure_time = 45
material_vendor = 3DM
[sla_material:3DM-HR Green 0.05] [sla_material:3DM-HR Green 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 15 exposure_time = 15
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = 3DM
[sla_material:3DM-HR Red Wine 0.05] [sla_material:3DM-HR Red Wine 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 9 exposure_time = 9
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = 3DM
[sla_material:3DM-XPRO White 0.05] [sla_material:3DM-XPRO White 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 9 exposure_time = 9
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = 3DM
[sla_material:FTD Ash Grey 0.05] [sla_material:FTD Ash Grey 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 9 exposure_time = 9
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = FTD
[sla_material:Harz Labs Model Resin Cherry 0.05] [sla_material:Harz Labs Model Resin Cherry 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 8 exposure_time = 8
initial_exposure_time = 45 initial_exposure_time = 45
material_vendor = Harz Labs
[sla_material:Photocentric Hard Grey 0.05] [sla_material:Photocentric Hard Grey 0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -2116,6 +2205,7 @@ initial_exposure_time = 35
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 13 exposure_time = 13
initial_exposure_time = 40 initial_exposure_time = 40
material_vendor = Prusa
## [sla_material:Prusa Yellow Solid 0.05] ## [sla_material:Prusa Yellow Solid 0.05]
## inherits = *common 0.05* ## inherits = *common 0.05*
@ -2126,6 +2216,7 @@ initial_exposure_time = 40
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7.5 exposure_time = 7.5
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
## [sla_material:Prusa Transparent Green Tough 0.05] ## [sla_material:Prusa Transparent Green Tough 0.05]
## inherits = *common 0.05* ## inherits = *common 0.05*
@ -2136,21 +2227,25 @@ initial_exposure_time = 35
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 6 exposure_time = 6
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
[sla_material:Prusa Maroon Tough 0.05] [sla_material:Prusa Maroon Tough 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 7.5 exposure_time = 7.5
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
[sla_material:Prusa Pink Tough 0.05] [sla_material:Prusa Pink Tough 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 8 exposure_time = 8
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
[sla_material:Prusa Azure Blue Tough 0.05] [sla_material:Prusa Azure Blue Tough 0.05]
inherits = *common 0.05* inherits = *common 0.05*
exposure_time = 8 exposure_time = 8
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
[sla_material:Prusa Transparent Tough 0.05] [sla_material:Prusa Transparent Tough 0.05]
inherits = *common 0.05* inherits = *common 0.05*
@ -2193,6 +2288,7 @@ initial_exposure_time = 15
inherits = *common 0.035* inherits = *common 0.035*
exposure_time = 6 exposure_time = 6
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
########### Materials 0.1 ########### Materials 0.1
@ -2235,6 +2331,7 @@ initial_exposure_time = 55
inherits = *common 0.1* inherits = *common 0.1*
exposure_time = 8 exposure_time = 8
initial_exposure_time = 35 initial_exposure_time = 35
material_vendor = Prusa
[sla_material:Prusa Green Casting 0.1] [sla_material:Prusa Green Casting 0.1]
inherits = *common 0.1* inherits = *common 0.1*

View file

@ -49,91 +49,84 @@ using BottomLeftPlacer = placers::_BottomLeftPlacer<PolygonImpl>;
extern template class Nester<NfpPlacer, FirstFitSelection>; extern template class Nester<NfpPlacer, FirstFitSelection>;
extern template class Nester<BottomLeftPlacer, FirstFitSelection>; extern template class Nester<BottomLeftPlacer, FirstFitSelection>;
extern template PackGroup Nester<NfpPlacer, FirstFitSelection>::execute( extern template std::size_t Nester<NfpPlacer, FirstFitSelection>::execute(
std::vector<Item>::iterator, std::vector<Item>::iterator); std::vector<Item>::iterator, std::vector<Item>::iterator);
extern template PackGroup Nester<BottomLeftPlacer, FirstFitSelection>::execute( extern template std::size_t Nester<BottomLeftPlacer, FirstFitSelection>::execute(
std::vector<Item>::iterator, std::vector<Item>::iterator); std::vector<Item>::iterator, std::vector<Item>::iterator);
#endif #endif
template<class Placer = NfpPlacer, template<class Placer = NfpPlacer, class Selector = FirstFitSelection>
class Selector = FirstFitSelection, struct NestConfig {
class Iterator = std::vector<Item>::iterator> typename Placer::Config placer_config;
void nest(Iterator from, Iterator to, typename Selector::Config selector_config;
const typename Placer::BinType& bin, using Placement = typename Placer::Config;
Coord dist = 0, using Selection = typename Selector::Config;
const typename Placer::Config& pconf = {},
const typename Selector::Config& sconf = {}) NestConfig() = default;
{ NestConfig(const typename Placer::Config &cfg) : placer_config{cfg} {}
_Nester<Placer, Selector> nester(bin, dist, pconf, sconf); NestConfig(const typename Selector::Config &cfg) : selector_config{cfg} {}
nester.execute(from, to); NestConfig(const typename Placer::Config & pcfg,
} const typename Selector::Config &scfg)
: placer_config{pcfg}, selector_config{scfg} {}
};
struct NestControl {
ProgressFunction progressfn;
StopCondition stopcond = []{ return false; };
NestControl() = default;
NestControl(ProgressFunction pr) : progressfn{std::move(pr)} {}
NestControl(StopCondition sc) : stopcond{std::move(sc)} {}
NestControl(ProgressFunction pr, StopCondition sc)
: progressfn{std::move(pr)}, stopcond{std::move(sc)}
{}
};
template<class Placer = NfpPlacer, template<class Placer = NfpPlacer,
class Selector = FirstFitSelection, class Selector = FirstFitSelection,
class Iterator = std::vector<Item>::iterator> class Iterator = std::vector<Item>::iterator>
void nest(Iterator from, Iterator to, std::size_t nest(Iterator from, Iterator to,
const typename Placer::BinType& bin, const typename Placer::BinType & bin,
ProgressFunction prg, Coord dist = 0,
StopCondition scond = []() { return false; }, const NestConfig<Placer, Selector> &cfg = {},
Coord dist = 0, NestControl ctl = {})
const typename Placer::Config& pconf = {},
const typename Selector::Config& sconf = {})
{ {
_Nester<Placer, Selector> nester(bin, dist, pconf, sconf); _Nester<Placer, Selector> nester{bin, dist, cfg.placer_config, cfg.selector_config};
if(prg) nester.progressIndicator(prg); if(ctl.progressfn) nester.progressIndicator(ctl.progressfn);
if(scond) nester.stopCondition(scond); if(ctl.stopcond) nester.stopCondition(ctl.stopcond);
nester.execute(from, to); return nester.execute(from, to);
} }
#ifdef LIBNEST2D_STATIC #ifdef LIBNEST2D_STATIC
extern template class Nester<NfpPlacer, FirstFitSelection>; extern template class Nester<NfpPlacer, FirstFitSelection>;
extern template class Nester<BottomLeftPlacer, FirstFitSelection>; extern template class Nester<BottomLeftPlacer, FirstFitSelection>;
extern template std::size_t nest(std::vector<Item>::iterator from,
extern template void nest(std::vector<Item>::iterator from, std::vector<Item>::iterator from to,
std::vector<Item>::iterator to, const Box & bin,
const Box& bin, Coord dist,
Coord dist = 0, const NestConfig<NfpPlacer, FirstFitSelection> &cfg,
const NfpPlacer::Config& pconf, NestControl ctl);
const FirstFitSelection::Config& sconf); extern template std::size_t nest(std::vector<Item>::iterator from,
std::vector<Item>::iterator from to,
extern template void nest(std::vector<Item>::iterator from, const Box & bin,
std::vector<Item>::iterator to, Coord dist,
const Box& bin, const NestConfig<BottomLeftPlacer, FirstFitSelection> &cfg,
ProgressFunction prg, NestControl ctl);
StopCondition scond,
Coord dist = 0,
const NfpPlacer::Config& pconf,
const FirstFitSelection::Config& sconf);
#endif #endif
template<class Placer = NfpPlacer, template<class Placer = NfpPlacer,
class Selector = FirstFitSelection, class Selector = FirstFitSelection,
class Container = std::vector<Item>> class Container = std::vector<Item>>
void nest(Container&& cont, std::size_t nest(Container&& cont,
const typename Placer::BinType& bin, const typename Placer::BinType & bin,
Coord dist = 0, Coord dist = 0,
const typename Placer::Config& pconf = {}, const NestConfig<Placer, Selector> &cfg = {},
const typename Selector::Config& sconf = {}) NestControl ctl = {})
{ {
nest<Placer, Selector>(cont.begin(), cont.end(), bin, dist, pconf, sconf); return nest<Placer, Selector>(cont.begin(), cont.end(), bin, dist, cfg, ctl);
}
template<class Placer = NfpPlacer,
class Selector = FirstFitSelection,
class Container = std::vector<Item>>
void nest(Container&& cont,
const typename Placer::BinType& bin,
ProgressFunction prg,
StopCondition scond = []() { return false; },
Coord dist = 0,
const typename Placer::Config& pconf = {},
const typename Selector::Config& sconf = {})
{
nest<Placer, Selector>(cont.begin(), cont.end(), bin, prg, scond, dist,
pconf, sconf);
} }
} }

View file

@ -129,8 +129,12 @@ public:
sh_(sl::create<RawShape>(std::move(contour), std::move(holes))) {} sh_(sl::create<RawShape>(std::move(contour), std::move(holes))) {}
inline bool isFixed() const noexcept { return fixed_; } inline bool isFixed() const noexcept { return fixed_; }
inline void markAsFixed(bool fixed = true) { fixed_ = fixed; } inline void markAsFixedInBin(int binid)
{
fixed_ = binid >= 0;
binid_ = binid;
}
inline void binId(int idx) { binid_ = idx; } inline void binId(int idx) { binid_ = idx; }
inline int binId() const noexcept { return binid_; } inline int binId() const noexcept { return binid_; }
@ -748,6 +752,7 @@ template<class PlacementStrategy, class SelectionStrategy >
class _Nester { class _Nester {
using TSel = SelectionStrategyLike<SelectionStrategy>; using TSel = SelectionStrategyLike<SelectionStrategy>;
TSel selector_; TSel selector_;
public: public:
using Item = typename PlacementStrategy::Item; using Item = typename PlacementStrategy::Item;
using ShapeType = typename Item::ShapeType; using ShapeType = typename Item::ShapeType;
@ -824,7 +829,7 @@ public:
* the selection algorithm. * the selection algorithm.
*/ */
template<class It> template<class It>
inline ItemIteratorOnly<It, void> execute(It from, It to) inline ItemIteratorOnly<It, size_t> execute(It from, It to)
{ {
auto infl = static_cast<Coord>(std::ceil(min_obj_distance_/2.0)); auto infl = static_cast<Coord>(std::ceil(min_obj_distance_/2.0));
if(infl > 0) std::for_each(from, to, [this, infl](Item& item) { if(infl > 0) std::for_each(from, to, [this, infl](Item& item) {
@ -837,6 +842,8 @@ public:
if(min_obj_distance_ > 0) std::for_each(from, to, [infl](Item& item) { if(min_obj_distance_ > 0) std::for_each(from, to, [infl](Item& item) {
item.inflate(-infl); item.inflate(-infl);
}); });
return selector_.getResult().size();
} }
/// Set a progress indicator function object for the selector. /// Set a progress indicator function object for the selector.

View file

@ -1122,8 +1122,6 @@ private:
sl::rotate(sh, item.rotation()); sl::rotate(sh, item.rotation());
Box bb = sl::boundingBox(sh); Box bb = sl::boundingBox(sh);
bb.minCorner() += item.translation();
bb.maxCorner() += item.translation();
Vertex ci, cb; Vertex ci, cb;
auto bbin = sl::boundingBox(bin_); auto bbin = sl::boundingBox(bin_);

View file

@ -5,19 +5,17 @@ namespace libnest2d {
template class Nester<NfpPlacer, FirstFitSelection>; template class Nester<NfpPlacer, FirstFitSelection>;
template class Nester<BottomLeftPlacer, FirstFitSelection>; template class Nester<BottomLeftPlacer, FirstFitSelection>;
template PackGroup nest(std::vector<Item>::iterator from, template std::size_t nest(std::vector<Item>::iterator from,
std::vector<Item>::iterator to, std::vector<Item>::iterator from to,
const Box& bin, const Box & bin,
Coord dist = 0, Coord dist,
const NfpPlacer::Config& pconf, const NestConfig<NfpPlacer, FirstFitSelection> &cfg,
const FirstFitSelection::Config& sconf); NestControl ctl);
template PackGroup nest(std::vector<Item>::iterator from, template std::size_t nest(std::vector<Item>::iterator from,
std::vector<Item>::iterator to, std::vector<Item>::iterator from to,
const Box& bin, const Box & bin,
ProgressFunction prg, Coord dist,
StopCondition scond, const NestConfig<BottomLeftPlacer, FirstFitSelection> &cfg,
Coord dist = 0, NestControl ctl);
const NfpPlacer::Config& pconf,
const FirstFitSelection::Config& sconf);
} }

View file

@ -375,7 +375,7 @@ public:
for(unsigned idx = 0; idx < fixeditems.size(); ++idx) { for(unsigned idx = 0; idx < fixeditems.size(); ++idx) {
Item& itm = fixeditems[idx]; Item& itm = fixeditems[idx];
itm.markAsFixed(); itm.markAsFixedInBin(0);
} }
m_pck.configure(m_pconf); m_pck.configure(m_pconf);

View file

@ -749,6 +749,10 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionStrings { "" }); def->set_default_value(new ConfigOptionStrings { "" });
def->cli = ConfigOptionDef::nocli; def->cli = ConfigOptionDef::nocli;
def = this->add("filament_vendor", coString);
def->set_default_value(new ConfigOptionString(L("(Unknown)")));
def->cli = ConfigOptionDef::nocli;
def = this->add("fill_angle", coFloat); def = this->add("fill_angle", coFloat);
def->label = L("Fill angle"); def->label = L("Fill angle");
def->category = L("Infill"); def->category = L("Infill");
@ -2398,6 +2402,18 @@ void PrintConfigDef::init_sla_params()
// SLA Material settings. // SLA Material settings.
def = this->add("material_type", coString);
def->label = L("SLA material type");
def->tooltip = L("SLA material type");
def->gui_type = "f_enum_open"; // TODO: ???
def->gui_flags = "show_value";
def->enum_values.push_back("Tough");
def->enum_values.push_back("Flexible");
def->enum_values.push_back("Casting");
def->enum_values.push_back("Dental");
def->enum_values.push_back("Heat-resistant");
def->set_default_value(new ConfigOptionString("Tough"));
def = this->add("initial_layer_height", coFloat); def = this->add("initial_layer_height", coFloat);
def->label = L("Initial layer height"); def->label = L("Initial layer height");
def->tooltip = L("Initial layer height"); def->tooltip = L("Initial layer height");
@ -2475,6 +2491,10 @@ void PrintConfigDef::init_sla_params()
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString("")); def->set_default_value(new ConfigOptionString(""));
def = this->add("material_vendor", coString);
def->set_default_value(new ConfigOptionString(L("(Unknown)")));
def->cli = ConfigOptionDef::nocli;
def = this->add("default_sla_material_profile", coString); def = this->add("default_sla_material_profile", coString);
def->label = L("Default SLA material profile"); def->label = L("Default SLA material profile");
def->tooltip = L("Default print profile associated with the current printer profile. " def->tooltip = L("Default print profile associated with the current printer profile. "

View file

@ -52,6 +52,14 @@ enum FilamentType {
}; };
*/ */
enum SLAMaterial {
slamTough,
slamFlex,
slamCasting,
slamDental,
slamHeatResistant,
};
enum SLADisplayOrientation { enum SLADisplayOrientation {
sladoLandscape, sladoLandscape,
sladoPortrait sladoPortrait

View file

@ -46,7 +46,7 @@ time_t str2time(const std::string &str, TimeZone zone, TimeFormat fmt);
inline std::string iso_utc_timestamp(time_t t) inline std::string iso_utc_timestamp(time_t t)
{ {
return time2str(t, TimeZone::utc, TimeFormat::gcode); return time2str(t, TimeZone::utc, TimeFormat::iso8601Z);
} }
inline std::string iso_utc_timestamp() inline std::string iso_utc_timestamp()

View file

@ -393,9 +393,9 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot:
// Read the active config bundle, parse the config version. // Read the active config bundle, parse the config version.
PresetBundle bundle; PresetBundle bundle;
bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY); bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
for (const VendorProfile &vp : bundle.vendors) for (const auto &vp : bundle.vendors)
if (vp.id == cfg.name) if (vp.second.id == cfg.name)
cfg.version.config_version = vp.config_version; cfg.version.config_version = vp.second.config_version;
// Fill-in the min/max slic3r version from the config index, if possible. // Fill-in the min/max slic3r version from the config index, if possible.
try { try {
// Load the config index for the vendor. // Load the config index for the vendor.

View file

@ -28,6 +28,9 @@ static const std::string VENDOR_PREFIX = "vendor:";
static const std::string MODEL_PREFIX = "model:"; static const std::string MODEL_PREFIX = "model:";
static const std::string VERSION_CHECK_URL = "https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaSlicer.version"; static const std::string VERSION_CHECK_URL = "https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaSlicer.version";
const std::string AppConfig::SECTION_FILAMENTS = "filaments";
const std::string AppConfig::SECTION_MATERIALS = "sla_materials";
void AppConfig::reset() void AppConfig::reset()
{ {
m_storage.clear(); m_storage.clear();

View file

@ -80,6 +80,12 @@ public:
} }
} }
bool has_section(const std::string &section) const
{ return m_storage.find(section) != m_storage.end(); }
const std::map<std::string, std::string>& get_section(const std::string &section) const
{ return m_storage.find(section)->second; }
void set_section(const std::string &section, const std::map<std::string, std::string>& data)
{ m_storage[section] = data; }
void clear_section(const std::string &section) void clear_section(const std::string &section)
{ m_storage[section].clear(); } { m_storage[section].clear(); }
@ -131,6 +137,9 @@ public:
bool get_mouse_device_rotation_speed(const std::string& name, float& rotation_speed); bool get_mouse_device_rotation_speed(const std::string& name, float& rotation_speed);
#endif // ENABLE_3DCONNEXION_DEVICES #endif // ENABLE_3DCONNEXION_DEVICES
static const std::string SECTION_FILAMENTS;
static const std::string SECTION_MATERIALS;
private: private:
// Map of section, name -> value // Map of section, name -> value
std::map<std::string, std::map<std::string, std::string>> m_storage; std::map<std::string, std::map<std::string, std::string>> m_storage;

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,15 @@ public:
RR_USER, // User requested the Wizard from the menus RR_USER, // User requested the Wizard from the menus
}; };
ConfigWizard(wxWindow *parent, RunReason run_reason); // What page should wizard start on
enum StartPage {
SP_WELCOME,
SP_PRINTERS,
SP_FILAMENTS,
SP_MATERIALS,
};
ConfigWizard(wxWindow *parent);
ConfigWizard(ConfigWizard &&) = delete; ConfigWizard(ConfigWizard &&) = delete;
ConfigWizard(const ConfigWizard &) = delete; ConfigWizard(const ConfigWizard &) = delete;
ConfigWizard &operator=(ConfigWizard &&) = delete; ConfigWizard &operator=(ConfigWizard &&) = delete;
@ -34,7 +42,7 @@ public:
~ConfigWizard(); ~ConfigWizard();
// Run the Wizard. Return whether it was completed. // Run the Wizard. Return whether it was completed.
bool run(PresetBundle *preset_bundle, const PresetUpdater *updater); bool run(RunReason reason, StartPage start_page = SP_WELCOME);
static const wxString& name(const bool from_menu = false); static const wxString& name(const bool from_menu = false);

View file

@ -15,11 +15,14 @@
#include <wx/choice.h> #include <wx/choice.h>
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <wx/listbox.h>
#include <wx/checklst.h>
#include <wx/radiobut.h>
#include "libslic3r/PrintConfig.hpp" #include "libslic3r/PrintConfig.hpp"
#include "slic3r/Utils/PresetUpdater.hpp" #include "slic3r/Utils/PresetUpdater.hpp"
#include "AppConfig.hpp" #include "AppConfig.hpp"
#include "Preset.hpp" #include "PresetBundle.hpp"
#include "BedShapeDialog.hpp" #include "BedShapeDialog.hpp"
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
@ -41,6 +44,76 @@ enum {
ROW_SPACING = 75, ROW_SPACING = 75,
}; };
// Configuration data structures extensions needed for the wizard
enum Technology {
// Bitflag equivalent of PrinterTechnology
T_FFF = 0x1,
T_SLA = 0x2,
T_ANY = ~0,
};
struct Materials
{
Technology technology;
std::set<const Preset*> presets;
std::set<std::string> types;
Materials(Technology technology) : technology(technology) {}
void push(const Preset *preset);
void clear();
bool containts(const Preset *preset) {
return presets.find(preset) != presets.end();
}
const std::string& appconfig_section() const;
const std::string& get_type(const Preset *preset) const;
const std::string& get_vendor(const Preset *preset) const;
template<class F> void filter_presets(const std::string &type, const std::string &vendor, F cb) {
for (const Preset *preset : presets) {
if ((type.empty() || get_type(preset) == type) && (vendor.empty() || get_vendor(preset) == vendor)) {
cb(preset);
}
}
}
static const std::string UNKNOWN;
static const std::string& get_filament_type(const Preset *preset);
static const std::string& get_filament_vendor(const Preset *preset);
static const std::string& get_material_type(const Preset *preset);
static const std::string& get_material_vendor(const Preset *preset);
};
struct Bundle
{
std::unique_ptr<PresetBundle> preset_bundle;
VendorProfile *vendor_profile;
const bool is_in_resources;
const bool is_prusa_bundle;
Bundle(fs::path source_path, bool is_in_resources, bool is_prusa_bundle = false);
Bundle(Bundle &&other);
const std::string& vendor_id() const { return vendor_profile->id; }
};
struct BundleMap: std::unordered_map<std::string /* = vendor ID */, Bundle>
{
static BundleMap load();
Bundle& prusa_bundle();
const Bundle& prusa_bundle() const;
};
struct PrinterPickerEvent;
// GUI elements
typedef std::function<bool(const VendorProfile::PrinterModel&)> ModelFilter; typedef std::function<bool(const VendorProfile::PrinterModel&)> ModelFilter;
struct PrinterPicker: wxPanel struct PrinterPicker: wxPanel
@ -61,19 +134,22 @@ struct PrinterPicker: wxPanel
std::vector<Checkbox*> cboxes; std::vector<Checkbox*> cboxes;
std::vector<Checkbox*> cboxes_alt; std::vector<Checkbox*> cboxes_alt;
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors, const ModelFilter &filter); PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig, const ModelFilter &filter);
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors); PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig);
void select_all(bool select, bool alternates = false); void select_all(bool select, bool alternates = false);
void select_one(size_t i, bool select); void select_one(size_t i, bool select);
void on_checkbox(const Checkbox *cbox, bool checked); bool any_selected() const;
int get_width() const { return width; } int get_width() const { return width; }
const std::vector<int>& get_button_indexes() { return m_button_indexes; } const std::vector<int>& get_button_indexes() { return m_button_indexes; }
static const std::string PRINTER_PLACEHOLDER;
private: private:
int width; int width;
std::vector<int> m_button_indexes; std::vector<int> m_button_indexes;
void on_checkbox(const Checkbox *cbox, bool checked);
}; };
struct ConfigWizardPage: wxPanel struct ConfigWizardPage: wxPanel
@ -87,43 +163,107 @@ struct ConfigWizardPage: wxPanel
virtual ~ConfigWizardPage(); virtual ~ConfigWizardPage();
template<class T> template<class T>
void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10) T* append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
{ {
content->Add(thing, proportion, flag, border); content->Add(thing, proportion, flag, border);
return thing;
} }
void append_text(wxString text); wxStaticText* append_text(wxString text);
void append_spacer(int space); void append_spacer(int space);
ConfigWizard::priv *wizard_p() const { return parent->p.get(); } ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
virtual void apply_custom_config(DynamicPrintConfig &config) {} virtual void apply_custom_config(DynamicPrintConfig &config) {}
virtual void set_run_reason(ConfigWizard::RunReason run_reason) {}
virtual void on_activate() {}
}; };
struct PageWelcome: ConfigWizardPage struct PageWelcome: ConfigWizardPage
{ {
wxStaticText *welcome_text;
wxCheckBox *cbox_reset; wxCheckBox *cbox_reset;
PageWelcome(ConfigWizard *parent); PageWelcome(ConfigWizard *parent);
bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; } bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; }
virtual void set_run_reason(ConfigWizard::RunReason run_reason) override;
}; };
struct PagePrinters: ConfigWizardPage struct PagePrinters: ConfigWizardPage
{ {
enum Technology {
// Bitflag equivalent of PrinterTechnology
T_FFF = 0x1,
T_SLA = 0x2,
T_Any = ~0,
};
std::vector<PrinterPicker *> printer_pickers; std::vector<PrinterPicker *> printer_pickers;
Technology technology;
bool install;
PagePrinters(ConfigWizard *parent, wxString title, wxString shortname, const VendorProfile &vendor, unsigned indent, Technology technology); PagePrinters(ConfigWizard *parent,
wxString title,
wxString shortname,
const VendorProfile &vendor,
unsigned indent, Technology technology);
void select_all(bool select, bool alternates = false); void select_all(bool select, bool alternates = false);
int get_width() const; int get_width() const;
bool any_selected() const;
virtual void set_run_reason(ConfigWizard::RunReason run_reason) override;
};
// Here we extend wxListBox and wxCheckListBox
// to make the client data API much easier to use.
template<class T, class D> struct DataList : public T
{
DataList(wxWindow *parent) : T(parent, wxID_ANY) {}
// Note: We're _not_ using wxLB_SORT here because it doesn't do the right thing,
// eg. "ABS" is sorted before "(All)"
int append(const std::string &label, const D *data) {
void *ptr = reinterpret_cast<void*>(const_cast<D*>(data));
return this->Append(from_u8(label), ptr);
}
int append(const wxString &label, const D *data) {
void *ptr = reinterpret_cast<void*>(const_cast<D*>(data));
return this->Append(label, ptr);
}
const D& get_data(int n) {
return *reinterpret_cast<const D*>(this->GetClientData(n));
}
int find(const D &data) {
for (unsigned i = 0; i < this->GetCount(); i++) {
if (get_data(i) == data) { return i; }
}
return wxNOT_FOUND;
}
};
typedef DataList<wxListBox, std::string> StringList;
typedef DataList<wxCheckListBox, Preset> PresetList;
struct PageMaterials: ConfigWizardPage
{
Materials *materials;
StringList *list_l1, *list_l2;
PresetList *list_l3;
int sel1_prev, sel2_prev;
bool presets_loaded;
static const std::string EMPTY;
PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name);
void reload_presets();
void update_lists(int sel1, int sel2);
void select_material(int i);
void select_all(bool select);
void clear();
virtual void on_activate() override;
}; };
struct PageCustom: ConfigWizardPage struct PageCustom: ConfigWizardPage
@ -150,13 +290,22 @@ struct PageUpdate: ConfigWizardPage
PageUpdate(ConfigWizard *parent); PageUpdate(ConfigWizard *parent);
}; };
struct PageMode: ConfigWizardPage
{
wxRadioButton *radio_simple;
wxRadioButton *radio_advanced;
wxRadioButton *radio_expert;
PageMode(ConfigWizard *parent);
void serialize_mode(AppConfig *app_config) const;
virtual void on_activate();
};
struct PageVendors: ConfigWizardPage struct PageVendors: ConfigWizardPage
{ {
std::vector<PrinterPicker*> pickers;
PageVendors(ConfigWizard *parent); PageVendors(ConfigWizard *parent);
void on_vendor_pick(size_t i);
}; };
struct PageFirmware: ConfigWizardPage struct PageFirmware: ConfigWizardPage
@ -194,6 +343,8 @@ struct PageTemperatures: ConfigWizardPage
virtual void apply_custom_config(DynamicPrintConfig &config); virtual void apply_custom_config(DynamicPrintConfig &config);
}; };
typedef std::map<std::string /* = vendor ID */, PagePrinters*> Pages3rdparty;
class ConfigWizardIndex: public wxPanel class ConfigWizardIndex: public wxPanel
{ {
@ -210,12 +361,14 @@ public:
void go_prev(); void go_prev();
void go_next(); void go_next();
void go_to(size_t i); void go_to(size_t i);
void go_to(ConfigWizardPage *page); void go_to(const ConfigWizardPage *page);
void clear(); void clear();
void msw_rescale(); void msw_rescale();
int em() const { return em_w; } int em() const { return em_w; }
static const size_t NO_ITEM = size_t(-1);
private: private:
struct Item struct Item
{ {
@ -228,12 +381,6 @@ private:
int em_w; int em_w;
int em_h; int em_h;
/* #ys_FIXME_delete_after_testing by VK
const wxBitmap bg;
const wxBitmap bullet_black;
const wxBitmap bullet_blue;
const wxBitmap bullet_white;
*/
ScalableBitmap bg; ScalableBitmap bg;
ScalableBitmap bullet_black; ScalableBitmap bullet_black;
ScalableBitmap bullet_blue; ScalableBitmap bullet_blue;
@ -245,9 +392,6 @@ private:
ssize_t item_hover; ssize_t item_hover;
size_t last_page; size_t last_page;
/* #ys_FIXME_delete_after_testing by VK
int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em_w) + em_w; }
*/
int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; } int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; }
void on_paint(wxPaintEvent &evt); void on_paint(wxPaintEvent &evt);
@ -256,14 +400,24 @@ private:
wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent); wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent);
// ConfigWizard private data
struct ConfigWizard::priv struct ConfigWizard::priv
{ {
ConfigWizard *q; ConfigWizard *q;
ConfigWizard::RunReason run_reason; ConfigWizard::RunReason run_reason = RR_USER;
AppConfig appconfig_vendors; AppConfig appconfig_new; // Backing for vendor/model/variant and material selections in the GUI
std::unordered_map<std::string, VendorProfile> vendors; BundleMap bundles; // Holds all loaded config bundles, the key is the vendor names.
std::unordered_map<std::string, std::string> vendors_rsrc; // Materials refers to Presets in those bundles by pointers.
std::unique_ptr<DynamicPrintConfig> custom_config; // Also we update the is_visible flag in printer Presets according to the
// PrinterPickers state.
Materials filaments; // Holds available filament presets and their types & vendors
Materials sla_materials; // Ditto for SLA materials
std::unique_ptr<DynamicPrintConfig> custom_config; // Backing for custom printer definition
bool any_fff_selected; // Used to decide whether to display Filaments page
bool any_sla_selected; // Used to decide whether to display SLA Materials page
wxScrolledWindow *hscroll = nullptr; wxScrolledWindow *hscroll = nullptr;
wxBoxSizer *hscroll_sizer = nullptr; wxBoxSizer *hscroll_sizer = nullptr;
@ -279,9 +433,13 @@ struct ConfigWizard::priv
PageWelcome *page_welcome = nullptr; PageWelcome *page_welcome = nullptr;
PagePrinters *page_fff = nullptr; PagePrinters *page_fff = nullptr;
PagePrinters *page_msla = nullptr; PagePrinters *page_msla = nullptr;
PageMaterials *page_filaments = nullptr;
PageMaterials *page_sla_materials = nullptr;
PageCustom *page_custom = nullptr; PageCustom *page_custom = nullptr;
PageUpdate *page_update = nullptr; PageUpdate *page_update = nullptr;
PageVendors *page_vendors = nullptr; // XXX: ? PageMode *page_mode = nullptr;
PageVendors *page_vendors = nullptr;
Pages3rdparty pages_3rdparty;
// Custom setup pages // Custom setup pages
PageFirmware *page_firmware = nullptr; PageFirmware *page_firmware = nullptr;
@ -289,17 +447,30 @@ struct ConfigWizard::priv
PageDiameters *page_diams = nullptr; PageDiameters *page_diams = nullptr;
PageTemperatures *page_temps = nullptr; PageTemperatures *page_temps = nullptr;
priv(ConfigWizard *q) : q(q) {} // Pointers to all pages (regardless or whether currently part of the ConfigWizardIndex)
std::vector<ConfigWizardPage*> all_pages;
void load_pages(bool custom_setup); priv(ConfigWizard *q)
: q(q)
, filaments(T_FFF)
, sla_materials(T_SLA)
, any_sla_selected(false)
{}
void load_pages();
void init_dialog_size(); void init_dialog_size();
bool check_first_variant() const;
void load_vendors(); void load_vendors();
void add_page(ConfigWizardPage *page); void add_page(ConfigWizardPage *page);
void enable_next(bool enable); void enable_next(bool enable);
void set_start_page(ConfigWizard::StartPage start_page);
void create_3rdparty_pages();
void set_run_reason(RunReason run_reason);
void update_materials(Technology technology);
void on_custom_setup(bool custom_wanted); void on_custom_setup();
void on_printer_pick(PagePrinters *page, const PrinterPickerEvent &evt);
void on_3rdparty_install(const VendorProfile *vendor, bool install);
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater); void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);

View file

@ -2323,7 +2323,8 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
m_dirty |= m_undoredo_toolbar.update_items_state(); m_dirty |= m_undoredo_toolbar.update_items_state();
m_dirty |= m_view_toolbar.update_items_state(); m_dirty |= m_view_toolbar.update_items_state();
#if ENABLE_3DCONNEXION_DEVICES #if ENABLE_3DCONNEXION_DEVICES
m_dirty |= wxGetApp().plater()->get_mouse3d_controller().apply(m_camera); bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(m_camera);
m_dirty |= mouse3d_controller_applied;
#endif // ENABLE_3DCONNEXION_DEVICES #endif // ENABLE_3DCONNEXION_DEVICES
if (!m_dirty) if (!m_dirty)
@ -2332,7 +2333,7 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
_refresh_if_shown_on_screen(); _refresh_if_shown_on_screen();
#if ENABLE_3DCONNEXION_DEVICES #if ENABLE_3DCONNEXION_DEVICES
if (m_keep_dirty) if (m_keep_dirty || mouse3d_controller_applied)
{ {
m_dirty = true; m_dirty = true;
evt.RequestMore(); evt.RequestMore();
@ -2585,9 +2586,9 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
{ {
#if ENABLE_3DCONNEXION_DEVICES #if ENABLE_3DCONNEXION_DEVICES
// try to filter out events coming from mouse 3d controller // try to filter out events coming from mouse 3d
const Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller(); Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller();
if (controller.has_translation_or_rotation()) if (controller.process_mouse_wheel())
return; return;
#endif // ENABLE_3DCONNEXION_DEVICES #endif // ENABLE_3DCONNEXION_DEVICES

View file

@ -101,49 +101,6 @@ const std::string& shortkey_alt_prefix()
return str; return str;
} }
bool config_wizard_startup(bool app_config_exists)
{
if (!app_config_exists || wxGetApp().preset_bundle->printers.size() <= 1) {
config_wizard(ConfigWizard::RR_DATA_EMPTY);
return true;
} else if (get_app_config()->legacy_datadir()) {
// Looks like user has legacy pre-vendorbundle data directory,
// explain what this is and run the wizard
MsgDataLegacy dlg;
dlg.ShowModal();
config_wizard(ConfigWizard::RR_DATA_LEGACY);
return true;
}
return false;
}
void config_wizard(int reason)
{
// Exit wizard if there are unsaved changes and the user cancels the action.
if (! wxGetApp().check_unsaved_changes())
return;
try {
ConfigWizard wizard(nullptr, static_cast<ConfigWizard::RunReason>(reason));
wizard.run(wxGetApp().preset_bundle, wxGetApp().preset_updater);
}
catch (const std::exception &e) {
show_error(nullptr, e.what());
}
wxGetApp().load_current_presets();
if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA && model_has_multi_part_objects(wxGetApp().model()))
{
show_info(nullptr,
_(L("It's impossible to print multi-part object(s) with SLA technology.")) + "\n\n" +
_(L("Please check and fix your object list.")),
_(L("Attention!")));
}
}
// opt_index = 0, by the reason of zero-index in ConfigOptionVector by default (in case only one element) // opt_index = 0, by the reason of zero-index in ConfigOptionVector by default (in case only one element)
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/) void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
{ {

View file

@ -35,14 +35,6 @@ extern AppConfig* get_app_config();
extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change);
// Checks if configuration wizard needs to run, calls config_wizard if so.
// Returns whether the Wizard ran.
extern bool config_wizard_startup(bool app_config_exists);
// Opens the configuration wizard, returns true if wizard is finished & accepted.
// The run_reason argument is actually ConfigWizard::RunReason, but int is used here because of Perl.
extern void config_wizard(int run_reason);
// Change option value in config // Change option value in config
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0); void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0);

View file

@ -38,7 +38,6 @@
#include "../Utils/PresetUpdater.hpp" #include "../Utils/PresetUpdater.hpp"
#include "../Utils/PrintHost.hpp" #include "../Utils/PrintHost.hpp"
#include "../Utils/MacDarkMode.hpp" #include "../Utils/MacDarkMode.hpp"
#include "ConfigWizard.hpp"
#include "slic3r/Config/Snapshot.hpp" #include "slic3r/Config/Snapshot.hpp"
#include "ConfigSnapshotDialog.hpp" #include "ConfigSnapshotDialog.hpp"
#include "FirmwareDialog.hpp" #include "FirmwareDialog.hpp"
@ -46,6 +45,7 @@
#include "Tab.hpp" #include "Tab.hpp"
#include "SysInfoDialog.hpp" #include "SysInfoDialog.hpp"
#include "KBShortcutsDialog.hpp" #include "KBShortcutsDialog.hpp"
#include "UpdateDialogs.hpp"
#ifdef __WXMSW__ #ifdef __WXMSW__
#include <Shlobj.h> #include <Shlobj.h>
@ -148,6 +148,7 @@ GUI_App::GUI_App()
: wxApp() : wxApp()
, m_em_unit(10) , m_em_unit(10)
, m_imgui(new ImGuiWrapper()) , m_imgui(new ImGuiWrapper())
, m_wizard(nullptr)
{} {}
GUI_App::~GUI_App() GUI_App::~GUI_App()
@ -204,7 +205,6 @@ bool GUI_App::on_init_inner()
// supplied as argument to --datadir; in that case we should still run the wizard // supplied as argument to --datadir; in that case we should still run the wizard
preset_bundle->setup_directories(); preset_bundle->setup_directories();
app_conf_exists = app_config->exists();
// load settings // load settings
app_conf_exists = app_config->exists(); app_conf_exists = app_config->exists();
if (app_conf_exists) { if (app_conf_exists) {
@ -287,7 +287,7 @@ bool GUI_App::on_init_inner()
} }
CallAfter([this] { CallAfter([this] {
config_wizard_startup(app_conf_exists); config_wizard_startup();
preset_updater->slic3r_update_notify(); preset_updater->slic3r_update_notify();
preset_updater->sync(preset_bundle); preset_updater->sync(preset_bundle);
}); });
@ -826,7 +826,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) { local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) {
switch (event.GetId() - config_id_base) { switch (event.GetId() - config_id_base) {
case ConfigMenuWizard: case ConfigMenuWizard:
config_wizard(ConfigWizard::RR_USER); run_wizard(ConfigWizard::RR_USER);
break; break;
case ConfigMenuTakeSnapshot: case ConfigMenuTakeSnapshot:
// Take a configuration snapshot. // Take a configuration snapshot.
@ -1057,6 +1057,31 @@ void GUI_App::open_web_page_localized(const std::string &http_address)
wxLaunchDefaultBrowser(http_address + "&lng=" + this->current_language_code_safe()); wxLaunchDefaultBrowser(http_address + "&lng=" + this->current_language_code_safe());
} }
bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page)
{
wxCHECK_MSG(mainframe != nullptr, false, "Internal error: Main frame not created / null");
if (! m_wizard) {
m_wizard = new ConfigWizard(mainframe);
}
const bool res = m_wizard->run(reason, start_page);
if (res) {
load_current_presets();
if (preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA
&& Slic3r::model_has_multi_part_objects(wxGetApp().model())) {
GUI::show_info(nullptr,
_(L("It's impossible to print multi-part object(s) with SLA technology.")) + "\n\n" +
_(L("Please check and fix your object list.")),
_(L("Attention!")));
}
}
return res;
}
void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name)
{ {
if (name.empty()) { return; } if (name.empty()) { return; }
@ -1105,6 +1130,24 @@ void GUI_App::window_pos_sanitize(wxTopLevelWindow* window)
} }
} }
bool GUI_App::config_wizard_startup()
{
if (!app_conf_exists || preset_bundle->printers.size() <= 1) {
run_wizard(ConfigWizard::RR_DATA_EMPTY);
return true;
} else if (get_app_config()->legacy_datadir()) {
// Looks like user has legacy pre-vendorbundle data directory,
// explain what this is and run the wizard
MsgDataLegacy dlg;
dlg.ShowModal();
run_wizard(ConfigWizard::RR_DATA_LEGACY);
return true;
}
return false;
}
// static method accepting a wxWindow object as first parameter // static method accepting a wxWindow object as first parameter
// void warning_catcher{ // void warning_catcher{
// my($self, $message_dialog) = @_; // my($self, $message_dialog) = @_;

View file

@ -6,6 +6,7 @@
#include "libslic3r/PrintConfig.hpp" #include "libslic3r/PrintConfig.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "ImGuiWrapper.hpp" #include "ImGuiWrapper.hpp"
#include "ConfigWizard.hpp"
#include <wx/app.h> #include <wx/app.h>
#include <wx/colour.h> #include <wx/colour.h>
@ -69,6 +70,7 @@ enum ConfigMenuIDs {
}; };
class Tab; class Tab;
class ConfigWizard;
static wxString dots("", wxConvUTF8); static wxString dots("", wxConvUTF8);
@ -96,6 +98,7 @@ class GUI_App : public wxApp
std::unique_ptr<ImGuiWrapper> m_imgui; std::unique_ptr<ImGuiWrapper> m_imgui;
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue; std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
ConfigWizard* m_wizard; // Managed by wxWindow tree
public: public:
bool OnInit() override; bool OnInit() override;
@ -184,6 +187,7 @@ public:
PrintHostJobQueue& printhost_job_queue() { return *m_printhost_job_queue.get(); } PrintHostJobQueue& printhost_job_queue() { return *m_printhost_job_queue.get(); }
void open_web_page_localized(const std::string &http_address); void open_web_page_localized(const std::string &http_address);
bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME);
private: private:
bool on_init_inner(); bool on_init_inner();
@ -191,6 +195,9 @@ private:
void window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false); void window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false);
void window_pos_sanitize(wxTopLevelWindow* window); void window_pos_sanitize(wxTopLevelWindow* window);
bool select_language(); bool select_language();
bool config_wizard_startup();
#ifdef __WXMSW__ #ifdef __WXMSW__
void associate_3mf_files(); void associate_3mf_files();
#endif // __WXMSW__ #endif // __WXMSW__

View file

@ -12,7 +12,6 @@
#include <boost/nowide/convert.hpp> #include <boost/nowide/convert.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include "I18N.hpp" #include "I18N.hpp"
// WARN: If updating these lists, please also update resources/udev/90-3dconnexion.rules // WARN: If updating these lists, please also update resources/udev/90-3dconnexion.rules
@ -23,6 +22,7 @@ static const std::vector<int> _3DCONNEXION_VENDORS =
0x256F // 3DCONNECTION = 9583 // 3Dconnexion 0x256F // 3DCONNECTION = 9583 // 3Dconnexion
}; };
// See: https://github.com/FreeSpacenav/spacenavd/blob/a9eccf34e7cac969ee399f625aef827f4f4aaec6/src/dev.c#L202 for a wider list of devices
static const std::vector<int> _3DCONNEXION_DEVICES = static const std::vector<int> _3DCONNEXION_DEVICES =
{ {
0xC623, // TRAVELER = 50723 0xC623, // TRAVELER = 50723
@ -43,13 +43,28 @@ const double Mouse3DController::State::DefaultTranslationScale = 2.5;
const float Mouse3DController::State::DefaultRotationScale = 1.0; const float Mouse3DController::State::DefaultRotationScale = 1.0;
Mouse3DController::State::State() Mouse3DController::State::State()
: m_translation(Vec3d::Zero()) : m_translation_scale(DefaultTranslationScale)
, m_rotation(Vec3f::Zero())
, m_translation_scale(DefaultTranslationScale)
, m_rotation_scale(DefaultRotationScale) , m_rotation_scale(DefaultRotationScale)
, m_mouse_wheel_counter(0)
{ {
} }
bool Mouse3DController::State::process_mouse_wheel()
{
if (m_mouse_wheel_counter > 0)
{
--m_mouse_wheel_counter;
return true;
}
else if (m_rotation.empty())
{
m_mouse_wheel_counter = 0;
return true;
}
return false;
}
bool Mouse3DController::State::apply(Camera& camera) bool Mouse3DController::State::apply(Camera& camera)
{ {
if (!wxGetApp().IsActive()) if (!wxGetApp().IsActive())
@ -59,35 +74,35 @@ bool Mouse3DController::State::apply(Camera& camera)
if (has_translation()) if (has_translation())
{ {
camera.set_target(camera.get_target() + m_translation_scale * (m_translation(0) * camera.get_dir_right() + m_translation(1) * camera.get_dir_forward() + m_translation(2) * camera.get_dir_up())); const Vec3d& translation = m_translation.front();
m_translation = Vec3d::Zero(); camera.set_target(camera.get_target() + m_translation_scale * (translation(0) * camera.get_dir_right() + translation(1) * camera.get_dir_forward() + translation(2) * camera.get_dir_up()));
m_translation.pop();
ret = true; ret = true;
} }
if (has_rotation()) if (has_rotation())
{ {
float theta = m_rotation_scale * m_rotation(0); const Vec3f& rotation = m_rotation.front();
float phi = m_rotation_scale * m_rotation(2); float theta = m_rotation_scale * rotation(0);
float phi = m_rotation_scale * rotation(2);
float sign = camera.inverted_phi ? -1.0f : 1.0f; float sign = camera.inverted_phi ? -1.0f : 1.0f;
camera.phi += sign * phi; camera.phi += sign * phi;
camera.set_theta(camera.get_theta() + theta, wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA); camera.set_theta(camera.get_theta() + theta, wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA);
m_rotation = Vec3f::Zero(); m_rotation.pop();
ret = true; ret = true;
} }
if (has_any_button()) if (has_any_button())
{ {
for (unsigned int i : m_buttons) unsigned int button = m_buttons.front();
switch (button)
{ {
switch (i) case 0: { camera.update_zoom(1.0); break; }
{ case 1: { camera.update_zoom(-1.0); break; }
case 0: { camera.update_zoom(1.0); break; } default: { break; }
case 1: { camera.update_zoom(-1.0); break; }
default: { break; }
}
} }
m_buttons.pop();
reset_buttons();
ret = true; ret = true;
} }
@ -361,7 +376,7 @@ void Mouse3DController::collect_input()
if (!translation.isApprox(Vec3d::Zero())) if (!translation.isApprox(Vec3d::Zero()))
{ {
updated = true; updated = true;
m_state.set_translation(translation); m_state.append_translation(translation);
} }
break; break;
@ -374,7 +389,7 @@ void Mouse3DController::collect_input()
if (!rotation.isApprox(Vec3f::Zero())) if (!rotation.isApprox(Vec3f::Zero()))
{ {
updated = true; updated = true;
m_state.set_rotation(rotation); m_state.append_rotation(rotation);
} }
break; break;
@ -393,7 +408,7 @@ void Mouse3DController::collect_input()
if (retrieved_data[1] & (0x1 << i)) if (retrieved_data[1] & (0x1 << i))
{ {
updated = true; updated = true;
m_state.set_button(i); m_state.append_button(i);
} }
} }

View file

@ -6,6 +6,7 @@
#include "hidapi.h" #include "hidapi.h"
#include <queue>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@ -24,26 +25,40 @@ class Mouse3DController
static const float DefaultRotationScale; static const float DefaultRotationScale;
private: private:
Vec3d m_translation; std::queue<Vec3d> m_translation;
Vec3f m_rotation; std::queue<Vec3f> m_rotation;
std::vector<unsigned int> m_buttons; std::queue<unsigned int> m_buttons;
double m_translation_scale; double m_translation_scale;
float m_rotation_scale; float m_rotation_scale;
// When the 3Dconnexion driver is running the system gets, by default, mouse wheel events when rotations around the X axis are detected.
// We want to filter these out because we are getting the data directly from the device, bypassing the driver, and those mouse wheel events interfere
// by triggering unwanted zoom in/out of the scene
// The following variable is used to count the potential mouse wheel events triggered and is updated by:
// Mouse3DController::collect_input() through the call to the append_rotation() method
// GLCanvas3D::on_mouse_wheel() through the call to the process_mouse_wheel() method
// GLCanvas3D::on_idle() through the call to the apply() method
unsigned int m_mouse_wheel_counter;
public: public:
State(); State();
void set_translation(const Vec3d& translation) { m_translation = translation; } void append_translation(const Vec3d& translation) { m_translation.push(translation); }
void set_rotation(const Vec3f& rotation) { m_rotation = rotation; } void append_rotation(const Vec3f& rotation)
void set_button(unsigned int id) { m_buttons.push_back(id); } {
void reset_buttons() { return m_buttons.clear(); } m_rotation.push(rotation);
if (rotation(0) != 0.0f)
++m_mouse_wheel_counter;
}
void append_button(unsigned int id) { m_buttons.push(id); }
bool has_translation() const { return !m_translation.isApprox(Vec3d::Zero()); } bool has_translation() const { return !m_translation.empty(); }
bool has_rotation() const { return !m_rotation.isApprox(Vec3f::Zero()); } bool has_rotation() const { return !m_rotation.empty(); }
bool has_translation_or_rotation() const { return !m_translation.isApprox(Vec3d::Zero()) && !m_rotation.isApprox(Vec3f::Zero()); }
bool has_any_button() const { return !m_buttons.empty(); } bool has_any_button() const { return !m_buttons.empty(); }
bool process_mouse_wheel();
double get_translation_scale() const { return m_translation_scale; } double get_translation_scale() const { return m_translation_scale; }
void set_translation_scale(double scale) { m_translation_scale = scale; } void set_translation_scale(double scale) { m_translation_scale = scale; }
@ -72,10 +87,7 @@ public:
bool is_device_connected() const { return m_device != nullptr; } bool is_device_connected() const { return m_device != nullptr; }
bool is_running() const { return m_running; } bool is_running() const { return m_running; }
// bool has_translation() const { return m_state.has_translation(); } bool process_mouse_wheel() { std::lock_guard<std::mutex> lock(m_mutex); return m_state.process_mouse_wheel(); }
// bool has_rotation() const { return m_state.has_rotation(); }
bool has_translation_or_rotation() const { return m_state.has_translation_or_rotation(); }
// bool has_any_button() const { return m_state.has_any_button(); }
bool apply(Camera& camera); bool apply(Camera& camera);

View file

@ -254,11 +254,18 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 *
auto selected_item = this->GetSelection(); auto selected_item = this->GetSelection();
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
if (marker == LABEL_ITEM_MARKER || marker == LABEL_ITEM_CONFIG_WIZARD) { if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
this->SetSelection(this->last_selected); this->SetSelection(this->last_selected);
evt.StopPropagation(); evt.StopPropagation();
if (marker == LABEL_ITEM_CONFIG_WIZARD) if (marker >= LABEL_ITEM_WIZARD_PRINTERS) {
wxTheApp->CallAfter([]() { Slic3r::GUI::config_wizard(Slic3r::GUI::ConfigWizard::RR_USER); }); ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
switch (marker) {
case LABEL_ITEM_WIZARD_PRINTERS: sp = ConfigWizard::SP_PRINTERS; break;
case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
}
wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); });
}
} else if ( this->last_selected != selected_item || } else if ( this->last_selected != selected_item ||
wxGetApp().get_tab(this->preset_type)->get_presets()->current_is_dirty() ) { wxGetApp().get_tab(this->preset_type)->get_presets()->current_is_dirty() ) {
this->last_selected = selected_item; this->last_selected = selected_item;
@ -1577,7 +1584,8 @@ struct Plater::priv
size_t count = 0; // To know how much space to reserve size_t count = 0; // To know how much space to reserve
for (auto obj : model.objects) count += obj->instances.size(); for (auto obj : model.objects) count += obj->instances.size();
m_selected.clear(), m_unselected.clear(); m_selected.clear();
m_unselected.clear();
m_selected.reserve(count + 1 /* for optional wti */); m_selected.reserve(count + 1 /* for optional wti */);
m_unselected.reserve(count + 1 /* for optional wti */); m_unselected.reserve(count + 1 /* for optional wti */);
} }
@ -1591,11 +1599,12 @@ struct Plater::priv
// Set up arrange polygon for a ModelInstance and Wipe tower // Set up arrange polygon for a ModelInstance and Wipe tower
template<class T> ArrangePolygon get_arrange_poly(T *obj) const { template<class T> ArrangePolygon get_arrange_poly(T *obj) const {
ArrangePolygon ap = obj->get_arrange_polygon(); ArrangePolygon ap = obj->get_arrange_polygon();
ap.priority = 0; ap.priority = 0;
ap.bed_idx = ap.translation.x() / bed_stride(); ap.bed_idx = ap.translation.x() / bed_stride();
ap.setter = [obj, this](const ArrangePolygon &p) { ap.setter = [obj, this](const ArrangePolygon &p) {
if (p.is_arranged()) { if (p.is_arranged()) {
auto t = p.translation; t.x() += p.bed_idx * bed_stride(); auto t = p.translation;
t.x() += p.bed_idx * bed_stride();
obj->apply_arrange_result(t, p.rotation); obj->apply_arrange_result(t, p.rotation);
} }
}; };
@ -1626,7 +1635,8 @@ struct Plater::priv
obj_sel(model.objects.size(), nullptr); obj_sel(model.objects.size(), nullptr);
for (auto &s : plater().get_selection().get_content()) for (auto &s : plater().get_selection().get_content())
if (s.first < int(obj_sel.size())) obj_sel[s.first] = &s.second; if (s.first < int(obj_sel.size()))
obj_sel[size_t(s.first)] = &s.second;
// Go through the objects and check if inside the selection // Go through the objects and check if inside the selection
for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) { for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) {
@ -1636,7 +1646,8 @@ struct Plater::priv
std::vector<bool> inst_sel(mo->instances.size(), false); std::vector<bool> inst_sel(mo->instances.size(), false);
if (instlist) if (instlist)
for (auto inst_id : *instlist) inst_sel[inst_id] = true; for (auto inst_id : *instlist)
inst_sel[size_t(inst_id)] = true;
for (size_t i = 0; i < inst_sel.size(); ++i) { for (size_t i = 0; i < inst_sel.size(); ++i) {
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]); ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]);
@ -2773,9 +2784,8 @@ void Plater::priv::ArrangeJob::process() {
try { try {
arrangement::arrange(m_selected, m_unselected, min_d, bedshape, arrangement::arrange(m_selected, m_unselected, min_d, bedshape,
[this, count](unsigned st) { [this, count](unsigned st) {
if (st > if (st > 0) // will not finalize after last one
0) // will not finalize after last one update_status(int(count - st), arrangestr);
update_status(count - st, arrangestr);
}, },
[this]() { return was_canceled(); }); [this]() { return was_canceled(); });
} catch (std::exception & /*e*/) { } catch (std::exception & /*e*/) {
@ -4909,7 +4919,11 @@ const DynamicPrintConfig* Plater::get_plater_config() const
std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const
{ {
const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
std::vector<std::string> extruder_colors = (config->option<ConfigOptionStrings>("extruder_colour"))->values; std::vector<std::string> extruder_colors;
if (!config->has("extruder_colour")) // in case of a SLA print
return extruder_colors;
extruder_colors = (config->option<ConfigOptionStrings>("extruder_colour"))->values;
const std::vector<std::string>& filament_colours = (p->config->option<ConfigOptionStrings>("filament_colour"))->values; const std::vector<std::string>& filament_colours = (p->config->option<ConfigOptionStrings>("filament_colour"))->values;
for (size_t i = 0; i < extruder_colors.size(); ++i) for (size_t i = 0; i < extruder_colors.size(); ++i)
if (extruder_colors[i] == "" && i < filament_colours.size()) if (extruder_colors[i] == "" && i < filament_colours.size())

View file

@ -57,8 +57,12 @@ public:
ScalableButton* edit_btn { nullptr }; ScalableButton* edit_btn { nullptr };
enum LabelItemType { enum LabelItemType {
LABEL_ITEM_MARKER = 0x4d, LABEL_ITEM_MARKER = 0xffffff01,
LABEL_ITEM_CONFIG_WIZARD = 0x4e LABEL_ITEM_WIZARD_PRINTERS,
LABEL_ITEM_WIZARD_FILAMENTS,
LABEL_ITEM_WIZARD_MATERIALS,
LABEL_ITEM_MAX,
}; };
void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER); void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER);

View file

@ -99,6 +99,9 @@ static const std::unordered_map<std::string, std::string> pre_family_model_map {
VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all) VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all)
{ {
static const std::string printer_model_key = "printer_model:"; static const std::string printer_model_key = "printer_model:";
static const std::string filaments_section = "default_filaments";
static const std::string materials_section = "default_sla_materials";
const std::string id = path.stem().string(); const std::string id = path.stem().string();
if (! boost::filesystem::exists(path)) { if (! boost::filesystem::exists(path)) {
@ -107,6 +110,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
VendorProfile res(id); VendorProfile res(id);
// Helper to get compulsory fields
auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator
{ {
auto res = tree.find(key); auto res = tree.find(key);
@ -116,6 +120,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
return res; return res;
}; };
// Load the header
const auto &vendor_section = get_or_throw(tree, "vendor")->second; const auto &vendor_section = get_or_throw(tree, "vendor")->second;
res.name = get_or_throw(vendor_section, "name")->second.data(); res.name = get_or_throw(vendor_section, "name")->second.data();
@ -127,6 +132,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
res.config_version = std::move(*config_version); res.config_version = std::move(*config_version);
} }
// Load URLs
const auto config_update_url = vendor_section.find("config_update_url"); const auto config_update_url = vendor_section.find("config_update_url");
if (config_update_url != vendor_section.not_found()) { if (config_update_url != vendor_section.not_found()) {
res.config_update_url = config_update_url->second.data(); res.config_update_url = config_update_url->second.data();
@ -141,6 +147,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
return res; return res;
} }
// Load printer models
for (auto &section : tree) { for (auto &section : tree) {
if (boost::starts_with(section.first, printer_model_key)) { if (boost::starts_with(section.first, printer_model_key)) {
VendorProfile::PrinterModel model; VendorProfile::PrinterModel model;
@ -182,6 +189,24 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
} }
} }
// Load filaments and sla materials to be installed by default
const auto filaments = tree.find(filaments_section);
if (filaments != tree.not_found()) {
for (auto &pair : filaments->second) {
if (pair.second.data() == "1") {
res.default_filaments.insert(pair.first);
}
}
}
const auto materials = tree.find(materials_section);
if (materials != tree.not_found()) {
for (auto &pair : materials->second) {
if (pair.second.data() == "1") {
res.default_sla_materials.insert(pair.first);
}
}
}
return res; return res;
} }
@ -351,10 +376,17 @@ bool Preset::update_compatible(const Preset &active_printer, const DynamicPrintC
void Preset::set_visible_from_appconfig(const AppConfig &app_config) void Preset::set_visible_from_appconfig(const AppConfig &app_config)
{ {
if (vendor == nullptr) { return; } if (vendor == nullptr) { return; }
const std::string &model = config.opt_string("printer_model");
const std::string &variant = config.opt_string("printer_variant"); if (type == TYPE_PRINTER) {
if (model.empty() || variant.empty()) { return; } const std::string &model = config.opt_string("printer_model");
is_visible = app_config.get_variant(vendor->id, model, variant); const std::string &variant = config.opt_string("printer_variant");
if (model.empty() || variant.empty()) { return; }
is_visible = app_config.get_variant(vendor->id, model, variant);
} else if (type == TYPE_FILAMENT) {
is_visible = app_config.has("filaments", name);
} else if (type == TYPE_SLA_MATERIAL) {
is_visible = app_config.has("sla_materials", name);
}
} }
const std::vector<std::string>& Preset::print_options() const std::vector<std::string>& Preset::print_options()
@ -404,7 +436,7 @@ const std::vector<std::string>& Preset::filament_options()
"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_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", "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe",
// Profile compatibility // Profile compatibility
"compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits" "filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
}; };
return s_opts; return s_opts;
} }
@ -501,11 +533,13 @@ const std::vector<std::string>& Preset::sla_material_options()
static std::vector<std::string> s_opts; static std::vector<std::string> s_opts;
if (s_opts.empty()) { if (s_opts.empty()) {
s_opts = { s_opts = {
"material_type",
"initial_layer_height", "initial_layer_height",
"exposure_time", "exposure_time",
"initial_exposure_time", "initial_exposure_time",
"material_correction", "material_correction",
"material_notes", "material_notes",
"material_vendor",
"default_sla_material_profile", "default_sla_material_profile",
"compatible_prints", "compatible_prints_condition", "compatible_prints", "compatible_prints_condition",
"compatible_printers", "compatible_printers_condition", "inherits" "compatible_printers", "compatible_printers_condition", "inherits"
@ -1054,7 +1088,9 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap); bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap);
bmp = m_bitmap_cache->insert(bitmap_key, bmps); bmp = m_bitmap_cache->insert(bitmap_key, bmps);
} }
ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add a new printer")), *bmp), GUI::PresetComboBox::LABEL_ITEM_CONFIG_WIZARD); ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add a new printer")), *bmp), GUI::PresetComboBox::LABEL_ITEM_WIZARD_PRINTERS);
} else if (m_type == Preset::TYPE_SLA_MATERIAL) {
ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add/Remove materials")), wxNullBitmap), GUI::PresetComboBox::LABEL_ITEM_WIZARD_MATERIALS);
} }
ui->SetSelection(selected_preset_item); ui->SetSelection(selected_preset_item);
@ -1300,7 +1336,7 @@ bool PresetCollection::select_preset_by_name_strict(const std::string &name)
} }
// Merge one vendor's presets with the other vendor's presets, report duplicates. // Merge one vendor's presets with the other vendor's presets, report duplicates.
std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&other, const std::set<VendorProfile> &new_vendors) std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&other, const VendorMap &new_vendors)
{ {
std::vector<std::string> duplicates; std::vector<std::string> duplicates;
for (Preset &preset : other.m_presets) { for (Preset &preset : other.m_presets) {
@ -1311,9 +1347,9 @@ std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&othe
if (it == m_presets.end() || it->name != preset.name) { if (it == m_presets.end() || it->name != preset.name) {
if (preset.vendor != nullptr) { if (preset.vendor != nullptr) {
// Re-assign a pointer to the vendor structure in the new PresetBundle. // Re-assign a pointer to the vendor structure in the new PresetBundle.
auto it = new_vendors.find(*preset.vendor); auto it = new_vendors.find(preset.vendor->id);
assert(it != new_vendors.end()); assert(it != new_vendors.end());
preset.vendor = &(*it); preset.vendor = &it->second;
} }
this->m_presets.emplace(it, std::move(preset)); this->m_presets.emplace(it, std::move(preset));
} else } else

View file

@ -2,6 +2,8 @@
#define slic3r_Preset_hpp_ #define slic3r_Preset_hpp_
#include <deque> #include <deque>
#include <set>
#include <unordered_map>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/property_tree/ptree_fwd.hpp> #include <boost/property_tree/ptree_fwd.hpp>
@ -71,9 +73,14 @@ public:
}; };
std::vector<PrinterModel> models; std::vector<PrinterModel> models;
std::set<std::string> default_filaments;
std::set<std::string> default_sla_materials;
VendorProfile() {} VendorProfile() {}
VendorProfile(std::string id) : id(std::move(id)) {} VendorProfile(std::string id) : id(std::move(id)) {}
// Load VendorProfile from an ini file.
// If `load_all` is false, only the header with basic info (name, version, URLs) is loaded.
static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true); static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true);
static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true); static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true);
@ -84,6 +91,12 @@ public:
bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; } bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; }
}; };
// Note: it is imporant that map is used here rather than unordered_map,
// because we need iterators to not be invalidated,
// because Preset and the ConfigWizard hold pointers to VendorProfiles.
// XXX: maybe set is enough (cf. changes in Wizard)
typedef std::map<std::string, VendorProfile> VendorMap;
class Preset class Preset
{ {
public: public:
@ -433,7 +446,7 @@ protected:
bool select_preset_by_name_strict(const std::string &name); bool select_preset_by_name_strict(const std::string &name);
// Merge one vendor's presets with the other vendor's presets, report duplicates. // Merge one vendor's presets with the other vendor's presets, report duplicates.
std::vector<std::string> merge_presets(PresetCollection &&other, const std::set<VendorProfile> &new_vendors); std::vector<std::string> merge_presets(PresetCollection &&other, const VendorMap &new_vendors);
private: private:
PresetCollection(); PresetCollection();

View file

@ -8,6 +8,7 @@
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <unordered_set>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/algorithm/clamp.hpp> #include <boost/algorithm/clamp.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
@ -41,6 +42,8 @@ static std::vector<std::string> s_project_options {
"wiping_volumes_matrix" "wiping_volumes_matrix"
}; };
const char *PresetBundle::PRUSA_BUNDLE = "PrusaResearch";
PresetBundle::PresetBundle() : PresetBundle::PresetBundle() :
prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())), prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())), filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
@ -194,7 +197,7 @@ void PresetBundle::setup_directories()
} }
} }
void PresetBundle::load_presets(const AppConfig &config, const std::string &preferred_model_id) void PresetBundle::load_presets(AppConfig &config, const std::string &preferred_model_id)
{ {
// First load the vendor specific system presets. // First load the vendor specific system presets.
std::string errors_cummulative = this->load_system_presets(); std::string errors_cummulative = this->load_system_presets();
@ -325,13 +328,71 @@ void PresetBundle::load_installed_printers(const AppConfig &config)
} }
} }
void PresetBundle::load_installed_filaments(AppConfig &config)
{
if (! config.has_section(AppConfig::SECTION_FILAMENTS)) {
std::unordered_set<const Preset*> comp_filaments;
for (const Preset &printer : printers) {
if (! printer.is_visible || printer.printer_technology() != ptFFF) {
continue;
}
for (const Preset &filament : filaments) {
if (filament.is_compatible_with_printer(printer)) {
comp_filaments.insert(&filament);
}
}
}
for (const auto &filament: comp_filaments) {
config.set(AppConfig::SECTION_FILAMENTS, filament->name, "1");
}
}
for (auto &preset : filaments) {
preset.set_visible_from_appconfig(config);
}
}
void PresetBundle::load_installed_sla_materials(AppConfig &config)
{
if (! config.has_section(AppConfig::SECTION_MATERIALS)) {
std::unordered_set<const Preset*> comp_sla_materials;
for (const Preset &printer : printers) {
if (! printer.is_visible || printer.printer_technology() != ptSLA) {
continue;
}
for (const Preset &material : sla_materials) {
if (material.is_compatible_with_printer(printer)) {
comp_sla_materials.insert(&material);
}
}
}
for (const auto &material: comp_sla_materials) {
config.set(AppConfig::SECTION_MATERIALS, material->name, "1");
}
}
for (auto &preset : sla_materials) {
preset.set_visible_from_appconfig(config);
}
}
// Load selections (current print, current filaments, current printer) from config.ini // Load selections (current print, current filaments, current printer) from config.ini
// This is done on application start up or after updates are applied. // This is done on application start up or after updates are applied.
void PresetBundle::load_selections(const AppConfig &config, const std::string &preferred_model_id) void PresetBundle::load_selections(AppConfig &config, const std::string &preferred_model_id)
{ {
// Update visibility of presets based on application vendor / model / variant configuration. // Update visibility of presets based on application vendor / model / variant configuration.
this->load_installed_printers(config); this->load_installed_printers(config);
// Update visibility of filament and sla material presets
this->load_installed_filaments(config);
this->load_installed_sla_materials(config);
// Parse the initial print / filament / printer profile names. // Parse the initial print / filament / printer profile names.
std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print")); std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print"));
std::string initial_sla_print_profile_name = remove_ini_suffix(config.get("presets", "sla_print")); std::string initial_sla_print_profile_name = remove_ini_suffix(config.get("presets", "sla_print"));
@ -1032,9 +1093,9 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
auto vp = VendorProfile::from_ini(tree, path); auto vp = VendorProfile::from_ini(tree, path);
if (vp.num_variants() == 0) if (vp.num_variants() == 0)
return 0; return 0;
vendor_profile = &(*this->vendors.insert(vp).first); vendor_profile = &this->vendors.insert({vp.id, vp}).first->second;
} }
if (flags & LOAD_CFGBUNDLE_VENDOR_ONLY) { if (flags & LOAD_CFGBUNDLE_VENDOR_ONLY) {
return 0; return 0;
} }
@ -1572,6 +1633,9 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
selected_preset_item = ui->GetCount() - 1; selected_preset_item = ui->GetCount() - 1;
} }
} }
ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add/Remove filaments")), wxNullBitmap), GUI::PresetComboBox::LABEL_ITEM_WIZARD_FILAMENTS);
ui->SetSelection(selected_preset_item); ui->SetSelection(selected_preset_item);
ui->SetToolTip(ui->GetString(selected_preset_item)); ui->SetToolTip(ui->GetString(selected_preset_item));
ui->check_selection(); ui->check_selection();

View file

@ -4,7 +4,9 @@
#include "AppConfig.hpp" #include "AppConfig.hpp"
#include "Preset.hpp" #include "Preset.hpp"
#include <memory>
#include <set> #include <set>
#include <unordered_map>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
class wxWindow; class wxWindow;
@ -31,7 +33,7 @@ public:
// Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets. // Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets.
// Load selections (current print, current filaments, current printer) from config.ini // Load selections (current print, current filaments, current printer) from config.ini
// This is done just once on application start up. // This is done just once on application start up.
void load_presets(const AppConfig &config, const std::string &preferred_model_id = ""); void load_presets(AppConfig &config, const std::string &preferred_model_id = "");
// Export selections (current print, current filaments, current printer) into config.ini // Export selections (current print, current filaments, current printer) into config.ini
void export_selections(AppConfig &config); void export_selections(AppConfig &config);
@ -52,7 +54,8 @@ public:
// There will be an entry for each system profile loaded, // There will be an entry for each system profile loaded,
// and the system profiles will point to the VendorProfile instances owned by PresetBundle::vendors. // and the system profiles will point to the VendorProfile instances owned by PresetBundle::vendors.
std::set<VendorProfile> vendors; // std::set<VendorProfile> vendors;
VendorMap vendors;
struct ObsoletePresets { struct ObsoletePresets {
std::vector<std::string> prints; std::vector<std::string> prints;
@ -131,19 +134,25 @@ public:
void load_default_preset_bitmaps(wxWindow *window); void load_default_preset_bitmaps(wxWindow *window);
// Set the is_visible flag for printer vendors, printer models and printer variants
// based on the user configuration.
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
void load_installed_printers(const AppConfig &config);
static const char *PRUSA_BUNDLE;
private: private:
std::string load_system_presets(); std::string load_system_presets();
// Merge one vendor's presets with the other vendor's presets, report duplicates. // Merge one vendor's presets with the other vendor's presets, report duplicates.
std::vector<std::string> merge_presets(PresetBundle &&other); std::vector<std::string> merge_presets(PresetBundle &&other);
// Set the "enabled" flag for printer vendors, printer models and printer variants // Set the is_visible flag for filaments and sla materials,
// based on the user configuration. // apply defaults based on enabled printers when no filaments/materials are installed.
// If the "vendor" section is missing, enable all models and variants of the particular vendor. void load_installed_filaments(AppConfig &config);
void load_installed_printers(const AppConfig &config); void load_installed_sla_materials(AppConfig &config);
// Load selections (current print, current filaments, current printer) from config.ini // Load selections (current print, current filaments, current printer) from config.ini
// This is done just once on application start up. // This is done just once on application start up.
void load_selections(const AppConfig &config, const std::string &preferred_model_id = ""); void load_selections(AppConfig &config, const std::string &preferred_model_id = "");
// Load print, filament & printer presets from a config. If it is an external config, then the name is extracted from the external path. // Load print, filament & printer presets from a config. If it is an external config, then the name is extracted from the external path.
// and the external config is just referenced, not stored into user profile directory. // and the external config is just referenced, not stored into user profile directory.

View file

@ -227,9 +227,9 @@ void Tab::create_preset_tab()
m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this); m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) {
//! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox,
//! but the OSX version derived from wxOwnerDrawnCombo, instead of: //! but the OSX version derived from wxOwnerDrawnCombo, instead of:
//! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data()); //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data());
//! we doing next: //! we doing next:
int selected_item = m_presets_choice->GetSelection(); int selected_item = m_presets_choice->GetSelection();
if (m_selected_preset_item == size_t(selected_item) && !m_presets->current_is_dirty()) if (m_selected_preset_item == size_t(selected_item) && !m_presets->current_is_dirty())
@ -241,7 +241,7 @@ void Tab::create_preset_tab()
selected_string == "------- User presets -------"*/) { selected_string == "------- User presets -------"*/) {
m_presets_choice->SetSelection(m_selected_preset_item); m_presets_choice->SetSelection(m_selected_preset_item);
if (wxString::FromUTF8(selected_string.c_str()) == PresetCollection::separator(L("Add a new printer"))) if (wxString::FromUTF8(selected_string.c_str()) == PresetCollection::separator(L("Add a new printer")))
wxTheApp->CallAfter([]() { Slic3r::GUI::config_wizard(Slic3r::GUI::ConfigWizard::RR_USER); }); wxTheApp->CallAfter([]() { wxGetApp().run_wizard(ConfigWizard::RR_USER); });
return; return;
} }
m_selected_preset_item = selected_item; m_selected_preset_item = selected_item;

View file

@ -455,6 +455,9 @@ Slic3r::GUI::BitmapCache* m_bitmap_cache = nullptr;
std::vector<wxBitmap*> bmps; std::vector<wxBitmap*> bmps;
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
if (bmps.empty())
return bmps;
unsigned char rgb[3]; unsigned char rgb[3];
/* It's supposed that standard size of an icon is 36px*16px for 100% scaled display. /* It's supposed that standard size of an icon is 36px*16px for 100% scaled display.
@ -484,6 +487,8 @@ static wxBitmap get_extruder_color_icon(size_t extruder_idx)
{ {
// Create the bitmap with color bars. // Create the bitmap with color bars.
std::vector<wxBitmap*> bmps = get_extruder_color_icons(); std::vector<wxBitmap*> bmps = get_extruder_color_icons();
if (bmps.empty())
return wxNullBitmap;
return *bmps[extruder_idx >= bmps.size() ? 0 : extruder_idx]; return *bmps[extruder_idx >= bmps.size() ? 0 : extruder_idx];
} }

View file

@ -153,7 +153,7 @@ struct PresetUpdater::priv
bool get_file(const std::string &url, const fs::path &target_path) const; bool get_file(const std::string &url, const fs::path &target_path) const;
void prune_tmps() const; void prune_tmps() const;
void sync_version() const; void sync_version() const;
void sync_config(const std::set<VendorProfile> vendors); void sync_config(const VendorMap vendors);
void check_install_indices() const; void check_install_indices() const;
Updates get_config_updates() const; Updates get_config_updates() const;
@ -266,7 +266,7 @@ void PresetUpdater::priv::sync_version() const
// Download vendor indices. Also download new bundles if an index indicates there's a new one available. // Download vendor indices. Also download new bundles if an index indicates there's a new one available.
// Both are saved in cache. // Both are saved in cache.
void PresetUpdater::priv::sync_config(const std::set<VendorProfile> vendors) void PresetUpdater::priv::sync_config(const VendorMap vendors)
{ {
BOOST_LOG_TRIVIAL(info) << "Syncing configuration cache"; BOOST_LOG_TRIVIAL(info) << "Syncing configuration cache";
@ -276,13 +276,13 @@ void PresetUpdater::priv::sync_config(const std::set<VendorProfile> vendors)
for (auto &index : index_db) { for (auto &index : index_db) {
if (cancel) { return; } if (cancel) { return; }
const auto vendor_it = vendors.find(VendorProfile(index.vendor())); const auto vendor_it = vendors.find(index.vendor());
if (vendor_it == vendors.end()) { if (vendor_it == vendors.end()) {
BOOST_LOG_TRIVIAL(warning) << "No such vendor: " << index.vendor(); BOOST_LOG_TRIVIAL(warning) << "No such vendor: " << index.vendor();
continue; continue;
} }
const VendorProfile &vendor = *vendor_it; const VendorProfile &vendor = vendor_it->second;
if (vendor.config_update_url.empty()) { if (vendor.config_update_url.empty()) {
BOOST_LOG_TRIVIAL(info) << "Vendor has no config_update_url: " << vendor.name; BOOST_LOG_TRIVIAL(info) << "Vendor has no config_update_url: " << vendor.name;
continue; continue;
@ -574,7 +574,7 @@ void PresetUpdater::sync(PresetBundle *preset_bundle)
// Copy the whole vendors data for use in the background thread // Copy the whole vendors data for use in the background thread
// Unfortunatelly as of C++11, it needs to be copied again // Unfortunatelly as of C++11, it needs to be copied again
// into the closure (but perhaps the compiler can elide this). // into the closure (but perhaps the compiler can elide this).
std::set<VendorProfile> vendors = preset_bundle->vendors; VendorMap vendors = preset_bundle->vendors;
p->thread = std::move(std::thread([this, vendors]() { p->thread = std::move(std::thread([this, vendors]() {
this->p->prune_tmps(); this->p->prune_tmps();
@ -643,13 +643,10 @@ PresetUpdater::UpdateResult PresetUpdater::config_update() const
// (snapshot is taken beforehand) // (snapshot is taken beforehand)
p->perform_updates(std::move(updates)); p->perform_updates(std::move(updates));
GUI::ConfigWizard wizard(nullptr, GUI::ConfigWizard::RR_DATA_INCOMPAT); if (! GUI::wxGetApp().run_wizard(GUI::ConfigWizard::RR_DATA_INCOMPAT)) {
if (! wizard.run(GUI::wxGetApp().preset_bundle, this)) {
return R_INCOMPAT_EXIT; return R_INCOMPAT_EXIT;
} }
GUI::wxGetApp().load_current_presets();
return R_INCOMPAT_CONFIGURED; return R_INCOMPAT_CONFIGURED;
} else { } else {
BOOST_LOG_TRIVIAL(info) << "User wants to exit Slic3r, bye..."; BOOST_LOG_TRIVIAL(info) << "User wants to exit Slic3r, bye...";
@ -694,8 +691,8 @@ void PresetUpdater::install_bundles_rsrc(std::vector<std::string> bundles, bool
BOOST_LOG_TRIVIAL(info) << boost::format("Installing %1% bundles from resources ...") % bundles.size(); BOOST_LOG_TRIVIAL(info) << boost::format("Installing %1% bundles from resources ...") % bundles.size();
for (const auto &bundle : bundles) { for (const auto &bundle : bundles) {
auto path_in_rsrc = p->rsrc_path / bundle; auto path_in_rsrc = (p->rsrc_path / bundle).replace_extension(".ini");
auto path_in_vendors = p->vendor_path / bundle; auto path_in_vendors = (p->vendor_path / bundle).replace_extension(".ini");
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", ""); updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", "");
} }

View file

@ -11,7 +11,7 @@ add_library(Catch2::Catch2 ALIAS Catch2)
include(Catch) include(Catch)
add_library(test_catch2_common INTERFACE) add_library(test_catch2_common INTERFACE)
target_compile_definitions(test_catch2_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)") target_compile_definitions(test_catch2_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE)
target_link_libraries(test_catch2_common INTERFACE Catch2::Catch2) target_link_libraries(test_catch2_common INTERFACE Catch2::Catch2)
add_library(test_common INTERFACE) add_library(test_common INTERFACE)
@ -22,10 +22,10 @@ endif()
target_link_libraries(test_common INTERFACE test_catch2_common) target_link_libraries(test_common INTERFACE test_catch2_common)
# DEPRECATED: # DEPRECATED:
find_package(GTest REQUIRED) #find_package(GTest REQUIRED)
add_library(test_gtest_common INTERFACE) #add_library(test_gtest_common INTERFACE)
target_compile_definitions(test_gtest_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)") #target_compile_definitions(test_gtest_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)")
target_link_libraries(test_gtest_common INTERFACE GTest::GTest GTest::Main) #target_link_libraries(test_gtest_common INTERFACE GTest::GTest GTest::Main)
add_subdirectory(libnest2d) add_subdirectory(libnest2d)
add_subdirectory(timeutils) add_subdirectory(timeutils)

View file

@ -2,4 +2,5 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp printer_parts.cpp printer_parts.hpp) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp printer_parts.cpp printer_parts.hpp)
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES}) target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES})
catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")
add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes")

View file

@ -1,5 +1,6 @@
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#include <fstream> #include <fstream>
#include <libnest2d.h> #include <libnest2d.h>
@ -224,12 +225,12 @@ TEST_CASE("Area", "[Geometry]") {
using namespace libnest2d; using namespace libnest2d;
RectangleItem rect(10, 10); RectangleItem rect(10, 10);
REQUIRE(rect.area() == 100); REQUIRE(rect.area() == Approx(100));
RectangleItem rect2 = {100, 100}; RectangleItem rect2 = {100, 100};
REQUIRE(rect2.area() == 10000); REQUIRE(rect2.area() == Approx(10000));
Item item = { Item item = {
{61, 97}, {61, 97},
@ -288,11 +289,9 @@ TEST_CASE("IsPointInsidePolygon", "[Geometry]") {
// REQUIRE_FALSE(ShapeLike::intersects(s1, s2)); // REQUIRE_FALSE(ShapeLike::intersects(s1, s2));
//} //}
// Simple TEST_CASE, does not use gmock
TEST_CASE("LeftAndDownPolygon", "[Geometry]") TEST_CASE("LeftAndDownPolygon", "[Geometry]")
{ {
using namespace libnest2d; using namespace libnest2d;
using namespace libnest2d;
Box bin(100, 100); Box bin(100, 100);
BottomLeftPlacer placer(bin); BottomLeftPlacer placer(bin);
@ -339,7 +338,6 @@ TEST_CASE("LeftAndDownPolygon", "[Geometry]")
} }
} }
// Simple TEST_CASE, does not use gmock
TEST_CASE("ArrangeRectanglesTight", "[Nesting]") TEST_CASE("ArrangeRectanglesTight", "[Nesting]")
{ {
using namespace libnest2d; using namespace libnest2d;
@ -449,8 +447,8 @@ TEST_CASE("ArrangeRectanglesLoose", "[Nesting]")
[](const Item &i1, const Item &i2) { [](const Item &i1, const Item &i2) {
return i1.binId() < i2.binId(); return i1.binId() < i2.binId();
}); });
size_t groups = max_group == rects.end() ? 0 : max_group->binId() + 1; auto groups = size_t(max_group == rects.end() ? 0 : max_group->binId() + 1);
REQUIRE(groups == 1u); REQUIRE(groups == 1u);
REQUIRE( REQUIRE(
@ -477,8 +475,6 @@ using namespace libnest2d;
template<long long SCALE = 1, class Bin> template<long long SCALE = 1, class Bin>
void exportSVG(std::vector<std::reference_wrapper<Item>>& result, const Bin& bin, int idx = 0) { void exportSVG(std::vector<std::reference_wrapper<Item>>& result, const Bin& bin, int idx = 0) {
std::string loc = "out"; std::string loc = "out";
static std::string svg_header = static std::string svg_header =
@ -494,20 +490,20 @@ void exportSVG(std::vector<std::reference_wrapper<Item>>& result, const Bin& bin
if(out.is_open()) { if(out.is_open()) {
out << svg_header; out << svg_header;
Item rbin( RectangleItem(bin.width(), bin.height()) ); Item rbin( RectangleItem(bin.width(), bin.height()) );
for(unsigned i = 0; i < rbin.vertexCount(); i++) { for(unsigned j = 0; j < rbin.vertexCount(); j++) {
auto v = rbin.vertex(i); auto v = rbin.vertex(j);
setY(v, -getY(v)/SCALE + 500 ); setY(v, -getY(v)/SCALE + 500 );
setX(v, getX(v)/SCALE); setX(v, getX(v)/SCALE);
rbin.setVertex(i, v); rbin.setVertex(j, v);
} }
out << shapelike::serialize<Formats::SVG>(rbin.rawShape()) << std::endl; out << shapelike::serialize<Formats::SVG>(rbin.rawShape()) << std::endl;
for(Item& sh : r) { for(Item& sh : r) {
Item tsh(sh.transformedShape()); Item tsh(sh.transformedShape());
for(unsigned i = 0; i < tsh.vertexCount(); i++) { for(unsigned j = 0; j < tsh.vertexCount(); j++) {
auto v = tsh.vertex(i); auto v = tsh.vertex(j);
setY(v, -getY(v)/SCALE + 500); setY(v, -getY(v)/SCALE + 500);
setX(v, getX(v)/SCALE); setX(v, getX(v)/SCALE);
tsh.setVertex(i, v); tsh.setVertex(j, v);
} }
out << shapelike::serialize<Formats::SVG>(tsh.rawShape()) << std::endl; out << shapelike::serialize<Formats::SVG>(tsh.rawShape()) << std::endl;
} }
@ -570,7 +566,7 @@ TEST_CASE("convexHull", "[Geometry]") {
REQUIRE(chull.size() == poly.size()); REQUIRE(chull.size() == poly.size());
} }
TEST_CASE("NestPrusaPartsShouldFitIntoTwoBins", "[Nesting]") { TEST_CASE("PrusaPartsShouldFitIntoTwoBins", "[Nesting]") {
// Get the input items and define the bin. // Get the input items and define the bin.
std::vector<Item> input = prusaParts(); std::vector<Item> input = prusaParts();
@ -579,21 +575,15 @@ TEST_CASE("NestPrusaPartsShouldFitIntoTwoBins", "[Nesting]") {
// Do the nesting. Check in each step if the remaining items are less than // Do the nesting. Check in each step if the remaining items are less than
// in the previous step. (Some algorithms can place more items in one step) // in the previous step. (Some algorithms can place more items in one step)
size_t pcount = input.size(); size_t pcount = input.size();
libnest2d::nest(input, bin, [&pcount](unsigned cnt) {
REQUIRE(cnt < pcount);
pcount = cnt;
});
// Get the number of logical bins: search for the max binId... size_t bins = libnest2d::nest(input, bin, 0, {},
auto max_binid_it = std::max_element(input.begin(), input.end(), ProgressFunction{[&pcount](unsigned cnt) {
[](const Item &i1, const Item &i2) { REQUIRE(cnt < pcount);
return i1.binId() < i2.binId(); pcount = cnt;
}); }});
auto bins = size_t(max_binid_it == input.end() ? 0 :
max_binid_it->binId() + 1);
// For prusa parts, 2 bins should be enough... // For prusa parts, 2 bins should be enough...
REQUIRE(bins > 0u);
REQUIRE(bins <= 2u); REQUIRE(bins <= 2u);
// All parts should be processed by the algorithm // All parts should be processed by the algorithm
@ -617,29 +607,83 @@ TEST_CASE("NestPrusaPartsShouldFitIntoTwoBins", "[Nesting]") {
} }
} }
TEST_CASE("NestEmptyItemShouldBeUntouched", "[Nesting]") { TEST_CASE("EmptyItemShouldBeUntouched", "[Nesting]") {
auto bin = Box(250000000, 210000000); // dummy bin auto bin = Box(250000000, 210000000); // dummy bin
std::vector<Item> items; std::vector<Item> items;
items.emplace_back(Item{}); // Emplace empty item items.emplace_back(Item{}); // Emplace empty item
items.emplace_back(Item{0, 200, 0}); // Emplace zero area item items.emplace_back(Item{0, 200, 0}); // Emplace zero area item
libnest2d::nest(items, bin); size_t bins = libnest2d::nest(items, bin);
REQUIRE(bins == 0u);
for (auto &itm : items) REQUIRE(itm.binId() == BIN_ID_UNSET); for (auto &itm : items) REQUIRE(itm.binId() == BIN_ID_UNSET);
} }
TEST_CASE("NestLargeItemShouldBeUntouched", "[Nesting]") { TEST_CASE("LargeItemShouldBeUntouched", "[Nesting]") {
auto bin = Box(250000000, 210000000); // dummy bin auto bin = Box(250000000, 210000000); // dummy bin
std::vector<Item> items; std::vector<Item> items;
items.emplace_back(RectangleItem{250000001, 210000001}); // Emplace large item items.emplace_back(RectangleItem{250000001, 210000001}); // Emplace large item
libnest2d::nest(items, bin); size_t bins = libnest2d::nest(items, bin);
REQUIRE(bins == 0u);
REQUIRE(items.front().binId() == BIN_ID_UNSET); REQUIRE(items.front().binId() == BIN_ID_UNSET);
} }
TEST_CASE("Items can be preloaded", "[Nesting]") {
auto bin = Box({0, 0}, {250000000, 210000000}); // dummy bin
std::vector<Item> items;
items.reserve(2);
NestConfig<> cfg;
cfg.placer_config.alignment = NestConfig<>::Placement::Alignment::DONT_ALIGN;
items.emplace_back(RectangleItem{10000000, 10000000});
Item &fixed_rect = items.back();
fixed_rect.translate(bin.center());
items.emplace_back(RectangleItem{20000000, 20000000});
Item &movable_rect = items.back();
movable_rect.translate(bin.center());
SECTION("Preloaded Item should be untouched") {
fixed_rect.markAsFixedInBin(0);
size_t bins = libnest2d::nest(items, bin, 0, cfg);
REQUIRE(bins == 1);
REQUIRE(fixed_rect.binId() == 0);
REQUIRE(fixed_rect.translation().X == bin.center().X);
REQUIRE(fixed_rect.translation().Y == bin.center().Y);
REQUIRE(movable_rect.binId() == 0);
REQUIRE(movable_rect.translation().X != bin.center().X);
REQUIRE(movable_rect.translation().Y != bin.center().Y);
}
SECTION("Preloaded Item should not affect free bins") {
fixed_rect.markAsFixedInBin(1);
size_t bins = libnest2d::nest(items, bin, 0, cfg);
REQUIRE(bins == 2);
REQUIRE(fixed_rect.binId() == 1);
REQUIRE(fixed_rect.translation().X == bin.center().X);
REQUIRE(fixed_rect.translation().Y == bin.center().Y);
REQUIRE(movable_rect.binId() == 0);
auto bb = movable_rect.boundingBox();
REQUIRE(bb.center().X == bin.center().X);
REQUIRE(bb.center().Y == bin.center().Y);
}
}
namespace { namespace {
struct ItemPair { struct ItemPair {
@ -969,8 +1013,8 @@ TEST_CASE("mergePileWithPolygon", "[Geometry]") {
REQUIRE(result.size() == 1); REQUIRE(result.size() == 1);
RectangleItem ref(45, 15); RectangleItem ref(45, 15);
REQUIRE(shapelike::area(result.front()) == ref.area()); REQUIRE(shapelike::area(result.front()) == Approx(ref.area()));
} }
namespace { namespace {

View file

@ -1,5 +1,6 @@
get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp tests_main.cpp) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp)
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES}) target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES})
catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") #catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")
add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes")

View file

@ -1,3 +1,4 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#include <unordered_set> #include <unordered_set>
@ -358,10 +359,13 @@ template <class I, class II> void test_pairhash()
const I Ibits = int(sizeof(I) * CHAR_BIT); const I Ibits = int(sizeof(I) * CHAR_BIT);
const II IIbits = int(sizeof(II) * CHAR_BIT); const II IIbits = int(sizeof(II) * CHAR_BIT);
const int bits = IIbits / 2 < Ibits ? Ibits / 2 : Ibits;
int bits = IIbits / 2 < Ibits ? Ibits / 2 : Ibits;
if (std::is_signed<I>::value) bits -= 1;
const I Imin = std::is_signed<I>::value ? -I(std::pow(2., bits)) : 0;
const I Imax = I(std::pow(2., bits) - 1); const I Imax = I(std::pow(2., bits) - 1);
std::uniform_int_distribution<I> dis(0, Imax);
std::uniform_int_distribution<I> dis(Imin, Imax);
for (size_t i = 0; i < nums;) { for (size_t i = 0; i < nums;) {
I a = dis(gen); I a = dis(gen);
@ -395,6 +399,7 @@ template <class I, class II> void test_pairhash()
} }
TEST_CASE("Pillar pairhash should be unique", "[SLASupportGeneration]") { TEST_CASE("Pillar pairhash should be unique", "[SLASupportGeneration]") {
test_pairhash<int, int>();
test_pairhash<int, long>(); test_pairhash<int, long>();
test_pairhash<unsigned, unsigned>(); test_pairhash<unsigned, unsigned>();
test_pairhash<unsigned, unsigned long>(); test_pairhash<unsigned, unsigned long>();

View file

@ -1,2 +0,0 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

View file

@ -2,4 +2,5 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp)
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES}) target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES})
catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")
add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes")

View file

@ -12,18 +12,18 @@ namespace {
void test_time_fmt(Slic3r::Utils::TimeFormat fmt) { void test_time_fmt(Slic3r::Utils::TimeFormat fmt) {
using namespace Slic3r::Utils; using namespace Slic3r::Utils;
time_t t = get_current_time_utc(); time_t t = get_current_time_utc();
std::string tstr = time2str(t, TimeZone::local, fmt); std::string tstr = time2str(t, TimeZone::local, fmt);
time_t parsedtime = str2time(tstr, TimeZone::local, fmt); time_t parsedtime = str2time(tstr, TimeZone::local, fmt);
REQUIRE(t == parsedtime); REQUIRE(t == parsedtime);
tstr = time2str(t, TimeZone::utc, fmt); tstr = time2str(t, TimeZone::utc, fmt);
parsedtime = str2time(tstr, TimeZone::utc, fmt); parsedtime = str2time(tstr, TimeZone::utc, fmt);
REQUIRE(t == parsedtime); REQUIRE(t == parsedtime);
parsedtime = str2time("not valid string", TimeZone::local, fmt); parsedtime = str2time("not valid string", TimeZone::local, fmt);
REQUIRE(parsedtime == time_t(-1)); REQUIRE(parsedtime == time_t(-1));
parsedtime = str2time("not valid string", TimeZone::utc, fmt); parsedtime = str2time("not valid string", TimeZone::utc, fmt);
REQUIRE(parsedtime == time_t(-1)); REQUIRE(parsedtime == time_t(-1));
} }
@ -31,8 +31,21 @@ void test_time_fmt(Slic3r::Utils::TimeFormat fmt) {
TEST_CASE("ISO8601Z", "[Timeutils]") { TEST_CASE("ISO8601Z", "[Timeutils]") {
test_time_fmt(Slic3r::Utils::TimeFormat::iso8601Z); test_time_fmt(Slic3r::Utils::TimeFormat::iso8601Z);
std::string mydate = "20190710T085000Z";
time_t t = Slic3r::Utils::parse_iso_utc_timestamp(mydate);
std::string date = Slic3r::Utils::iso_utc_timestamp(t);
REQUIRE(date == mydate);
} }
TEST_CASE("Slic3r_UTC_Time_Format", "[Timeutils]") { TEST_CASE("Slic3r_UTC_Time_Format", "[Timeutils]") {
test_time_fmt(Slic3r::Utils::TimeFormat::gcode); using namespace Slic3r::Utils;
test_time_fmt(TimeFormat::gcode);
std::string mydate = "2019-07-10 at 08:50:00 UTC";
time_t t = Slic3r::Utils::str2time(mydate, TimeZone::utc, TimeFormat::gcode);
std::string date = Slic3r::Utils::utc_timestamp(t);
REQUIRE(date == mydate);
} }