Merge branch 'master' into fs_emboss_temp
This commit is contained in:
commit
75f5acb4ff
46 changed files with 4105 additions and 3687 deletions
|
@ -1,4 +1,8 @@
|
||||||
|
min_slic3r_version = 2.6.0-alpha2
|
||||||
|
0.2.1 Added Eolas Prints filaments.
|
||||||
|
0.2.0 Added Photon Mono X printer.
|
||||||
min_slic3r_version = 2.4.1-rc1
|
min_slic3r_version = 2.4.1-rc1
|
||||||
|
0.1.2 Added VOXELPLA filament profile.
|
||||||
0.1.1 Fixed before layer change g-code for Mega Zero.
|
0.1.1 Fixed before layer change g-code for Mega Zero.
|
||||||
0.1.0 Added Anycubic 4Max Pro 2.0
|
0.1.0 Added Anycubic 4Max Pro 2.0
|
||||||
min_slic3r_version = 2.3.2-alpha0
|
min_slic3r_version = 2.3.2-alpha0
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name = Anycubic
|
name = Anycubic
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.1.1
|
config_version = 0.2.1
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -738,6 +738,17 @@ first_layer_temperature = 245
|
||||||
filament_cost = 24.99
|
filament_cost = 24.99
|
||||||
filament_density = 1.27
|
filament_density = 1.27
|
||||||
|
|
||||||
|
[filament:VOXELPLA PLUS @MEGA0]
|
||||||
|
inherits = *PLA_mega0*
|
||||||
|
filament_vendor = VOXELPLA
|
||||||
|
temperature = 200
|
||||||
|
bed_temperature = 55
|
||||||
|
first_layer_temperature = 200
|
||||||
|
first_layer_bed_temperature = 55
|
||||||
|
filament_cost = 16.99
|
||||||
|
filament_density = 1.24
|
||||||
|
filament_colour = #FF4640
|
||||||
|
|
||||||
# Common printer preset
|
# Common printer preset
|
||||||
[printer:*common_mega0*]
|
[printer:*common_mega0*]
|
||||||
printer_technology = FFF
|
printer_technology = FFF
|
||||||
|
@ -1050,6 +1061,68 @@ max_fan_speed = 50
|
||||||
min_fan_speed = 30
|
min_fan_speed = 30
|
||||||
temperature = 240
|
temperature = 240
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA @MEGA]
|
||||||
|
inherits = *PLA_mega*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 23.50
|
||||||
|
filament_density = 1.24
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
first_layer_bed_temperature = 65
|
||||||
|
first_layer_temperature = 212
|
||||||
|
temperature = 208
|
||||||
|
bed_temperature = 60
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA Matte @MEGA]
|
||||||
|
inherits = Eolas Prints PLA @MEGA
|
||||||
|
filament_cost = 25.50
|
||||||
|
filament_max_volumetric_speed = 14
|
||||||
|
temperature = 212
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 850 @MEGA]
|
||||||
|
inherits = Eolas Prints PLA @MEGA
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 870 @MEGA]
|
||||||
|
inherits = Eolas Prints PLA @MEGA
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 215
|
||||||
|
first_layer_bed_temperature = 68
|
||||||
|
first_layer_temperature = 220
|
||||||
|
bed_temperature = 65
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG @MEGA]
|
||||||
|
inherits = *PETG_mega*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 29.90
|
||||||
|
filament_density = 1.27
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
temperature = 240
|
||||||
|
first_layer_bed_temperature = 85
|
||||||
|
first_layer_temperature = 235
|
||||||
|
bed_temperature = 90
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG - UV Resistant @MEGA]
|
||||||
|
inherits = Eolas Prints PETG @MEGA
|
||||||
|
filament_cost = 35.90
|
||||||
|
temperature = 242
|
||||||
|
first_layer_temperature = 237
|
||||||
|
|
||||||
|
[filament:Eolas Prints TPU 93A @MEGA]
|
||||||
|
inherits = *FLEX_mega*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 34.99
|
||||||
|
filament_density = 1.21
|
||||||
|
filament_colour = #4D9398
|
||||||
|
filament_max_volumetric_speed = 1.2
|
||||||
|
temperature = 235
|
||||||
|
first_layer_bed_temperature = 30
|
||||||
|
bed_temperature = 30
|
||||||
|
filament_retract_length = 0
|
||||||
|
extrusion_multiplier = 1.16
|
||||||
|
|
||||||
[filament:Generic PETG @MEGA]
|
[filament:Generic PETG @MEGA]
|
||||||
inherits = *PETG_mega*
|
inherits = *PETG_mega*
|
||||||
|
|
||||||
|
@ -1177,6 +1250,17 @@ inherits = *PLA_mega*
|
||||||
filament_vendor = Verbatim
|
filament_vendor = Verbatim
|
||||||
filament_cost = 23.88
|
filament_cost = 23.88
|
||||||
|
|
||||||
|
[filament:VOXELPLA PLUS @MEGA]
|
||||||
|
inherits = *PLA_mega*
|
||||||
|
filament_vendor = VOXELPLA
|
||||||
|
temperature = 200
|
||||||
|
bed_temperature = 55
|
||||||
|
first_layer_temperature = 200
|
||||||
|
first_layer_bed_temperature = 55
|
||||||
|
filament_cost = 16.99
|
||||||
|
filament_density = 1.24
|
||||||
|
filament_colour = #FF4640
|
||||||
|
|
||||||
[printer:*common_mega*]
|
[printer:*common_mega*]
|
||||||
printer_technology = FFF
|
printer_technology = FFF
|
||||||
bed_shape = 0x0,210x0,210x210,0x210
|
bed_shape = 0x0,210x0,210x210,0x210
|
||||||
|
@ -2240,7 +2324,7 @@ variable_layer_height = 1
|
||||||
wipe = 0
|
wipe = 0
|
||||||
z_offset = 0
|
z_offset = 0
|
||||||
|
|
||||||
########## SLA printer presets ##########
|
## SLA printers
|
||||||
|
|
||||||
[sla_print:*common print ANYCUBIC SLA*]
|
[sla_print:*common print ANYCUBIC SLA*]
|
||||||
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
||||||
|
@ -2275,7 +2359,7 @@ support_small_pillar_diameter_percent = 60%
|
||||||
inherits = *common print ANYCUBIC SLA*
|
inherits = *common print ANYCUBIC SLA*
|
||||||
layer_height = 0.05
|
layer_height = 0.05
|
||||||
|
|
||||||
########### Materials
|
## SLA materials
|
||||||
|
|
||||||
[sla_material:*common ANYCUBIC SLA*]
|
[sla_material:*common ANYCUBIC SLA*]
|
||||||
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
||||||
|
@ -2298,7 +2382,7 @@ material_vendor = Generic
|
||||||
material_colour = #6080EC
|
material_colour = #6080EC
|
||||||
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
||||||
|
|
||||||
########## Printers
|
## Printers
|
||||||
|
|
||||||
[printer:Anycubic Photon Mono X]
|
[printer:Anycubic Photon Mono X]
|
||||||
printer_technology = SLA
|
printer_technology = SLA
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
min_slic3r_version = 2.4.1-alpha0
|
min_slic3r_version = 2.4.1-alpha0
|
||||||
|
0.0.7 Added Eolas Prints filaments.
|
||||||
|
0.0.6 Reduced retract_length for direct extruders
|
||||||
0.0.5 Added Artillery Hornet
|
0.0.5 Added Artillery Hornet
|
||||||
min_slic3r_version = 2.3.1-beta
|
min_slic3r_version = 2.3.1-beta
|
||||||
0.0.4 Fixed first layer height in 0.28mm profile.
|
0.0.4 Fixed first layer height in 0.28mm profile.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
name = Artillery
|
name = Artillery
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.0.5
|
config_version = 0.0.7
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Artillery/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Artillery/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -89,7 +89,7 @@ remaining_times = 0
|
||||||
retract_before_travel = 1
|
retract_before_travel = 1
|
||||||
retract_before_wipe = 0%
|
retract_before_wipe = 0%
|
||||||
retract_layer_change = 1
|
retract_layer_change = 1
|
||||||
retract_length = 1.9
|
retract_length = 0.8
|
||||||
retract_length_toolchange = 4
|
retract_length_toolchange = 4
|
||||||
retract_lift = 0.6
|
retract_lift = 0.6
|
||||||
retract_lift_above = 0
|
retract_lift_above = 0
|
||||||
|
@ -513,3 +513,64 @@ filament_vendor = Generic
|
||||||
[filament:Generic TPU @Artillery]
|
[filament:Generic TPU @Artillery]
|
||||||
inherits = *TPU*
|
inherits = *TPU*
|
||||||
filament_vendor = Generic
|
filament_vendor = Generic
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA @Artillery]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 23.50
|
||||||
|
filament_density = 1.24
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
first_layer_bed_temperature = 65
|
||||||
|
first_layer_temperature = 208
|
||||||
|
temperature = 202
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA Matte @Artillery]
|
||||||
|
inherits = Eolas Prints PLA @Artillery
|
||||||
|
filament_cost = 25.50
|
||||||
|
filament_max_volumetric_speed = 14
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 850 @Artillery]
|
||||||
|
inherits = Eolas Prints PLA @Artillery
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 870 @Artillery]
|
||||||
|
inherits = Eolas Prints PLA @Artillery
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 215
|
||||||
|
first_layer_bed_temperature = 68
|
||||||
|
first_layer_temperature = 220
|
||||||
|
bed_temperature = 65
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG @Artillery]
|
||||||
|
inherits = *PET*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 29.90
|
||||||
|
filament_density = 1.27
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
temperature = 240
|
||||||
|
first_layer_bed_temperature = 85
|
||||||
|
first_layer_temperature = 235
|
||||||
|
bed_temperature = 90
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG - UV Resistant @Artillery]
|
||||||
|
inherits = Eolas Prints PETG @Artillery
|
||||||
|
filament_cost = 35.90
|
||||||
|
temperature = 242
|
||||||
|
first_layer_temperature = 237
|
||||||
|
|
||||||
|
[filament:Eolas Prints TPU 93A @Artillery]
|
||||||
|
inherits = *TPU*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 34.99
|
||||||
|
filament_density = 1.21
|
||||||
|
filament_colour = #4D9398
|
||||||
|
filament_max_volumetric_speed = 1.2
|
||||||
|
temperature = 230
|
||||||
|
first_layer_bed_temperature = 30
|
||||||
|
bed_temperature = 30
|
||||||
|
filament_retract_length = 0
|
||||||
|
extrusion_multiplier = 1.16
|
|
@ -1,4 +1,5 @@
|
||||||
min_slic3r_version = 2.6.0-alpha0
|
min_slic3r_version = 2.6.0-alpha0
|
||||||
|
0.2.7 Added Eolas Prints filaments.
|
||||||
0.2.6 Add Ender-5 Pro, Ender-5 S1, Sermoon-V1, Sermoon-V1 Pro. Unlock HIGHSPEED/SUPERSPEED presets for Ender-5 S1/Ender-6/Ender-7.
|
0.2.6 Add Ender-5 Pro, Ender-5 S1, Sermoon-V1, Sermoon-V1 Pro. Unlock HIGHSPEED/SUPERSPEED presets for Ender-5 S1/Ender-6/Ender-7.
|
||||||
min_slic3r_version = 2.5.0-alpha0
|
min_slic3r_version = 2.5.0-alpha0
|
||||||
0.2.4 Add SPEED presets. More conservative extruder clearance.
|
0.2.4 Add SPEED presets. More conservative extruder clearance.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name = Creality
|
name = Creality
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.2.6
|
config_version = 0.2.7
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -1510,7 +1510,66 @@ filament_cost = 28.99
|
||||||
filament_density = 1.12
|
filament_density = 1.12
|
||||||
filament_colour = #3598DB
|
filament_colour = #3598DB
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA @CREALITY]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 23.50
|
||||||
|
filament_density = 1.24
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
first_layer_bed_temperature = 65
|
||||||
|
first_layer_temperature = 208
|
||||||
|
temperature = 202
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA Matte @CREALITY]
|
||||||
|
inherits = Eolas Prints PLA @CREALITY
|
||||||
|
filament_cost = 25.50
|
||||||
|
filament_max_volumetric_speed = 14
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 850 @CREALITY]
|
||||||
|
inherits = Eolas Prints PLA @CREALITY
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 870 @CREALITY]
|
||||||
|
inherits = Eolas Prints PLA @CREALITY
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 215
|
||||||
|
first_layer_bed_temperature = 68
|
||||||
|
first_layer_temperature = 220
|
||||||
|
bed_temperature = 65
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG @CREALITY]
|
||||||
|
inherits = *PET*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 29.90
|
||||||
|
filament_density = 1.27
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
temperature = 240
|
||||||
|
first_layer_bed_temperature = 85
|
||||||
|
first_layer_temperature = 235
|
||||||
|
bed_temperature = 90
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG - UV Resistant @CREALITY]
|
||||||
|
inherits = Eolas Prints PETG @CREALITY
|
||||||
|
filament_cost = 35.90
|
||||||
|
temperature = 242
|
||||||
|
first_layer_temperature = 237
|
||||||
|
|
||||||
|
[filament:Eolas Prints TPU 93A @CREALITY]
|
||||||
|
inherits = *TPU*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 34.99
|
||||||
|
filament_density = 1.21
|
||||||
|
filament_colour = #4D9398
|
||||||
|
filament_max_volumetric_speed = 1.2
|
||||||
|
temperature = 235
|
||||||
|
first_layer_bed_temperature = 30
|
||||||
|
bed_temperature = 30
|
||||||
|
filament_retract_length = 0
|
||||||
|
extrusion_multiplier = 1.16
|
||||||
|
|
||||||
# Common printer preset
|
# Common printer preset
|
||||||
[printer:*common*]
|
[printer:*common*]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
min_slic3r_version = 2.6.0-alpha1
|
min_slic3r_version = 2.6.0-alpha1
|
||||||
|
1.0.3 Added Eolas Prints filaments.
|
||||||
1.0.2 Added new printer models.
|
1.0.2 Added new printer models.
|
||||||
min_slic3r_version = 2.5.0-alpha3
|
min_slic3r_version = 2.5.0-alpha3
|
||||||
1.0.1 Decreased bed size to 220x220.
|
1.0.1 Decreased bed size to 220x220.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
name = Elegoo
|
name = Elegoo
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 1.0.2
|
config_version = 1.0.3
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Elegoo/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Elegoo/
|
||||||
|
|
||||||
# The printer models will be shown by the Configuration Wizard in this order,
|
# The printer models will be shown by the Configuration Wizard in this order,
|
||||||
|
@ -365,6 +365,54 @@ first_layer_bed_temperature = 90
|
||||||
bed_temperature = 90
|
bed_temperature = 90
|
||||||
filament_vendor = Generic
|
filament_vendor = Generic
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA @ELEGOO]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 23.50
|
||||||
|
filament_density = 1.24
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
first_layer_bed_temperature = 65
|
||||||
|
first_layer_temperature = 208
|
||||||
|
temperature = 202
|
||||||
|
|
||||||
|
[filament:Eolas Prints PLA Matte @ELEGOO]
|
||||||
|
inherits = Eolas Prints PLA @ELEGOO
|
||||||
|
filament_cost = 25.50
|
||||||
|
filament_max_volumetric_speed = 14
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 850 @ELEGOO]
|
||||||
|
inherits = Eolas Prints PLA @ELEGOO
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
|
[filament:Eolas Prints INGEO 870 @ELEGOO]
|
||||||
|
inherits = Eolas Prints PLA @ELEGOO
|
||||||
|
filament_cost = 25.90
|
||||||
|
temperature = 215
|
||||||
|
first_layer_bed_temperature = 68
|
||||||
|
first_layer_temperature = 220
|
||||||
|
bed_temperature = 65
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG @ELEGOO]
|
||||||
|
inherits = *PET*
|
||||||
|
filament_vendor = Eolas Prints
|
||||||
|
filament_cost = 29.90
|
||||||
|
filament_density = 1.27
|
||||||
|
filament_spool_weight = 0
|
||||||
|
filament_colour = #4D9398
|
||||||
|
temperature = 240
|
||||||
|
first_layer_bed_temperature = 85
|
||||||
|
first_layer_temperature = 235
|
||||||
|
bed_temperature = 90
|
||||||
|
|
||||||
|
[filament:Eolas Prints PETG - UV Resistant @ELEGOO]
|
||||||
|
inherits = Eolas Prints PETG @ELEGOO
|
||||||
|
filament_cost = 35.90
|
||||||
|
temperature = 242
|
||||||
|
first_layer_temperature = 237
|
||||||
|
|
||||||
# Common printer preset
|
# Common printer preset
|
||||||
[printer:*common*]
|
[printer:*common*]
|
||||||
printer_technology = FFF
|
printer_technology = FFF
|
||||||
|
|
|
@ -72,6 +72,8 @@ int CLI::run(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Mark the main thread for the debugger and for runtime checks.
|
// Mark the main thread for the debugger and for runtime checks.
|
||||||
set_current_thread_name("slic3r_main");
|
set_current_thread_name("slic3r_main");
|
||||||
|
// Save the thread ID of the main thread.
|
||||||
|
save_main_thread_id();
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// On Linux, wxGTK has no support for Wayland, and the app crashes on
|
// On Linux, wxGTK has no support for Wayland, and the app crashes on
|
||||||
|
|
|
@ -417,12 +417,8 @@ std::string AppConfig::load()
|
||||||
|
|
||||||
void AppConfig::save()
|
void AppConfig::save()
|
||||||
{
|
{
|
||||||
{
|
if (! is_main_thread_active())
|
||||||
// Returns "undefined" if the thread naming functionality is not supported by the operating system.
|
|
||||||
std::optional<std::string> current_thread_name = get_current_thread_name();
|
|
||||||
if (current_thread_name && *current_thread_name != "slic3r_main")
|
|
||||||
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
||||||
}
|
|
||||||
|
|
||||||
// The config is first written to a file with a PID suffix and then moved
|
// The config is first written to a file with a PID suffix and then moved
|
||||||
// to avoid race conditions with multiple instances of Slic3r
|
// to avoid race conditions with multiple instances of Slic3r
|
||||||
|
|
|
@ -361,6 +361,8 @@ inline Slic3r::Polygons expand(const Slic3r::Polygon &polygon, const float del
|
||||||
{ assert(delta > 0); return offset(polygon, delta, joinType, miterLimit); }
|
{ assert(delta > 0); return offset(polygon, delta, joinType, miterLimit); }
|
||||||
inline Slic3r::Polygons expand(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
inline Slic3r::Polygons expand(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
||||||
{ assert(delta > 0); return offset(polygons, delta, joinType, miterLimit); }
|
{ assert(delta > 0); return offset(polygons, delta, joinType, miterLimit); }
|
||||||
|
inline Slic3r::Polygons expand(const Slic3r::ExPolygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
||||||
|
{ assert(delta > 0); return offset(polygons, delta, joinType, miterLimit); }
|
||||||
inline Slic3r::ExPolygons expand_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
inline Slic3r::ExPolygons expand_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
||||||
{ assert(delta > 0); return offset_ex(polygons, delta, joinType, miterLimit); }
|
{ assert(delta > 0); return offset_ex(polygons, delta, joinType, miterLimit); }
|
||||||
// Input polygons for shrinking shall be "normalized": There must be no overlap / intersections between the input polygons.
|
// Input polygons for shrinking shall be "normalized": There must be no overlap / intersections between the input polygons.
|
||||||
|
|
|
@ -268,7 +268,7 @@ ConfigOption* ConfigOptionDef::create_empty_option() const
|
||||||
// case coPoint3s: return new ConfigOptionPoint3s();
|
// case coPoint3s: return new ConfigOptionPoint3s();
|
||||||
case coBool: return new ConfigOptionBool();
|
case coBool: return new ConfigOptionBool();
|
||||||
case coBools: return new ConfigOptionBools();
|
case coBools: return new ConfigOptionBools();
|
||||||
case coEnum: return new ConfigOptionEnumGeneric(this->enum_keys_map);
|
case coEnum: return new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map);
|
||||||
default: throw ConfigurationError(std::string("Unknown option type for option ") + this->label);
|
default: throw ConfigurationError(std::string("Unknown option type for option ") + this->label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ ConfigOption* ConfigOptionDef::create_default_option() const
|
||||||
if (this->default_value)
|
if (this->default_value)
|
||||||
return (this->default_value->type() == coEnum) ?
|
return (this->default_value->type() == coEnum) ?
|
||||||
// Special case: For a DynamicConfig, convert a templated enum to a generic enum.
|
// Special case: For a DynamicConfig, convert a templated enum to a generic enum.
|
||||||
new ConfigOptionEnumGeneric(this->enum_keys_map, this->default_value->getInt()) :
|
new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map, this->default_value->getInt()) :
|
||||||
this->default_value->clone();
|
this->default_value->clone();
|
||||||
return this->create_empty_option();
|
return this->create_empty_option();
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,31 @@ ConfigOptionDef* ConfigDef::add_nullable(const t_config_option_key &opt_key, Con
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigDef::finalize()
|
||||||
|
{
|
||||||
|
// Validate & finalize open & closed enums.
|
||||||
|
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options) {
|
||||||
|
ConfigOptionDef& def = kvp.second;
|
||||||
|
if (def.type == coEnum) {
|
||||||
|
assert(def.enum_def);
|
||||||
|
assert(def.enum_def->is_valid_closed_enum());
|
||||||
|
assert(def.gui_type != ConfigOptionDef::GUIType::i_enum_open &&
|
||||||
|
def.gui_type != ConfigOptionDef::GUIType::f_enum_open &&
|
||||||
|
def.gui_type != ConfigOptionDef::GUIType::select_open);
|
||||||
|
def.enum_def->finalize_closed_enum();
|
||||||
|
} else if (def.gui_type == ConfigOptionDef::GUIType::i_enum_open || def.gui_type == ConfigOptionDef::GUIType::f_enum_open ||
|
||||||
|
def.gui_type == ConfigOptionDef::GUIType::select_open) {
|
||||||
|
assert(def.enum_def);
|
||||||
|
assert(def.enum_def->is_valid_open_enum());
|
||||||
|
assert(def.gui_type != ConfigOptionDef::GUIType::i_enum_open || def.type == coInt || def.type == coInts);
|
||||||
|
assert(def.gui_type != ConfigOptionDef::GUIType::f_enum_open || def.type == coFloat || def.type == coPercent || def.type == coFloatOrPercent);
|
||||||
|
assert(def.gui_type != ConfigOptionDef::GUIType::select_open || def.type == coString || def.type == coStrings);
|
||||||
|
} else {
|
||||||
|
assert(! def.enum_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, std::function<bool(const ConfigOptionDef &)> filter) const
|
std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, std::function<bool(const ConfigOptionDef &)> filter) const
|
||||||
{
|
{
|
||||||
// prepare a function for wrapping text
|
// prepare a function for wrapping text
|
||||||
|
@ -378,8 +403,8 @@ std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, s
|
||||||
descr += " (";
|
descr += " (";
|
||||||
if (!def.sidetext.empty()) {
|
if (!def.sidetext.empty()) {
|
||||||
descr += def.sidetext + ", ";
|
descr += def.sidetext + ", ";
|
||||||
} else if (!def.enum_values.empty()) {
|
} else if (def.enum_def->has_values()) {
|
||||||
descr += boost::algorithm::join(def.enum_values, ", ") + "; ";
|
descr += boost::algorithm::join(def.enum_def->values(), ", ") + "; ";
|
||||||
}
|
}
|
||||||
descr += "default: " + def.default_value->serialize() + ")";
|
descr += "default: " + def.default_value->serialize() + ")";
|
||||||
}
|
}
|
||||||
|
@ -1142,7 +1167,7 @@ bool DynamicConfig::read_cli(int argc, const char* const argv[], t_config_option
|
||||||
}
|
}
|
||||||
|
|
||||||
const t_config_option_key &opt_key = it->second;
|
const t_config_option_key &opt_key = it->second;
|
||||||
const ConfigOptionDef &optdef = this->def()->options.at(opt_key);
|
const ConfigOptionDef &optdef = *this->option_def(opt_key);
|
||||||
|
|
||||||
// If the option type expects a value and it was not already provided,
|
// If the option type expects a value and it was not already provided,
|
||||||
// look for it in the next token.
|
// look for it in the next token.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
|
@ -226,6 +227,7 @@ enum ForwardCompatibilitySubstitutionRule
|
||||||
EnableSilentDisableSystem,
|
EnableSilentDisableSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConfigDef;
|
||||||
class ConfigOption;
|
class ConfigOption;
|
||||||
class ConfigOptionDef;
|
class ConfigOptionDef;
|
||||||
// For forward definition of ConfigOption in ConfigOptionUniquePtr, we have to define a custom deleter.
|
// For forward definition of ConfigOption in ConfigOptionUniquePtr, we have to define a custom deleter.
|
||||||
|
@ -1547,7 +1549,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map from an enum name to an enum integer value.
|
// Map from an enum integer value to name.
|
||||||
static const t_config_enum_names& get_enum_names();
|
static const t_config_enum_names& get_enum_names();
|
||||||
// Map from an enum name to an enum integer value.
|
// Map from an enum name to an enum integer value.
|
||||||
static const t_config_enum_values& get_enum_values();
|
static const t_config_enum_values& get_enum_values();
|
||||||
|
@ -1619,6 +1621,177 @@ private:
|
||||||
template<class Archive> void serialize(Archive& ar) { ar(cereal::base_class<ConfigOptionInt>(this)); }
|
template<class Archive> void serialize(Archive& ar) { ar(cereal::base_class<ConfigOptionInt>(this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Definition of values / labels for a combo box.
|
||||||
|
// Mostly used for closed enums (when type == coEnum), but may be used for
|
||||||
|
// open enums with ints resp. floats, if gui_type is set to GUIType::i_enum_open" resp. GUIType::f_enum_open.
|
||||||
|
class ConfigOptionEnumDef {
|
||||||
|
public:
|
||||||
|
bool has_values() const { return ! m_values.empty(); }
|
||||||
|
bool has_labels() const { return ! m_labels.empty(); }
|
||||||
|
const std::vector<std::string>& values() const { return m_values; }
|
||||||
|
const std::string& value(int idx) const { return m_values[idx]; }
|
||||||
|
// Used for open enums (gui_type is set to GUIType::i_enum_open" resp. GUIType::f_enum_open).
|
||||||
|
// If values not defined, use labels.
|
||||||
|
const std::vector<std::string>& enums() const {
|
||||||
|
assert(this->is_valid_open_enum());
|
||||||
|
return this->has_values() ? m_values : m_labels;
|
||||||
|
}
|
||||||
|
// Used for closed enums. If labels are not defined, use values instead.
|
||||||
|
const std::vector<std::string>& labels() const { return this->has_labels() ? m_labels : m_values; }
|
||||||
|
const std::string& label(int idx) const { return this->labels()[idx]; }
|
||||||
|
|
||||||
|
// Look up a closed enum value of this combo box based on an index of the combo box value / label.
|
||||||
|
// Such a mapping should always succeed.
|
||||||
|
int index_to_enum(int index) const {
|
||||||
|
// It has to be a closed enum, thus values have to be defined.
|
||||||
|
assert(this->is_valid_closed_enum());
|
||||||
|
assert(index >= 0 && index < int(m_values.size()));
|
||||||
|
if (m_values_ordinary)
|
||||||
|
return index;
|
||||||
|
else {
|
||||||
|
auto it = m_enum_keys_map->find(m_values[index]);
|
||||||
|
assert(it != m_enum_keys_map->end());
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up an index of value / label of this combo box based on enum value.
|
||||||
|
// Such a mapping may fail, thus an optional is returned.
|
||||||
|
std::optional<int> enum_to_index(int enum_val) const {
|
||||||
|
assert(this->is_valid_closed_enum());
|
||||||
|
assert(enum_val >= 0 && enum_val < int(m_enum_names->size()));
|
||||||
|
if (m_values_ordinary)
|
||||||
|
return { enum_val };
|
||||||
|
else {
|
||||||
|
auto it = std::find(m_values.begin(), m_values.end(), (*m_enum_names)[enum_val]);
|
||||||
|
return it == m_values.end() ? std::optional<int>{} : std::optional<int>{ int(it - m_values.begin()) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up an index of value / label of this combo box based on value string.
|
||||||
|
std::optional<int> value_to_index(const std::string &value) const {
|
||||||
|
assert(this->is_valid_open_enum() || this->is_valid_closed_enum());
|
||||||
|
auto it = std::find(m_values.begin(), m_values.end(), value);
|
||||||
|
return it == m_values.end() ?
|
||||||
|
std::optional<int>{} : std::optional<int>{ it - m_values.begin() };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up an index of label of this combo box. Used for open enums.
|
||||||
|
std::optional<int> label_to_index(const std::string &value) const {
|
||||||
|
assert(is_valid_open_enum());
|
||||||
|
const auto &ls = this->labels();
|
||||||
|
auto it = std::find(ls.begin(), ls.end(), value);
|
||||||
|
return it == ls.end() ?
|
||||||
|
std::optional<int>{} : std::optional<int>{ it - ls.begin() };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<const std::string>> enum_to_value(int enum_val) const {
|
||||||
|
assert(this->is_valid_closed_enum());
|
||||||
|
auto opt = this->enum_to_index(enum_val);
|
||||||
|
return opt.has_value() ?
|
||||||
|
std::optional<std::reference_wrapper<const std::string>>{ this->value(*opt) } :
|
||||||
|
std::optional<std::reference_wrapper<const std::string>>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<const std::string>> enum_to_label(int enum_val) const {
|
||||||
|
assert(this->is_valid_closed_enum());
|
||||||
|
auto opt = this->enum_to_index(enum_val);
|
||||||
|
return opt.has_value() ?
|
||||||
|
std::optional<std::reference_wrapper<const std::string>>{ this->label(*opt) } :
|
||||||
|
std::optional<std::reference_wrapper<const std::string>>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
bool is_valid_closed_enum() const {
|
||||||
|
return m_enum_names != nullptr && m_enum_keys_map != nullptr &&
|
||||||
|
! m_values.empty() && (m_labels.empty() || m_values.size() == m_labels.size());
|
||||||
|
}
|
||||||
|
bool is_valid_open_enum() const {
|
||||||
|
return m_enum_names == nullptr && m_enum_keys_map == nullptr &&
|
||||||
|
(! m_values.empty() || ! m_labels.empty()) && (m_values.empty() || m_labels.empty() || m_values.size() == m_labels.size());
|
||||||
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
m_values_ordinary = false;
|
||||||
|
m_enum_names = nullptr;
|
||||||
|
m_enum_keys_map = nullptr;
|
||||||
|
m_values.clear();
|
||||||
|
m_labels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigOptionEnumDef* clone() const { return new ConfigOptionEnumDef{ *this }; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend ConfigDef;
|
||||||
|
friend ConfigOptionDef;
|
||||||
|
|
||||||
|
// Only allow ConfigOptionEnumDef() to be created from ConfigOptionDef.
|
||||||
|
ConfigOptionEnumDef() = default;
|
||||||
|
|
||||||
|
void set_values(const std::vector<std::string> &v) {
|
||||||
|
m_values = v;
|
||||||
|
assert(m_labels.empty() || m_labels.size() == m_values.size());
|
||||||
|
}
|
||||||
|
void set_values(const std::initializer_list<std::string_view> il) {
|
||||||
|
m_values.clear();
|
||||||
|
m_values.reserve(il.size());
|
||||||
|
for (const std::string_view p : il)
|
||||||
|
m_values.emplace_back(p);
|
||||||
|
assert(m_labels.empty() || m_labels.size() == m_values.size());
|
||||||
|
}
|
||||||
|
void set_values(const std::initializer_list<std::pair<std::string_view, std::string_view>> il) {
|
||||||
|
m_values.clear();
|
||||||
|
m_values.reserve(il.size());
|
||||||
|
m_labels.clear();
|
||||||
|
m_labels.reserve(il.size());
|
||||||
|
for (const std::pair<std::string_view, std::string_view> p : il) {
|
||||||
|
m_values.emplace_back(p.first);
|
||||||
|
m_labels.emplace_back(p.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void set_labels(const std::initializer_list<std::string_view> il) {
|
||||||
|
m_labels.clear();
|
||||||
|
m_labels.reserve(il.size());
|
||||||
|
for (const std::string_view p : il)
|
||||||
|
m_labels.emplace_back(p);
|
||||||
|
assert(m_values.empty() || m_labels.size() == m_values.size());
|
||||||
|
}
|
||||||
|
void finalize_closed_enum() {
|
||||||
|
assert(this->is_valid_closed_enum());
|
||||||
|
// Check whether def.enum_values contains all the values of def.enum_keys_map and
|
||||||
|
// that they are sorted by their ordinary values.
|
||||||
|
m_values_ordinary = true;
|
||||||
|
for (const std::pair<std::string, int>& key : *m_enum_keys_map) {
|
||||||
|
assert(key.second >= 0);
|
||||||
|
if (key.second >= this->values().size() || this->value(key.second) != key.first) {
|
||||||
|
m_values_ordinary = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> m_values;
|
||||||
|
std::vector<std::string> m_labels;
|
||||||
|
// If true, then enum_values are sorted and they contain all the values, thus the UI element ordinary
|
||||||
|
// to enum value could be converted directly.
|
||||||
|
bool m_values_ordinary { false };
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
void set_enum_map()
|
||||||
|
{
|
||||||
|
m_enum_names = &ConfigOptionEnum<EnumType>::get_enum_names();
|
||||||
|
m_enum_keys_map = &ConfigOptionEnum<EnumType>::get_enum_values();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For enums (when type == coEnum). Maps enums to enum names.
|
||||||
|
// Initialized by ConfigOptionEnum<xxx>::get_enum_names()
|
||||||
|
const t_config_enum_names* m_enum_names{ nullptr };
|
||||||
|
// For enums (when type == coEnum). Maps enum_values to enums.
|
||||||
|
// Initialized by ConfigOptionEnum<xxx>::get_enum_values()
|
||||||
|
const t_config_enum_values* m_enum_keys_map{ nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
// Definition of a configuration value for the purpose of GUI presentation, editing, value mapping and config file handling.
|
// Definition of a configuration value for the purpose of GUI presentation, editing, value mapping and config file handling.
|
||||||
class ConfigOptionDef
|
class ConfigOptionDef
|
||||||
{
|
{
|
||||||
|
@ -1629,16 +1802,18 @@ public:
|
||||||
i_enum_open,
|
i_enum_open,
|
||||||
// Open enums, float value could be one of the enumerated values or something else.
|
// Open enums, float value could be one of the enumerated values or something else.
|
||||||
f_enum_open,
|
f_enum_open,
|
||||||
|
// Open enums, string value could be one of the enumerated values or something else.
|
||||||
|
select_open,
|
||||||
// Color picker, string value.
|
// Color picker, string value.
|
||||||
color,
|
color,
|
||||||
// ???
|
|
||||||
select_open,
|
|
||||||
// Currently unused.
|
// Currently unused.
|
||||||
slider,
|
slider,
|
||||||
// Static text
|
// Static text
|
||||||
legend,
|
legend,
|
||||||
// Vector value, but edited as a single string.
|
// Vector value, but edited as a single string.
|
||||||
one_string,
|
one_string,
|
||||||
|
// Close parameter, string value could be one of the list values.
|
||||||
|
select_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Identifier of this option. It is stored here so that it is accessible through the by_serialization_key_ordinal map.
|
// Identifier of this option. It is stored here so that it is accessible through the by_serialization_key_ordinal map.
|
||||||
|
@ -1683,7 +1858,7 @@ public:
|
||||||
case coPoint3: { auto opt = new ConfigOptionPoint3(); archive(*opt); return opt; }
|
case coPoint3: { auto opt = new ConfigOptionPoint3(); archive(*opt); return opt; }
|
||||||
case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
|
case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
|
||||||
case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
|
case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
|
||||||
case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_keys_map); archive(*opt); return opt; }
|
case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map); archive(*opt); return opt; }
|
||||||
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
|
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1780,30 +1955,73 @@ public:
|
||||||
// Sometimes a single value may well define multiple values in a "beginner" mode.
|
// Sometimes a single value may well define multiple values in a "beginner" mode.
|
||||||
// Currently used for aliasing "solid_layers" to "top_solid_layers", "bottom_solid_layers".
|
// Currently used for aliasing "solid_layers" to "top_solid_layers", "bottom_solid_layers".
|
||||||
std::vector<t_config_option_key> shortcut;
|
std::vector<t_config_option_key> shortcut;
|
||||||
// Definition of values / labels for a combo box.
|
|
||||||
// Mostly used for enums (when type == coEnum), but may be used for ints resp. floats, if gui_type is set to "i_enum_open" resp. "f_enum_open".
|
|
||||||
std::vector<std::string> enum_values;
|
|
||||||
std::vector<std::string> enum_labels;
|
|
||||||
// For enums (when type == coEnum). Maps enum_values to enums.
|
|
||||||
// Initialized by ConfigOptionEnum<xxx>::get_enum_values()
|
|
||||||
const t_config_enum_values *enum_keys_map = nullptr;
|
|
||||||
|
|
||||||
void set_enum_values(std::initializer_list<std::pair<std::string_view, std::string_view>> il) {
|
Slic3r::clonable_ptr<ConfigOptionEnumDef> enum_def;
|
||||||
enum_values.clear();
|
|
||||||
enum_values.reserve(il.size());
|
void set_enum_values(const std::initializer_list<std::string_view> il) {
|
||||||
enum_labels.clear();
|
this->enum_def_new();
|
||||||
enum_labels.reserve(il.size());
|
enum_def->set_values(il);
|
||||||
for (const std::pair<std::string_view, std::string_view> p : il) {
|
|
||||||
enum_values.emplace_back(p.first);
|
|
||||||
enum_labels.emplace_back(p.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_enum_values(GUIType gui_type, const std::initializer_list<std::string_view> il) {
|
||||||
|
this->enum_def_new();
|
||||||
|
assert(gui_type == GUIType::i_enum_open || gui_type == GUIType::f_enum_open || gui_type == GUIType::select_open);
|
||||||
|
this->gui_type = gui_type;
|
||||||
|
enum_def->set_values(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_enum_values(const std::initializer_list<std::pair<std::string_view, std::string_view>> il) {
|
||||||
|
this->enum_def_new();
|
||||||
|
enum_def->set_values(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_enum_values(GUIType gui_type, const std::initializer_list<std::pair<std::string_view, std::string_view>> il) {
|
||||||
|
this->enum_def_new();
|
||||||
|
assert(gui_type == GUIType::i_enum_open || gui_type == GUIType::f_enum_open);
|
||||||
|
this->gui_type = gui_type;
|
||||||
|
enum_def->set_values(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Values, typename Labels>
|
||||||
|
void set_enum_values(Values &&values, Labels &&labels) {
|
||||||
|
this->enum_def_new();
|
||||||
|
enum_def->set_values(std::move(values));
|
||||||
|
enum_def->set_labels(std::move(labels));
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_enum_labels(GUIType gui_type, const std::initializer_list<std::string_view> il) {
|
||||||
|
this->enum_def_new();
|
||||||
|
assert(gui_type == GUIType::i_enum_open || gui_type == GUIType::f_enum_open || gui_type == ConfigOptionDef::GUIType::select_open);
|
||||||
|
this->gui_type = gui_type;
|
||||||
|
enum_def->set_labels(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
void set_enum(std::initializer_list<std::string_view> il) {
|
||||||
|
this->set_enum_values(il);
|
||||||
|
enum_def->set_enum_map<EnumType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
void set_enum(std::initializer_list<std::pair<std::string_view, std::string_view>> il) {
|
||||||
|
this->set_enum_values(il);
|
||||||
|
enum_def->set_enum_map<EnumType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename EnumType, typename Values, typename Labels>
|
||||||
|
void set_enum(Values &&values, Labels &&labels) {
|
||||||
|
this->set_enum_values(std::move(values), std::move(labels));
|
||||||
|
enum_def->set_enum_map<EnumType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename EnumType, typename Values>
|
||||||
|
void set_enum(Values &&values, const std::initializer_list<std::string_view> labels) {
|
||||||
|
this->set_enum_values(std::move(values), labels);
|
||||||
|
enum_def->set_enum_map<EnumType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_enum_value(const std::string &value) const {
|
bool has_enum_value(const std::string &value) const {
|
||||||
for (const std::string &v : enum_values)
|
return enum_def && enum_def->value_to_index(value).has_value();
|
||||||
if (v == value)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 is an invalid key.
|
// 0 is an invalid key.
|
||||||
|
@ -1815,6 +2033,14 @@ public:
|
||||||
|
|
||||||
// Assign this key to cli to disable CLI for this option.
|
// Assign this key to cli to disable CLI for this option.
|
||||||
static const constexpr char *nocli = "~~~noCLI";
|
static const constexpr char *nocli = "~~~noCLI";
|
||||||
|
|
||||||
|
private:
|
||||||
|
void enum_def_new() {
|
||||||
|
if (enum_def)
|
||||||
|
enum_def->clear();
|
||||||
|
else
|
||||||
|
enum_def = Slic3r::clonable_ptr<ConfigOptionEnumDef>(new ConfigOptionEnumDef{});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator<(const ConfigSubstitution &lhs, const ConfigSubstitution &rhs) throw() {
|
inline bool operator<(const ConfigSubstitution &lhs, const ConfigSubstitution &rhs) throw() {
|
||||||
|
@ -1860,6 +2086,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type);
|
ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type);
|
||||||
ConfigOptionDef* add_nullable(const t_config_option_key &opt_key, ConfigOptionType type);
|
ConfigOptionDef* add_nullable(const t_config_option_key &opt_key, ConfigOptionType type);
|
||||||
|
// Finalize open / close enums, validate everything.
|
||||||
|
void finalize();
|
||||||
};
|
};
|
||||||
|
|
||||||
// A pure interface to resolving ConfigOptions.
|
// A pure interface to resolving ConfigOptions.
|
||||||
|
@ -1970,6 +2198,11 @@ public:
|
||||||
template<class T> const T* opt(const t_config_option_key &opt_key) const
|
template<class T> const T* opt(const t_config_option_key &opt_key) const
|
||||||
{ return dynamic_cast<const T*>(this->optptr(opt_key)); }
|
{ return dynamic_cast<const T*>(this->optptr(opt_key)); }
|
||||||
|
|
||||||
|
// Get definition for a particular option.
|
||||||
|
// Returns null if such an option definition does not exist.
|
||||||
|
const ConfigOptionDef* option_def(const t_config_option_key &opt_key) const
|
||||||
|
{ return this->def()->get(opt_key); }
|
||||||
|
|
||||||
// Apply all keys of other ConfigBase defined by this->def() to this ConfigBase.
|
// Apply all keys of other ConfigBase defined by this->def() to this ConfigBase.
|
||||||
// An UnknownOptionException is thrown in case some option keys of other are not defined by this->def(),
|
// An UnknownOptionException is thrown in case some option keys of other are not defined by this->def(),
|
||||||
// or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set.
|
// or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set.
|
||||||
|
|
|
@ -31,6 +31,9 @@ public:
|
||||||
virtual void reverse() = 0;
|
virtual void reverse() = 0;
|
||||||
virtual const Point& first_point() const = 0;
|
virtual const Point& first_point() const = 0;
|
||||||
virtual const Point& last_point() const = 0;
|
virtual const Point& last_point() const = 0;
|
||||||
|
// Returns an approximately middle point of a path, loop or an extrusion collection.
|
||||||
|
// Used to get a sample point of an extrusion or extrusion collection, which is possibly deep inside its island.
|
||||||
|
virtual const Point& middle_point() const = 0;
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
virtual void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const = 0;
|
virtual void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const = 0;
|
||||||
|
@ -81,6 +84,7 @@ public:
|
||||||
void reverse() override { this->polyline.reverse(); }
|
void reverse() override { this->polyline.reverse(); }
|
||||||
const Point& first_point() const override { return this->polyline.points.front(); }
|
const Point& first_point() const override { return this->polyline.points.front(); }
|
||||||
const Point& last_point() const override { return this->polyline.points.back(); }
|
const Point& last_point() const override { return this->polyline.points.back(); }
|
||||||
|
const Point& middle_point() const override { return this->polyline.points[this->polyline.size() / 2]; }
|
||||||
size_t size() const { return this->polyline.size(); }
|
size_t size() const { return this->polyline.size(); }
|
||||||
bool empty() const { return this->polyline.empty(); }
|
bool empty() const { return this->polyline.empty(); }
|
||||||
bool is_closed() const { return ! this->empty() && this->polyline.points.front() == this->polyline.points.back(); }
|
bool is_closed() const { return ! this->empty() && this->polyline.points.front() == this->polyline.points.back(); }
|
||||||
|
@ -153,6 +157,7 @@ public:
|
||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
const Point& last_point() const override { return this->paths.back().polyline.points.back(); }
|
const Point& last_point() const override { return this->paths.back().polyline.points.back(); }
|
||||||
|
const Point& middle_point() const override { auto &path = this->paths[this->paths.size() / 2]; return path.polyline.points[path.polyline.size() / 2]; }
|
||||||
size_t size() const { return this->paths.size(); }
|
size_t size() const { return this->paths.size(); }
|
||||||
bool empty() const { return this->paths.empty(); }
|
bool empty() const { return this->paths.empty(); }
|
||||||
double length() const override;
|
double length() const override;
|
||||||
|
@ -204,6 +209,7 @@ public:
|
||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
const Point& last_point() const override { assert(this->first_point() == this->paths.back().polyline.points.back()); return this->first_point(); }
|
const Point& last_point() const override { assert(this->first_point() == this->paths.back().polyline.points.back()); return this->first_point(); }
|
||||||
|
const Point& middle_point() const override { auto& path = this->paths[this->paths.size() / 2]; return path.polyline.points[path.polyline.size() / 2]; }
|
||||||
Polygon polygon() const;
|
Polygon polygon() const;
|
||||||
double length() const override;
|
double length() const override;
|
||||||
bool split_at_vertex(const Point &point, const double scaled_epsilon = scaled<double>(0.001));
|
bool split_at_vertex(const Point &point, const double scaled_epsilon = scaled<double>(0.001));
|
||||||
|
|
|
@ -102,6 +102,7 @@ public:
|
||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->entities.front()->first_point(); }
|
const Point& first_point() const override { return this->entities.front()->first_point(); }
|
||||||
const Point& last_point() const override { return this->entities.back()->last_point(); }
|
const Point& last_point() const override { return this->entities.back()->last_point(); }
|
||||||
|
const Point& middle_point() const override { return this->entities[this->entities.size() / 2]->middle_point(); }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
||||||
|
|
|
@ -83,6 +83,11 @@ struct ExtrusionRole : public ExtrusionRoleModifiers
|
||||||
bool is_solid_infill() const { return this->is_infill() && this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Solid); }
|
bool is_solid_infill() const { return this->is_infill() && this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Solid); }
|
||||||
bool is_external() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::External); }
|
bool is_external() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::External); }
|
||||||
bool is_bridge() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Bridge); }
|
bool is_bridge() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Bridge); }
|
||||||
|
|
||||||
|
bool is_support() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Support); }
|
||||||
|
bool is_support_base() const { return this->is_support() && ! this->is_external(); }
|
||||||
|
bool is_support_interface() const { return this->is_support() && this->is_external(); }
|
||||||
|
bool is_mixed() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Mixed); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special flags describing loop
|
// Special flags describing loop
|
||||||
|
|
|
@ -2246,29 +2246,24 @@ void GCode::process_layer_single_object(
|
||||||
if (! print_wipe_extrusions && layer_to_print.support_layer != nullptr)
|
if (! print_wipe_extrusions && layer_to_print.support_layer != nullptr)
|
||||||
if (const SupportLayer &support_layer = *layer_to_print.support_layer; ! support_layer.support_fills.entities.empty()) {
|
if (const SupportLayer &support_layer = *layer_to_print.support_layer; ! support_layer.support_fills.entities.empty()) {
|
||||||
ExtrusionRole role = support_layer.support_fills.role();
|
ExtrusionRole role = support_layer.support_fills.role();
|
||||||
bool has_support = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterial;
|
bool has_support = role.is_mixed() || role.is_support_base();
|
||||||
bool has_interface = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterialInterface;
|
bool has_interface = role.is_mixed() || role.is_support_interface();
|
||||||
// Extruder ID of the support base. -1 if "don't care".
|
// Extruder ID of the support base. -1 if "don't care".
|
||||||
unsigned int support_extruder = print_object.config().support_material_extruder.value - 1;
|
unsigned int support_extruder = print_object.config().support_material_extruder.value - 1;
|
||||||
// Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
|
// Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
|
||||||
bool support_dontcare = print_object.config().support_material_extruder.value == 0;
|
bool support_dontcare = support_extruder == std::numeric_limits<unsigned int>::max();
|
||||||
// Extruder ID of the support interface. -1 if "don't care".
|
// Extruder ID of the support interface. -1 if "don't care".
|
||||||
unsigned int interface_extruder = print_object.config().support_material_interface_extruder.value - 1;
|
unsigned int interface_extruder = print_object.config().support_material_interface_extruder.value - 1;
|
||||||
// Shall the support interface be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
|
// Shall the support interface be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
|
||||||
bool interface_dontcare = print_object.config().support_material_interface_extruder.value == 0;
|
bool interface_dontcare = interface_extruder == std::numeric_limits<unsigned int>::max();
|
||||||
if (support_dontcare || interface_dontcare) {
|
if (support_dontcare || interface_dontcare) {
|
||||||
// Some support will be printed with "don't care" material, preferably non-soluble.
|
// Some support will be printed with "don't care" material, preferably non-soluble.
|
||||||
// Is the current extruder assigned a soluble filament?
|
// Is the current extruder assigned a soluble filament?
|
||||||
unsigned int dontcare_extruder = layer_tools.extruders.front();
|
auto it_nonsoluble = std::find_if(layer_tools.extruders.begin(), layer_tools.extruders.end(),
|
||||||
if (print.config().filament_soluble.get_at(dontcare_extruder)) {
|
[&soluble = std::as_const(print.config().filament_soluble)](unsigned int extruder_id) { return ! soluble.get_at(extruder_id); });
|
||||||
// The last extruder printed on the previous layer extrudes soluble filament.
|
// There should be a non-soluble extruder available.
|
||||||
// Try to find a non-soluble extruder on the same layer.
|
assert(it_nonsoluble != layer_tools.extruders.end());
|
||||||
for (unsigned int extruder_id : layer_tools.extruders)
|
unsigned int dontcare_extruder = it_nonsoluble == layer_tools.extruders.end() ? layer_tools.extruders.front() : *it_nonsoluble;
|
||||||
if (! print.config().filament_soluble.get_at(extruder_id)) {
|
|
||||||
dontcare_extruder = extruder_id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (support_dontcare)
|
if (support_dontcare)
|
||||||
support_extruder = dontcare_extruder;
|
support_extruder = dontcare_extruder;
|
||||||
if (interface_dontcare)
|
if (interface_dontcare)
|
||||||
|
@ -2282,7 +2277,7 @@ void GCode::process_layer_single_object(
|
||||||
m_object_layer_over_raft = false;
|
m_object_layer_over_raft = false;
|
||||||
gcode += this->extrude_support(
|
gcode += this->extrude_support(
|
||||||
// support_extrusion_role is ExtrusionRole::SupportMaterial, ExtrusionRole::SupportMaterialInterface or ExtrusionRole::Mixed for all extrusion paths.
|
// support_extrusion_role is ExtrusionRole::SupportMaterial, ExtrusionRole::SupportMaterialInterface or ExtrusionRole::Mixed for all extrusion paths.
|
||||||
support_layer.support_fills.chained_path_from(m_last_pos, has_support ? (has_interface ? ExtrusionRole::Mixed : ExtrusionRole::SupportMaterial) : ExtrusionRole::SupportMaterialInterface));
|
support_layer.support_fills.chained_path_from(m_last_pos, extrude_support ? (extrude_interface ? ExtrusionRole::Mixed : ExtrusionRole::SupportMaterial) : ExtrusionRole::SupportMaterialInterface));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2859,9 +2854,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||||
bool variable_speed = false;
|
bool variable_speed = false;
|
||||||
std::vector<ProcessedPoint> new_points{};
|
std::vector<ProcessedPoint> new_points{};
|
||||||
if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && path.role().is_perimeter()) {
|
if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && path.role().is_perimeter()) {
|
||||||
|
double external_perim_reference_speed = std::min(m_config.get_abs_value("external_perimeter_speed"),
|
||||||
|
std::min(EXTRUDER_CONFIG(filament_max_volumetric_speed) / path.mm3_per_mm,
|
||||||
|
m_config.max_volumetric_speed.value / path.mm3_per_mm));
|
||||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_overlap_levels,
|
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_overlap_levels,
|
||||||
m_config.dynamic_overhang_speeds,
|
m_config.dynamic_overhang_speeds,
|
||||||
m_config.get_abs_value("external_perimeter_speed"), speed);
|
external_perim_reference_speed, speed);
|
||||||
variable_speed = std::any_of(new_points.begin(), new_points.end(), [speed](const ProcessedPoint &p) { return p.speed != speed; });
|
variable_speed = std::any_of(new_points.begin(), new_points.end(), [speed](const ProcessedPoint &p) { return p.speed != speed; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2946,10 +2944,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||||
prev = p;
|
prev = p;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::string comment;
|
std::string marked_comment;
|
||||||
if (m_config.gcode_comments) {
|
if (m_config.gcode_comments) {
|
||||||
comment = description;
|
marked_comment = description;
|
||||||
comment += description_bridge;
|
marked_comment += description_bridge;
|
||||||
}
|
}
|
||||||
double last_set_speed = new_points[0].speed * 60.0;
|
double last_set_speed = new_points[0].speed * 60.0;
|
||||||
gcode += m_writer.set_speed(last_set_speed, "", comment);
|
gcode += m_writer.set_speed(last_set_speed, "", comment);
|
||||||
|
@ -2958,7 +2956,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||||
const ProcessedPoint& processed_point = new_points[i];
|
const ProcessedPoint& processed_point = new_points[i];
|
||||||
Vec2d p = this->point_to_gcode_quantized(processed_point.p);
|
Vec2d p = this->point_to_gcode_quantized(processed_point.p);
|
||||||
const double line_length = (p - prev).norm();
|
const double line_length = (p - prev).norm();
|
||||||
gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, comment);
|
gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, marked_comment);
|
||||||
prev = p;
|
prev = p;
|
||||||
double new_speed = processed_point.speed * 60.0;
|
double new_speed = processed_point.speed * 60.0;
|
||||||
if (last_set_speed != new_speed) {
|
if (last_set_speed != new_speed) {
|
||||||
|
|
|
@ -264,10 +264,11 @@ public:
|
||||||
float original_speed)
|
float original_speed)
|
||||||
{
|
{
|
||||||
size_t speed_sections_count = std::min(overlaps.values.size(), speeds.values.size());
|
size_t speed_sections_count = std::min(overlaps.values.size(), speeds.values.size());
|
||||||
|
float speed_base = ext_perimeter_speed > 0 ? ext_perimeter_speed : original_speed;
|
||||||
std::vector<std::pair<float, float>> speed_sections;
|
std::vector<std::pair<float, float>> speed_sections;
|
||||||
for (size_t i = 0; i < speed_sections_count; i++) {
|
for (size_t i = 0; i < speed_sections_count; i++) {
|
||||||
float distance = path.width * (1.0 - (overlaps.get_at(i) / 100.0));
|
float distance = path.width * (1.0 - (overlaps.get_at(i) / 100.0));
|
||||||
float speed = speeds.get_at(i).percent ? (ext_perimeter_speed * speeds.get_at(i).value / 100.0) : speeds.get_at(i).value;
|
float speed = speeds.get_at(i).percent ? (speed_base * speeds.get_at(i).value / 100.0) : speeds.get_at(i).value;
|
||||||
speed_sections.push_back({distance, speed});
|
speed_sections.push_back({distance, speed});
|
||||||
}
|
}
|
||||||
std::sort(speed_sections.begin(), speed_sections.end(),
|
std::sort(speed_sections.begin(), speed_sections.end(),
|
||||||
|
|
|
@ -578,7 +578,7 @@ void Layer::sort_perimeters_into_islands(
|
||||||
// Take a sample deep inside its island if available. Infills are usually quite far from the island boundary.
|
// Take a sample deep inside its island if available. Infills are usually quite far from the island boundary.
|
||||||
for (uint32_t iexpoly : fill_expolygons_ranges[islice])
|
for (uint32_t iexpoly : fill_expolygons_ranges[islice])
|
||||||
if (const ExPolygon &expoly = fill_expolygons[iexpoly]; ! expoly.empty()) {
|
if (const ExPolygon &expoly = fill_expolygons[iexpoly]; ! expoly.empty()) {
|
||||||
sample = expoly.contour.points.front();
|
sample = expoly.contour.points[expoly.contour.points.size() / 2];
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -589,12 +589,12 @@ void Layer::sort_perimeters_into_islands(
|
||||||
if (ee.is_collection()) {
|
if (ee.is_collection()) {
|
||||||
for (const ExtrusionEntity *ee2 : dynamic_cast<const ExtrusionEntityCollection&>(ee).entities)
|
for (const ExtrusionEntity *ee2 : dynamic_cast<const ExtrusionEntityCollection&>(ee).entities)
|
||||||
if (! ee2->role().is_external()) {
|
if (! ee2->role().is_external()) {
|
||||||
sample = ee2->first_point();
|
sample = ee2->middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
goto loop_end;
|
goto loop_end;
|
||||||
}
|
}
|
||||||
} else if (! ee.role().is_external()) {
|
} else if (! ee.role().is_external()) {
|
||||||
sample = ee.first_point();
|
sample = ee.middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -603,12 +603,12 @@ void Layer::sort_perimeters_into_islands(
|
||||||
if (! sample_set) {
|
if (! sample_set) {
|
||||||
if (! extrusions.second.empty()) {
|
if (! extrusions.second.empty()) {
|
||||||
// If there is no inner perimeter, take a sample of some gap fill extrusion.
|
// If there is no inner perimeter, take a sample of some gap fill extrusion.
|
||||||
sample = this_layer_region.thin_fills().entities[*extrusions.second.begin()]->first_point();
|
sample = this_layer_region.thin_fills().entities[*extrusions.second.begin()]->middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
}
|
}
|
||||||
if (! sample_set && ! extrusions.first.empty()) {
|
if (! sample_set && ! extrusions.first.empty()) {
|
||||||
// As a last resort, take a sample of some external perimeter.
|
// As a last resort, take a sample of some external perimeter.
|
||||||
sample = this_layer_region.perimeters().entities[*extrusions.first.begin()]->first_point();
|
sample = this_layer_region.perimeters().entities[*extrusions.first.begin()]->middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -835,6 +835,15 @@ void Layer::sort_perimeters_into_islands(
|
||||||
d2min = d2;
|
d2min = d2;
|
||||||
lslice_idx_min = lslice_idx;
|
lslice_idx_min = lslice_idx;
|
||||||
}
|
}
|
||||||
|
if (lslice_idx_min == -1) {
|
||||||
|
// This should not happen, but Arachne seems to produce a perimeter point far outside its source contour.
|
||||||
|
// As a last resort, find the closest source contours to the sample point.
|
||||||
|
for (int lslice_idx = int(lslices_ex.size()) - 1; lslice_idx >= 0; -- lslice_idx)
|
||||||
|
if (double d2 = (lslices[lslice_idx].point_projection(it_source_slice->second) - it_source_slice->second).cast<double>().squaredNorm(); d2 < d2min) {
|
||||||
|
d2min = d2;
|
||||||
|
lslice_idx_min = lslice_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
assert(lslice_idx_min != -1);
|
assert(lslice_idx_min != -1);
|
||||||
insert_into_island(lslice_idx_min, it_source_slice->first);
|
insert_into_island(lslice_idx_min, it_source_slice->first);
|
||||||
}
|
}
|
||||||
|
|
|
@ -653,10 +653,10 @@ std::string Print::validate(std::string* warning) const
|
||||||
"If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), "
|
"If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), "
|
||||||
"all nozzles have to be of the same diameter.");
|
"all nozzles have to be of the same diameter.");
|
||||||
}
|
}
|
||||||
if (this->has_wipe_tower()) {
|
if (this->has_wipe_tower() && object->config().support_material_style != smsOrganic) {
|
||||||
if (object->config().support_material_contact_distance == 0) {
|
if (object->config().support_material_contact_distance == 0) {
|
||||||
// Soluble interface
|
// Soluble interface
|
||||||
if (object->config().support_material_contact_distance == 0 && ! object->config().support_material_synchronize_layers)
|
if (! object->config().support_material_synchronize_layers)
|
||||||
return L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers.");
|
return L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers.");
|
||||||
} else {
|
} else {
|
||||||
// Non-soluble interface
|
// Non-soluble interface
|
||||||
|
|
|
@ -243,6 +243,7 @@ PrintConfigDef::PrintConfigDef()
|
||||||
assign_printer_technology_to_unknown(this->options, ptFFF);
|
assign_printer_technology_to_unknown(this->options, ptFFF);
|
||||||
this->init_sla_params();
|
this->init_sla_params();
|
||||||
assign_printer_technology_to_unknown(this->options, ptSLA);
|
assign_printer_technology_to_unknown(this->options, ptSLA);
|
||||||
|
this->finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintConfigDef::init_common_params()
|
void PrintConfigDef::init_common_params()
|
||||||
|
@ -252,9 +253,7 @@ void PrintConfigDef::init_common_params()
|
||||||
def = this->add("printer_technology", coEnum);
|
def = this->add("printer_technology", coEnum);
|
||||||
def->label = L("Printer technology");
|
def->label = L("Printer technology");
|
||||||
def->tooltip = L("Printer technology");
|
def->tooltip = L("Printer technology");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<PrinterTechnology>::get_enum_values();
|
def->set_enum<PrinterTechnology>({ "FFF", "SLA" });
|
||||||
def->enum_values.push_back("FFF");
|
|
||||||
def->enum_values.push_back("SLA");
|
|
||||||
def->set_default_value(new ConfigOptionEnum<PrinterTechnology>(ptFFF));
|
def->set_default_value(new ConfigOptionEnum<PrinterTechnology>(ptFFF));
|
||||||
|
|
||||||
def = this->add("bed_shape", coPoints);
|
def = this->add("bed_shape", coPoints);
|
||||||
|
@ -293,10 +292,7 @@ void PrintConfigDef::init_common_params()
|
||||||
def->label = L("Format of G-code thumbnails");
|
def->label = L("Format of G-code thumbnails");
|
||||||
def->tooltip = L("Format of G-code thumbnails: PNG for best quality, JPG for smallest size, QOI for low memory firmware");
|
def->tooltip = L("Format of G-code thumbnails: PNG for best quality, JPG for smallest size, QOI for low memory firmware");
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->enum_keys_map = &ConfigOptionEnum<GCodeThumbnailsFormat>::get_enum_values();
|
def->set_enum<GCodeThumbnailsFormat>({ "PNG", "JPG", "QOI" });
|
||||||
def->enum_values.push_back("PNG");
|
|
||||||
def->enum_values.push_back("JPG");
|
|
||||||
def->enum_values.push_back("QOI");
|
|
||||||
def->set_default_value(new ConfigOptionEnum<GCodeThumbnailsFormat>(GCodeThumbnailsFormat::PNG));
|
def->set_default_value(new ConfigOptionEnum<GCodeThumbnailsFormat>(GCodeThumbnailsFormat::PNG));
|
||||||
|
|
||||||
def = this->add("layer_height", coFloat);
|
def = this->add("layer_height", coFloat);
|
||||||
|
@ -338,7 +334,7 @@ void PrintConfigDef::init_common_params()
|
||||||
def = this->add("printhost_port", coString);
|
def = this->add("printhost_port", coString);
|
||||||
def->label = L("Printer");
|
def->label = L("Printer");
|
||||||
def->tooltip = L("Name of the printer");
|
def->tooltip = L("Name of the printer");
|
||||||
def->gui_type = ConfigOptionDef::GUIType::select_open;
|
def->gui_type = ConfigOptionDef::GUIType::select_close;
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->cli = ConfigOptionDef::nocli;
|
def->cli = ConfigOptionDef::nocli;
|
||||||
def->set_default_value(new ConfigOptionString(""));
|
def->set_default_value(new ConfigOptionString(""));
|
||||||
|
@ -385,11 +381,10 @@ void PrintConfigDef::init_common_params()
|
||||||
def = this->add("printhost_authorization_type", coEnum);
|
def = this->add("printhost_authorization_type", coEnum);
|
||||||
def->label = L("Authorization Type");
|
def->label = L("Authorization Type");
|
||||||
// def->tooltip = L("");
|
// def->tooltip = L("");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<AuthorizationType>::get_enum_values();
|
def->set_enum<AuthorizationType>({
|
||||||
def->enum_values.push_back("key");
|
{ "key", L("API key") },
|
||||||
def->enum_values.push_back("user");
|
{ "user", L("HTTP digest") }
|
||||||
def->enum_labels.push_back(L("API key"));
|
});
|
||||||
def->enum_labels.push_back(L("HTTP digest"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->cli = ConfigOptionDef::nocli;
|
def->cli = ConfigOptionDef::nocli;
|
||||||
def->set_default_value(new ConfigOptionEnum<AuthorizationType>(atKeyPassword));
|
def->set_default_value(new ConfigOptionEnum<AuthorizationType>(atKeyPassword));
|
||||||
|
@ -585,15 +580,12 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Brim type");
|
def->label = L("Brim type");
|
||||||
def->category = L("Skirt and brim");
|
def->category = L("Skirt and brim");
|
||||||
def->tooltip = L("The places where the brim will be printed around each object on the first layer.");
|
def->tooltip = L("The places where the brim will be printed around each object on the first layer.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<BrimType>::get_enum_values();
|
def->set_enum<BrimType>({
|
||||||
def->enum_values.emplace_back("no_brim");
|
{ "no_brim", L("No brim") },
|
||||||
def->enum_values.emplace_back("outer_only");
|
{ "outer_only", L("Outer brim only") },
|
||||||
def->enum_values.emplace_back("inner_only");
|
{ "inner_only", L("Inner brim only") },
|
||||||
def->enum_values.emplace_back("outer_and_inner");
|
{ "outer_and_inner", L("Outer and inner brim") }
|
||||||
def->enum_labels.emplace_back(L("No brim"));
|
});
|
||||||
def->enum_labels.emplace_back(L("Outer brim only"));
|
|
||||||
def->enum_labels.emplace_back(L("Inner brim only"));
|
|
||||||
def->enum_labels.emplace_back(L("Outer and inner brim"));
|
|
||||||
def->mode = comSimple;
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionEnum<BrimType>(btOuterOnly));
|
def->set_default_value(new ConfigOptionEnum<BrimType>(btOuterOnly));
|
||||||
|
|
||||||
|
@ -774,8 +766,7 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->category = L("Infill");
|
def->category = L("Infill");
|
||||||
def->tooltip = L("Fill pattern for top infill. This only affects the top visible layer, and not its adjacent solid shells.");
|
def->tooltip = L("Fill pattern for top infill. This only affects the top visible layer, and not its adjacent solid shells.");
|
||||||
def->cli = "top-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
def->cli = "top-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
||||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
def->set_enum<InfillPattern>({
|
||||||
def->set_enum_values({
|
|
||||||
{ "rectilinear", L("Rectilinear") },
|
{ "rectilinear", L("Rectilinear") },
|
||||||
{ "monotonic", L("Monotonic") },
|
{ "monotonic", L("Monotonic") },
|
||||||
{ "monotoniclines", L("Monotonic Lines") },
|
{ "monotoniclines", L("Monotonic Lines") },
|
||||||
|
@ -795,9 +786,7 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->category = L("Infill");
|
def->category = L("Infill");
|
||||||
def->tooltip = L("Fill pattern for bottom infill. This only affects the bottom external visible layer, and not its adjacent solid shells.");
|
def->tooltip = L("Fill pattern for bottom infill. This only affects the bottom external visible layer, and not its adjacent solid shells.");
|
||||||
def->cli = "bottom-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
def->cli = "bottom-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
||||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
def->enum_def = Slic3r::clonable_ptr<Slic3r::ConfigOptionEnumDef>(def_top_fill_pattern->enum_def->clone());
|
||||||
def->enum_values = def_top_fill_pattern->enum_values;
|
|
||||||
def->enum_labels = def_top_fill_pattern->enum_labels;
|
|
||||||
def->aliases = def_top_fill_pattern->aliases;
|
def->aliases = def_top_fill_pattern->aliases;
|
||||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipMonotonic));
|
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipMonotonic));
|
||||||
|
|
||||||
|
@ -851,18 +840,13 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
def = this->add("extruder", coInt);
|
def = this->add("extruder", coInt);
|
||||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
|
||||||
def->label = L("Extruder");
|
def->label = L("Extruder");
|
||||||
def->category = L("Extruders");
|
def->category = L("Extruders");
|
||||||
def->tooltip = L("The extruder to use (unless more specific extruder settings are specified). "
|
def->tooltip = L("The extruder to use (unless more specific extruder settings are specified). "
|
||||||
"This value overrides perimeter and infill extruders, but not the support extruders.");
|
"This value overrides perimeter and infill extruders, but not the support extruders.");
|
||||||
def->min = 0; // 0 = inherit defaults
|
def->min = 0; // 0 = inherit defaults
|
||||||
def->enum_labels.push_back(L("default")); // override label for item 0
|
def->set_enum_labels(ConfigOptionDef::GUIType::i_enum_open,
|
||||||
def->enum_labels.push_back("1");
|
{ L("default"), "1", "2", "3", "4", "5" }); // override label for item 0
|
||||||
def->enum_labels.push_back("2");
|
|
||||||
def->enum_labels.push_back("3");
|
|
||||||
def->enum_labels.push_back("4");
|
|
||||||
def->enum_labels.push_back("5");
|
|
||||||
|
|
||||||
def = this->add("extruder_clearance_height", coFloat);
|
def = this->add("extruder_clearance_height", coFloat);
|
||||||
def->label = L("Height");
|
def->label = L("Height");
|
||||||
|
@ -1096,29 +1080,29 @@ void PrintConfigDef::init_fff_params()
|
||||||
def = this->add("filament_type", coStrings);
|
def = this->add("filament_type", coStrings);
|
||||||
def->label = L("Filament type");
|
def->label = L("Filament type");
|
||||||
def->tooltip = L("The filament material type for use in custom G-codes.");
|
def->tooltip = L("The filament material type for use in custom G-codes.");
|
||||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
|
||||||
def->gui_flags = "show_value";
|
def->gui_flags = "show_value";
|
||||||
def->enum_values.push_back("PLA");
|
def->set_enum_values(ConfigOptionDef::GUIType::select_open, {
|
||||||
def->enum_values.push_back("PET");
|
"PLA",
|
||||||
def->enum_values.push_back("ABS");
|
"PET",
|
||||||
def->enum_values.push_back("ASA");
|
"ABS",
|
||||||
def->enum_values.push_back("FLEX");
|
"ASA",
|
||||||
def->enum_values.push_back("HIPS");
|
"FLEX",
|
||||||
def->enum_values.push_back("EDGE");
|
"HIPS",
|
||||||
def->enum_values.push_back("NGEN");
|
"EDGE",
|
||||||
def->enum_values.push_back("PA");
|
"NGEN",
|
||||||
def->enum_values.push_back("NYLON");
|
"PA",
|
||||||
def->enum_values.push_back("PVA");
|
"NYLON",
|
||||||
def->enum_values.push_back("PC");
|
"PVA",
|
||||||
def->enum_values.push_back("PP");
|
"PC",
|
||||||
def->enum_values.push_back("PEI");
|
"PP",
|
||||||
def->enum_values.push_back("PEEK");
|
"PEI",
|
||||||
def->enum_values.push_back("PEKK");
|
"PEEK",
|
||||||
def->enum_values.push_back("POM");
|
"PEKK",
|
||||||
def->enum_values.push_back("PSU");
|
"POM",
|
||||||
def->enum_values.push_back("PVDF");
|
"PSU",
|
||||||
def->enum_values.push_back("SCAFF");
|
"PVDF",
|
||||||
|
"SCAFF"
|
||||||
|
});
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionStrings { "PLA" });
|
def->set_default_value(new ConfigOptionStrings { "PLA" });
|
||||||
|
|
||||||
|
@ -1166,7 +1150,6 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->set_default_value(new ConfigOptionFloat(45));
|
def->set_default_value(new ConfigOptionFloat(45));
|
||||||
|
|
||||||
def = this->add("fill_density", coPercent);
|
def = this->add("fill_density", coPercent);
|
||||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
|
||||||
def->gui_flags = "show_value";
|
def->gui_flags = "show_value";
|
||||||
def->label = L("Fill density");
|
def->label = L("Fill density");
|
||||||
def->category = L("Infill");
|
def->category = L("Infill");
|
||||||
|
@ -1174,75 +1157,47 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->sidetext = L("%");
|
def->sidetext = L("%");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->max = 100;
|
def->max = 100;
|
||||||
def->enum_values.push_back("0");
|
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||||
def->enum_values.push_back("5");
|
{ "0", "0%" },
|
||||||
def->enum_values.push_back("10");
|
{ "5", "5%" },
|
||||||
def->enum_values.push_back("15");
|
{ "10", "10%" },
|
||||||
def->enum_values.push_back("20");
|
{ "15", "15%" },
|
||||||
def->enum_values.push_back("25");
|
{ "20", "20%" },
|
||||||
def->enum_values.push_back("30");
|
{ "25", "25%" },
|
||||||
def->enum_values.push_back("40");
|
{ "30", "30%" },
|
||||||
def->enum_values.push_back("50");
|
{ "40", "40%" },
|
||||||
def->enum_values.push_back("60");
|
{ "50", "50%" },
|
||||||
def->enum_values.push_back("70");
|
{ "60", "60%" },
|
||||||
def->enum_values.push_back("80");
|
{ "70", "70%" },
|
||||||
def->enum_values.push_back("90");
|
{ "80", "80%" },
|
||||||
def->enum_values.push_back("100");
|
{ "90", "90%" },
|
||||||
def->enum_labels.push_back("0%");
|
{ "100", "100%" }
|
||||||
def->enum_labels.push_back("5%");
|
});
|
||||||
def->enum_labels.push_back("10%");
|
|
||||||
def->enum_labels.push_back("15%");
|
|
||||||
def->enum_labels.push_back("20%");
|
|
||||||
def->enum_labels.push_back("25%");
|
|
||||||
def->enum_labels.push_back("30%");
|
|
||||||
def->enum_labels.push_back("40%");
|
|
||||||
def->enum_labels.push_back("50%");
|
|
||||||
def->enum_labels.push_back("60%");
|
|
||||||
def->enum_labels.push_back("70%");
|
|
||||||
def->enum_labels.push_back("80%");
|
|
||||||
def->enum_labels.push_back("90%");
|
|
||||||
def->enum_labels.push_back("100%");
|
|
||||||
def->set_default_value(new ConfigOptionPercent(20));
|
def->set_default_value(new ConfigOptionPercent(20));
|
||||||
|
|
||||||
def = this->add("fill_pattern", coEnum);
|
def = this->add("fill_pattern", coEnum);
|
||||||
def->label = L("Fill pattern");
|
def->label = L("Fill pattern");
|
||||||
def->category = L("Infill");
|
def->category = L("Infill");
|
||||||
def->tooltip = L("Fill pattern for general low-density infill.");
|
def->tooltip = L("Fill pattern for general low-density infill.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
def->set_enum<InfillPattern>({
|
||||||
def->enum_values.push_back("rectilinear");
|
{ "rectilinear", L("Rectilinear") },
|
||||||
def->enum_values.push_back("alignedrectilinear");
|
{ "alignedrectilinear", L("Aligned Rectilinear") },
|
||||||
def->enum_values.push_back("grid");
|
{ "grid", L("Grid") },
|
||||||
def->enum_values.push_back("triangles");
|
{ "triangles", L("Triangles")},
|
||||||
def->enum_values.push_back("stars");
|
{ "stars", L("Stars")},
|
||||||
def->enum_values.push_back("cubic");
|
{ "cubic", L("Cubic")},
|
||||||
def->enum_values.push_back("line");
|
{ "line", L("Line")},
|
||||||
def->enum_values.push_back("concentric");
|
{ "concentric", L("Concentric")},
|
||||||
def->enum_values.push_back("honeycomb");
|
{ "honeycomb", L("Honeycomb")},
|
||||||
def->enum_values.push_back("3dhoneycomb");
|
{ "3dhoneycomb", L("3D Honeycomb")},
|
||||||
def->enum_values.push_back("gyroid");
|
{ "gyroid", L("Gyroid")},
|
||||||
def->enum_values.push_back("hilbertcurve");
|
{ "hilbertcurve", L("Hilbert Curve")},
|
||||||
def->enum_values.push_back("archimedeanchords");
|
{ "archimedeanchords", L("Archimedean Chords")},
|
||||||
def->enum_values.push_back("octagramspiral");
|
{ "octagramspiral", L("Octagram Spiral")},
|
||||||
def->enum_values.push_back("adaptivecubic");
|
{ "adaptivecubic", L("Adaptive Cubic")},
|
||||||
def->enum_values.push_back("supportcubic");
|
{ "supportcubic", L("Support Cubic")},
|
||||||
def->enum_values.push_back("lightning");
|
{ "lightning", L("Lightning")}
|
||||||
def->enum_labels.push_back(L("Rectilinear"));
|
});
|
||||||
def->enum_labels.push_back(L("Aligned Rectilinear"));
|
|
||||||
def->enum_labels.push_back(L("Grid"));
|
|
||||||
def->enum_labels.push_back(L("Triangles"));
|
|
||||||
def->enum_labels.push_back(L("Stars"));
|
|
||||||
def->enum_labels.push_back(L("Cubic"));
|
|
||||||
def->enum_labels.push_back(L("Line"));
|
|
||||||
def->enum_labels.push_back(L("Concentric"));
|
|
||||||
def->enum_labels.push_back(L("Honeycomb"));
|
|
||||||
def->enum_labels.push_back(L("3D Honeycomb"));
|
|
||||||
def->enum_labels.push_back(L("Gyroid"));
|
|
||||||
def->enum_labels.push_back(L("Hilbert Curve"));
|
|
||||||
def->enum_labels.push_back(L("Archimedean Chords"));
|
|
||||||
def->enum_labels.push_back(L("Octagram Spiral"));
|
|
||||||
def->enum_labels.push_back(L("Adaptive Cubic"));
|
|
||||||
def->enum_labels.push_back(L("Support Cubic"));
|
|
||||||
def->enum_labels.push_back(L("Lightning"));
|
|
||||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipStars));
|
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipStars));
|
||||||
|
|
||||||
def = this->add("first_layer_acceleration", coFloat);
|
def = this->add("first_layer_acceleration", coFloat);
|
||||||
|
@ -1343,14 +1298,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Fuzzy Skin");
|
def->label = L("Fuzzy Skin");
|
||||||
def->category = L("Fuzzy Skin");
|
def->category = L("Fuzzy Skin");
|
||||||
def->tooltip = L("Fuzzy skin type.");
|
def->tooltip = L("Fuzzy skin type.");
|
||||||
|
def->set_enum<FuzzySkinType>({
|
||||||
def->enum_keys_map = &ConfigOptionEnum<FuzzySkinType>::get_enum_values();
|
{ "none", L("None") },
|
||||||
def->enum_values.push_back("none");
|
{ "external", L("Outside walls") },
|
||||||
def->enum_values.push_back("external");
|
{ "all", L("All walls") }
|
||||||
def->enum_values.push_back("all");
|
});
|
||||||
def->enum_labels.push_back(L("None"));
|
|
||||||
def->enum_labels.push_back(L("Outside walls"));
|
|
||||||
def->enum_labels.push_back(L("All walls"));
|
|
||||||
def->mode = comSimple;
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionEnum<FuzzySkinType>(FuzzySkinType::None));
|
def->set_default_value(new ConfigOptionEnum<FuzzySkinType>(FuzzySkinType::None));
|
||||||
|
|
||||||
|
@ -1404,31 +1356,20 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->tooltip = L("Some G/M-code commands, including temperature control and others, are not universal. "
|
def->tooltip = L("Some G/M-code commands, including temperature control and others, are not universal. "
|
||||||
"Set this option to your printer's firmware to get a compatible output. "
|
"Set this option to your printer's firmware to get a compatible output. "
|
||||||
"The \"No extrusion\" flavor prevents PrusaSlicer from exporting any extrusion value at all.");
|
"The \"No extrusion\" flavor prevents PrusaSlicer from exporting any extrusion value at all.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<GCodeFlavor>::get_enum_values();
|
def->set_enum<GCodeFlavor>({
|
||||||
def->enum_values.push_back("reprap");
|
{ "reprap", "RepRap/Sprinter" },
|
||||||
def->enum_values.push_back("reprapfirmware");
|
{ "reprapfirmware", "RepRapFirmware" },
|
||||||
def->enum_values.push_back("repetier");
|
{ "repetier", "Repetier" },
|
||||||
def->enum_values.push_back("teacup");
|
{ "teacup", "Teacup" },
|
||||||
def->enum_values.push_back("makerware");
|
{ "makerware", "MakerWare (MakerBot)" },
|
||||||
def->enum_values.push_back("marlin");
|
{ "marlin", "Marlin (legacy)" },
|
||||||
def->enum_values.push_back("marlin2");
|
{ "marlin2", "Marlin 2" },
|
||||||
def->enum_values.push_back("sailfish");
|
{ "sailfish", "Sailfish (MakerBot)" },
|
||||||
def->enum_values.push_back("mach3");
|
{ "mach3", "Mach3/LinuxCNC" },
|
||||||
def->enum_values.push_back("machinekit");
|
{ "machinekit", "Machinekit" },
|
||||||
def->enum_values.push_back("smoothie");
|
{ "smoothie", "Smoothie" },
|
||||||
def->enum_values.push_back("no-extrusion");
|
{ "no-extrusion", L("No extrusion") }
|
||||||
def->enum_labels.push_back("RepRap/Sprinter");
|
});
|
||||||
def->enum_labels.push_back("RepRapFirmware");
|
|
||||||
def->enum_labels.push_back("Repetier");
|
|
||||||
def->enum_labels.push_back("Teacup");
|
|
||||||
def->enum_labels.push_back("MakerWare (MakerBot)");
|
|
||||||
def->enum_labels.push_back("Marlin (legacy)");
|
|
||||||
def->enum_labels.push_back("Marlin 2");
|
|
||||||
def->enum_labels.push_back("Sailfish (MakerBot)");
|
|
||||||
def->enum_labels.push_back("Mach3/LinuxCNC");
|
|
||||||
def->enum_labels.push_back("Machinekit");
|
|
||||||
def->enum_labels.push_back("Smoothie");
|
|
||||||
def->enum_labels.push_back(L("No extrusion"));
|
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRapSprinter));
|
def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRapSprinter));
|
||||||
|
|
||||||
|
@ -1486,19 +1427,14 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->sidetext = L("mm or %");
|
def->sidetext = L("mm or %");
|
||||||
def->ratio_over = "infill_extrusion_width";
|
def->ratio_over = "infill_extrusion_width";
|
||||||
def->max_literal = 1000;
|
def->max_literal = 1000;
|
||||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||||
def->enum_values.push_back("0");
|
{ "0", L("0 (no open anchors)") },
|
||||||
def->enum_values.push_back("1");
|
{ "1", L("1 mm") },
|
||||||
def->enum_values.push_back("2");
|
{ "2", L("2 mm") },
|
||||||
def->enum_values.push_back("5");
|
{ "5", L("5 mm") },
|
||||||
def->enum_values.push_back("10");
|
{ "10", L("10 mm") },
|
||||||
def->enum_values.push_back("1000");
|
{ "1000", L("1000 (unlimited)") }
|
||||||
def->enum_labels.push_back(L("0 (no open anchors)"));
|
});
|
||||||
def->enum_labels.push_back(L("1 mm"));
|
|
||||||
def->enum_labels.push_back(L("2 mm"));
|
|
||||||
def->enum_labels.push_back(L("5 mm"));
|
|
||||||
def->enum_labels.push_back(L("10 mm"));
|
|
||||||
def->enum_labels.push_back(L("1000 (unlimited)"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloatOrPercent(600, true));
|
def->set_default_value(new ConfigOptionFloatOrPercent(600, true));
|
||||||
|
|
||||||
|
@ -1514,14 +1450,14 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->sidetext = def_infill_anchor_min->sidetext;
|
def->sidetext = def_infill_anchor_min->sidetext;
|
||||||
def->ratio_over = def_infill_anchor_min->ratio_over;
|
def->ratio_over = def_infill_anchor_min->ratio_over;
|
||||||
def->max_literal = def_infill_anchor_min->max_literal;
|
def->max_literal = def_infill_anchor_min->max_literal;
|
||||||
def->gui_type = def_infill_anchor_min->gui_type;
|
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||||
def->enum_values = def_infill_anchor_min->enum_values;
|
{ "0", L("0 (not anchored)") },
|
||||||
def->enum_labels.push_back(L("0 (not anchored)"));
|
{ "1", L("1 mm") },
|
||||||
def->enum_labels.push_back(L("1 mm"));
|
{ "2", L("2 mm") },
|
||||||
def->enum_labels.push_back(L("2 mm"));
|
{ "5", L("5 mm") },
|
||||||
def->enum_labels.push_back(L("5 mm"));
|
{ "10", L("10 mm") },
|
||||||
def->enum_labels.push_back(L("10 mm"));
|
{ "1000", L("1000 (unlimited)") }
|
||||||
def->enum_labels.push_back(L("1000 (unlimited)"));
|
});
|
||||||
def->mode = def_infill_anchor_min->mode;
|
def->mode = def_infill_anchor_min->mode;
|
||||||
def->set_default_value(new ConfigOptionFloatOrPercent(50, false));
|
def->set_default_value(new ConfigOptionFloatOrPercent(50, false));
|
||||||
|
|
||||||
|
@ -1625,13 +1561,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Ironing Type");
|
def->label = L("Ironing Type");
|
||||||
def->category = L("Ironing");
|
def->category = L("Ironing");
|
||||||
def->tooltip = L("Ironing Type");
|
def->tooltip = L("Ironing Type");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<IroningType>::get_enum_values();
|
def->set_enum<IroningType>({
|
||||||
def->enum_values.push_back("top");
|
{ "top", L("All top surfaces") },
|
||||||
def->enum_values.push_back("topmost");
|
{ "topmost", L("Topmost surface only") },
|
||||||
def->enum_values.push_back("solid");
|
{ "solid", L("All solid surfaces") }
|
||||||
def->enum_labels.push_back(L("All top surfaces"));
|
});
|
||||||
def->enum_labels.push_back(L("Topmost surface only"));
|
|
||||||
def->enum_labels.push_back(L("All solid surfaces"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<IroningType>(IroningType::TopSurfaces));
|
def->set_default_value(new ConfigOptionEnum<IroningType>(IroningType::TopSurfaces));
|
||||||
|
|
||||||
|
@ -1695,13 +1629,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->full_label = L("Purpose of Machine Limits");
|
def->full_label = L("Purpose of Machine Limits");
|
||||||
def->category = L("Machine limits");
|
def->category = L("Machine limits");
|
||||||
def->tooltip = L("How to apply the Machine Limits");
|
def->tooltip = L("How to apply the Machine Limits");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<MachineLimitsUsage>::get_enum_values();
|
def->set_enum<MachineLimitsUsage>({
|
||||||
def->enum_values.push_back("emit_to_gcode");
|
{ "emit_to_gcode", L("Emit to G-code") },
|
||||||
def->enum_values.push_back("time_estimate_only");
|
{ "time_estimate_only", L("Use for time estimate") },
|
||||||
def->enum_values.push_back("ignore");
|
{ "ignore", L("Ignore") }
|
||||||
def->enum_labels.push_back(L("Emit to G-code"));
|
});
|
||||||
def->enum_labels.push_back(L("Use for time estimate"));
|
|
||||||
def->enum_labels.push_back(L("Ignore"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<MachineLimitsUsage>(MachineLimitsUsage::TimeEstimateOnly));
|
def->set_default_value(new ConfigOptionEnum<MachineLimitsUsage>(MachineLimitsUsage::TimeEstimateOnly));
|
||||||
|
|
||||||
|
@ -1947,23 +1879,16 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Host Type");
|
def->label = L("Host Type");
|
||||||
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain "
|
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain "
|
||||||
"the kind of the host.");
|
"the kind of the host.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<PrintHostType>::get_enum_values();
|
def->set_enum<PrintHostType>({
|
||||||
def->enum_values.push_back("prusalink");
|
{ "prusalink", "PrusaLink" },
|
||||||
def->enum_values.push_back("prusaconnect");
|
{ "prusaconnect", "PrusaConnect" },
|
||||||
def->enum_values.push_back("octoprint");
|
{ "octoprint", "OctoPrint" },
|
||||||
def->enum_values.push_back("duet");
|
{ "duet", "Duet" },
|
||||||
def->enum_values.push_back("flashair");
|
{ "flashair", "FlashAir" },
|
||||||
def->enum_values.push_back("astrobox");
|
{ "astrobox", "AstroBox" },
|
||||||
def->enum_values.push_back("repetier");
|
{ "repetier", "Repetier" },
|
||||||
def->enum_values.push_back("mks");
|
{ "mks", "MKS" }
|
||||||
def->enum_labels.push_back("PrusaLink");
|
});
|
||||||
def->enum_labels.push_back("PrusaConnect");
|
|
||||||
def->enum_labels.push_back("OctoPrint");
|
|
||||||
def->enum_labels.push_back("Duet");
|
|
||||||
def->enum_labels.push_back("FlashAir");
|
|
||||||
def->enum_labels.push_back("AstroBox");
|
|
||||||
def->enum_labels.push_back("Repetier");
|
|
||||||
def->enum_labels.push_back("MKS");
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->cli = ConfigOptionDef::nocli;
|
def->cli = ConfigOptionDef::nocli;
|
||||||
def->set_default_value(new ConfigOptionEnum<PrintHostType>(htPrusaLink));
|
def->set_default_value(new ConfigOptionEnum<PrintHostType>(htPrusaLink));
|
||||||
|
@ -2296,15 +2221,12 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Seam position");
|
def->label = L("Seam position");
|
||||||
def->category = L("Layers and Perimeters");
|
def->category = L("Layers and Perimeters");
|
||||||
def->tooltip = L("Position of perimeters starting points.");
|
def->tooltip = L("Position of perimeters starting points.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SeamPosition>::get_enum_values();
|
def->set_enum<SeamPosition>({
|
||||||
def->enum_values.push_back("random");
|
{ "random", L("Random") },
|
||||||
def->enum_values.push_back("nearest");
|
{ "nearest", L("Nearest") },
|
||||||
def->enum_values.push_back("aligned");
|
{ "aligned", L("Aligned") },
|
||||||
def->enum_values.push_back("rear");
|
{ "rear", L("Rear") }
|
||||||
def->enum_labels.push_back(L("Random"));
|
});
|
||||||
def->enum_labels.push_back(L("Nearest"));
|
|
||||||
def->enum_labels.push_back(L("Aligned"));
|
|
||||||
def->enum_labels.push_back(L("Rear"));
|
|
||||||
def->mode = comSimple;
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spAligned));
|
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spAligned));
|
||||||
|
|
||||||
|
@ -2356,13 +2278,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
"Enabled = skirt is as tall as the highest printed object.\n"
|
"Enabled = skirt is as tall as the highest printed object.\n"
|
||||||
"Limited = skirt is as tall as specified by skirt_height.\n"
|
"Limited = skirt is as tall as specified by skirt_height.\n"
|
||||||
"This is useful to protect an ABS or ASA print from warping and detaching from print bed due to wind draft.");
|
"This is useful to protect an ABS or ASA print from warping and detaching from print bed due to wind draft.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<DraftShield>::get_enum_values();
|
def->set_enum<DraftShield>({
|
||||||
def->enum_values.push_back("disabled");
|
{ "disabled", L("Disabled") },
|
||||||
def->enum_values.push_back("limited");
|
{ "limited", L("Limited") },
|
||||||
def->enum_values.push_back("enabled");
|
{ "enabled", L("Enabled") }
|
||||||
def->enum_labels.push_back(L("Disabled"));
|
});
|
||||||
def->enum_labels.push_back(L("Limited"));
|
|
||||||
def->enum_labels.push_back(L("Enabled"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<DraftShield>(dsDisabled));
|
def->set_default_value(new ConfigOptionEnum<DraftShield>(dsDisabled));
|
||||||
|
|
||||||
|
@ -2579,13 +2499,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Slicing Mode");
|
def->label = L("Slicing Mode");
|
||||||
def->category = L("Advanced");
|
def->category = L("Advanced");
|
||||||
def->tooltip = L("Use \"Even-odd\" for 3DLabPrint airplane models. Use \"Close holes\" to close all holes in the model.");
|
def->tooltip = L("Use \"Even-odd\" for 3DLabPrint airplane models. Use \"Close holes\" to close all holes in the model.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SlicingMode>::get_enum_values();
|
def->set_enum<SlicingMode>({
|
||||||
def->enum_values.push_back("regular");
|
{ "regular", L("Regular") },
|
||||||
def->enum_values.push_back("even_odd");
|
{ "even_odd", L("Even-odd") },
|
||||||
def->enum_values.push_back("close_holes");
|
{ "close_holes", L("Close holes") }
|
||||||
def->enum_labels.push_back(L("Regular"));
|
});
|
||||||
def->enum_labels.push_back(L("Even-odd"));
|
|
||||||
def->enum_labels.push_back(L("Close holes"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
|
def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
|
||||||
|
|
||||||
|
@ -2634,7 +2552,6 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
def = this->add("support_material_contact_distance", coFloat);
|
def = this->add("support_material_contact_distance", coFloat);
|
||||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
|
||||||
def->label = L("Top contact Z distance");
|
def->label = L("Top contact Z distance");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
def->tooltip = L("The vertical distance between object and support material interface. "
|
def->tooltip = L("The vertical distance between object and support material interface. "
|
||||||
|
@ -2642,30 +2559,27 @@ void PrintConfigDef::init_fff_params()
|
||||||
"for the first object layer.");
|
"for the first object layer.");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
// def->min = 0;
|
// def->min = 0;
|
||||||
def->enum_values.push_back("0");
|
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||||
def->enum_values.push_back("0.1");
|
{ "0", L("0 (soluble)") },
|
||||||
def->enum_values.push_back("0.2");
|
{ "0.1", L("0.1 (detachable)") },
|
||||||
def->enum_labels.push_back(L("0 (soluble)"));
|
{ "0.2", L("0.2 (detachable)") }
|
||||||
def->enum_labels.push_back(L("0.1 (detachable)"));
|
});
|
||||||
def->enum_labels.push_back(L("0.2 (detachable)"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloat(0.2));
|
def->set_default_value(new ConfigOptionFloat(0.2));
|
||||||
|
|
||||||
def = this->add("support_material_bottom_contact_distance", coFloat);
|
def = this->add("support_material_bottom_contact_distance", coFloat);
|
||||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
|
||||||
def->label = L("Bottom contact Z distance");
|
def->label = L("Bottom contact Z distance");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
def->tooltip = L("The vertical distance between the object top surface and the support material interface. "
|
def->tooltip = L("The vertical distance between the object top surface and the support material interface. "
|
||||||
"If set to zero, support_material_contact_distance will be used for both top and bottom contact Z distances.");
|
"If set to zero, support_material_contact_distance will be used for both top and bottom contact Z distances.");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
// def->min = 0;
|
// def->min = 0;
|
||||||
def->enum_values.push_back("0");
|
|
||||||
def->enum_values.push_back("0.1");
|
|
||||||
def->enum_values.push_back("0.2");
|
|
||||||
//TRN To be shown in Print Settings "Bottom contact Z distance". Have to be as short as possible
|
//TRN To be shown in Print Settings "Bottom contact Z distance". Have to be as short as possible
|
||||||
def->enum_labels.push_back(L("Same as top"));
|
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||||
def->enum_labels.push_back("0.1");
|
{ "0", L("Same as top") },
|
||||||
def->enum_labels.push_back("0.2");
|
{ "0.1", "0.1" },
|
||||||
|
{ "0.2", "0.2" }
|
||||||
|
});
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloat(0));
|
def->set_default_value(new ConfigOptionFloat(0));
|
||||||
|
|
||||||
|
@ -2720,36 +2634,35 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->set_default_value(new ConfigOptionInt(1));
|
def->set_default_value(new ConfigOptionInt(1));
|
||||||
|
|
||||||
auto support_material_interface_layers = def = this->add("support_material_interface_layers", coInt);
|
auto support_material_interface_layers = def = this->add("support_material_interface_layers", coInt);
|
||||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
|
||||||
def->label = L("Top interface layers");
|
def->label = L("Top interface layers");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
def->tooltip = L("Number of interface layers to insert between the object(s) and support material.");
|
def->tooltip = L("Number of interface layers to insert between the object(s) and support material.");
|
||||||
def->sidetext = L("layers");
|
def->sidetext = L("layers");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->enum_values.push_back("0");
|
def->set_enum_values(ConfigOptionDef::GUIType::i_enum_open, {
|
||||||
def->enum_values.push_back("1");
|
{ "0", L("0 (off)") },
|
||||||
def->enum_values.push_back("2");
|
{ "1", L("1 (light)") },
|
||||||
def->enum_values.push_back("3");
|
{ "2", L("2 (default)") },
|
||||||
def->enum_labels.push_back(L("0 (off)"));
|
{ "3", L("3 (heavy)") }
|
||||||
def->enum_labels.push_back(L("1 (light)"));
|
});
|
||||||
def->enum_labels.push_back(L("2 (default)"));
|
|
||||||
def->enum_labels.push_back(L("3 (heavy)"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionInt(3));
|
def->set_default_value(new ConfigOptionInt(3));
|
||||||
|
|
||||||
def = this->add("support_material_bottom_interface_layers", coInt);
|
def = this->add("support_material_bottom_interface_layers", coInt);
|
||||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
|
||||||
def->label = L("Bottom interface layers");
|
def->label = L("Bottom interface layers");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
def->tooltip = L("Number of interface layers to insert between the object(s) and support material. "
|
def->tooltip = L("Number of interface layers to insert between the object(s) and support material. "
|
||||||
"Set to -1 to use support_material_interface_layers");
|
"Set to -1 to use support_material_interface_layers");
|
||||||
def->sidetext = L("layers");
|
def->sidetext = L("layers");
|
||||||
def->min = -1;
|
def->min = -1;
|
||||||
def->enum_values.push_back("-1");
|
|
||||||
append(def->enum_values, support_material_interface_layers->enum_values);
|
|
||||||
//TRN To be shown in Print Settings "Bottom interface layers". Have to be as short as possible
|
//TRN To be shown in Print Settings "Bottom interface layers". Have to be as short as possible
|
||||||
def->enum_labels.push_back(L("Same as top"));
|
def->set_enum_values(ConfigOptionDef::GUIType::i_enum_open, {
|
||||||
append(def->enum_labels, support_material_interface_layers->enum_labels);
|
{ "-1", L("Same as top") },
|
||||||
|
{ "0", L("0 (off)") },
|
||||||
|
{ "1", L("1 (light)") },
|
||||||
|
{ "2", L("2 (default)") },
|
||||||
|
{ "3", L("3 (heavy)") }
|
||||||
|
});
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionInt(-1));
|
def->set_default_value(new ConfigOptionInt(-1));
|
||||||
|
|
||||||
|
@ -2787,13 +2700,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("Pattern");
|
def->label = L("Pattern");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
def->tooltip = L("Pattern used to generate support material.");
|
def->tooltip = L("Pattern used to generate support material.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialPattern>::get_enum_values();
|
def->set_enum<SupportMaterialPattern>({
|
||||||
def->enum_values.push_back("rectilinear");
|
{ "rectilinear", L("Rectilinear") },
|
||||||
def->enum_values.push_back("rectilinear-grid");
|
{ "rectilinear-grid", L("Rectilinear grid") },
|
||||||
def->enum_values.push_back("honeycomb");
|
{ "honeycomb", L("Honeycomb") }
|
||||||
def->enum_labels.push_back(L("Rectilinear"));
|
});
|
||||||
def->enum_labels.push_back(L("Rectilinear grid"));
|
|
||||||
def->enum_labels.push_back(L("Honeycomb"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear));
|
def->set_default_value(new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear));
|
||||||
|
|
||||||
|
@ -2803,13 +2714,11 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->tooltip = L("Pattern used to generate support material interface. "
|
def->tooltip = L("Pattern used to generate support material interface. "
|
||||||
"Default pattern for non-soluble support interface is Rectilinear, "
|
"Default pattern for non-soluble support interface is Rectilinear, "
|
||||||
"while default pattern for soluble support interface is Concentric.");
|
"while default pattern for soluble support interface is Concentric.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values();
|
def->set_enum<SupportMaterialInterfacePattern>({
|
||||||
def->enum_values.push_back("auto");
|
{ "auto", L("Default") },
|
||||||
def->enum_values.push_back("rectilinear");
|
{ "rectilinear", L("Rectilinear") },
|
||||||
def->enum_values.push_back("concentric");
|
{ "concentric", L("Concentric") }
|
||||||
def->enum_labels.push_back(L("Default"));
|
});
|
||||||
def->enum_labels.push_back(L("Rectilinear"));
|
|
||||||
def->enum_labels.push_back(L("Concentric"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<SupportMaterialInterfacePattern>(smipRectilinear));
|
def->set_default_value(new ConfigOptionEnum<SupportMaterialInterfacePattern>(smipRectilinear));
|
||||||
|
|
||||||
|
@ -2837,8 +2746,7 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->tooltip = L("Style and shape of the support towers. Projecting the supports into a regular grid "
|
def->tooltip = L("Style and shape of the support towers. Projecting the supports into a regular grid "
|
||||||
"will create more stable supports, while snug support towers will save material and reduce "
|
"will create more stable supports, while snug support towers will save material and reduce "
|
||||||
"object scarring.");
|
"object scarring.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialStyle>::get_enum_values();
|
def->set_enum<SupportMaterialStyle>({
|
||||||
def->set_enum_values({
|
|
||||||
{ "grid", L("Grid") },
|
{ "grid", L("Grid") },
|
||||||
{ "snug", L("Snug") },
|
{ "snug", L("Snug") },
|
||||||
{ "organic", L("Organic") }
|
{ "organic", L("Organic") }
|
||||||
|
@ -3207,11 +3115,10 @@ void PrintConfigDef::init_fff_params()
|
||||||
"very thin areas is used gap-fill. "
|
"very thin areas is used gap-fill. "
|
||||||
"Arachne engine produces perimeters with variable extrusion width. "
|
"Arachne engine produces perimeters with variable extrusion width. "
|
||||||
"This setting also affects the Concentric infill.");
|
"This setting also affects the Concentric infill.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<PerimeterGeneratorType>::get_enum_values();
|
def->set_enum<PerimeterGeneratorType>({
|
||||||
def->enum_values.push_back("classic");
|
{ "classic", L("Classic") },
|
||||||
def->enum_values.push_back("arachne");
|
{ "arachne", L("Arachne") }
|
||||||
def->enum_labels.push_back(L("Classic"));
|
});
|
||||||
def->enum_labels.push_back(L("Arachne"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Arachne));
|
def->set_default_value(new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Arachne));
|
||||||
|
|
||||||
|
@ -3434,13 +3341,9 @@ void PrintConfigDef::init_sla_support_params(const std::string &prefix)
|
||||||
" Can be zig-zag, cross (double zig-zag) or dynamic which"
|
" Can be zig-zag, cross (double zig-zag) or dynamic which"
|
||||||
" will automatically switch between the first two depending"
|
" will automatically switch between the first two depending"
|
||||||
" on the distance of the two pillars.");
|
" on the distance of the two pillars.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_values();
|
def->set_enum<SLAPillarConnectionMode>(
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_values();
|
ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_names(),
|
||||||
def->enum_values = ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_names();
|
{ L("Zig-Zag"), L("Cross"), L("Dynamic") });
|
||||||
def->enum_labels = ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_names();
|
|
||||||
def->enum_labels[0] = L("Zig-Zag");
|
|
||||||
def->enum_labels[1] = L("Cross");
|
|
||||||
def->enum_labels[2] = L("Dynamic");
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum(SLAPillarConnectionMode::dynamic));
|
def->set_default_value(new ConfigOptionEnum(SLAPillarConnectionMode::dynamic));
|
||||||
|
|
||||||
|
@ -3602,11 +3505,10 @@ void PrintConfigDef::init_sla_params()
|
||||||
def->tooltip = L("Set the actual LCD display orientation inside the SLA printer."
|
def->tooltip = L("Set the actual LCD display orientation inside the SLA printer."
|
||||||
" Portrait mode will flip the meaning of display width and height parameters"
|
" Portrait mode will flip the meaning of display width and height parameters"
|
||||||
" and the output images will be rotated by 90 degrees.");
|
" and the output images will be rotated by 90 degrees.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SLADisplayOrientation>::get_enum_values();
|
def->set_enum<SLADisplayOrientation>({
|
||||||
def->enum_values.push_back("landscape");
|
{ "landscape", L("Landscape") },
|
||||||
def->enum_values.push_back("portrait");
|
{ "portrait", L("Portrait") }
|
||||||
def->enum_labels.push_back(L("Landscape"));
|
});
|
||||||
def->enum_labels.push_back(L("Portrait"));
|
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait));
|
def->set_default_value(new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait));
|
||||||
|
|
||||||
|
@ -3718,13 +3620,9 @@ void PrintConfigDef::init_sla_params()
|
||||||
def = this->add("material_type", coString);
|
def = this->add("material_type", coString);
|
||||||
def->label = L("SLA material type");
|
def->label = L("SLA material type");
|
||||||
def->tooltip = L("SLA material type");
|
def->tooltip = L("SLA material type");
|
||||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open; // TODO: ???
|
|
||||||
def->gui_flags = "show_value";
|
def->gui_flags = "show_value";
|
||||||
def->enum_values.push_back("Tough");
|
def->set_enum_values(ConfigOptionDef::GUIType::select_open,
|
||||||
def->enum_values.push_back("Flexible");
|
{ "Tough", "Flexible", "Casting", "Dental", "Heat-resistant" });
|
||||||
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->set_default_value(new ConfigOptionString("Tough"));
|
||||||
|
|
||||||
def = this->add("initial_layer_height", coFloat);
|
def = this->add("initial_layer_height", coFloat);
|
||||||
|
@ -3898,12 +3796,10 @@ void PrintConfigDef::init_sla_params()
|
||||||
def = this->add("support_tree_type", coEnum);
|
def = this->add("support_tree_type", coEnum);
|
||||||
def->label = L("Support tree type");
|
def->label = L("Support tree type");
|
||||||
def->tooltip = L("Support tree building strategy");
|
def->tooltip = L("Support tree building strategy");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<sla::SupportTreeType>::get_enum_values();
|
def->set_enum<sla::SupportTreeType>(
|
||||||
def->enum_values = ConfigOptionEnum<sla::SupportTreeType>::get_enum_names();
|
ConfigOptionEnum<sla::SupportTreeType>::get_enum_names(),
|
||||||
def->enum_labels = ConfigOptionEnum<sla::SupportTreeType>::get_enum_names();
|
{ L("Default"), L("Branching (experimental)") });
|
||||||
def->enum_labels[0] = L("Default");
|
// TODO: def->enum_def->labels[2] = L("Organic");
|
||||||
def->enum_labels[1] = L("Branching (experimental)");
|
|
||||||
// TODO: def->enum_labels[2] = L("Organic");
|
|
||||||
def->mode = comSimple;
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionEnum(sla::SupportTreeType::Default));
|
def->set_default_value(new ConfigOptionEnum(sla::SupportTreeType::Default));
|
||||||
|
|
||||||
|
@ -4107,13 +4003,11 @@ void PrintConfigDef::init_sla_params()
|
||||||
def->tooltip = L(
|
def->tooltip = L(
|
||||||
"A slower printing profile might be necessary when using materials with higher viscosity "
|
"A slower printing profile might be necessary when using materials with higher viscosity "
|
||||||
"or with some hollowed parts. It slows down the tilt movement and adds a delay before exposure.");
|
"or with some hollowed parts. It slows down the tilt movement and adds a delay before exposure.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SLAMaterialSpeed>::get_enum_values();
|
def->set_enum<SLAMaterialSpeed>({
|
||||||
def->enum_values.push_back("slow");
|
{ "slow", L("Slow") },
|
||||||
def->enum_values.push_back("fast");
|
{ "fast", L("Fast") },
|
||||||
def->enum_values.push_back("high_viscosity");
|
{ "high_viscosity", L("High viscosity") }
|
||||||
def->enum_labels.push_back(L("Slow"));
|
});
|
||||||
def->enum_labels.push_back(L("Fast"));
|
|
||||||
def->enum_labels.push_back(L("High viscosity"));
|
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<SLAMaterialSpeed>(slamsFast));
|
def->set_default_value(new ConfigOptionEnum<SLAMaterialSpeed>(slamsFast));
|
||||||
|
|
||||||
|
@ -4126,7 +4020,7 @@ void PrintConfigDef::init_sla_params()
|
||||||
def->label = L("SLA output precision");
|
def->label = L("SLA output precision");
|
||||||
def->tooltip = L("Minimum resolution in nanometers");
|
def->tooltip = L("Minimum resolution in nanometers");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
def->min = SCALING_FACTOR;
|
def->min = float(SCALING_FACTOR);
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionFloat(0.001));
|
def->set_default_value(new ConfigOptionFloat(0.001));
|
||||||
}
|
}
|
||||||
|
@ -4794,13 +4688,11 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||||
def->tooltip = L("This version of PrusaSlicer may not understand configurations produced by the newest PrusaSlicer versions. "
|
def->tooltip = L("This version of PrusaSlicer may not understand configurations produced by the newest PrusaSlicer versions. "
|
||||||
"For example, newer PrusaSlicer may extend the list of supported firmware flavors. One may decide to "
|
"For example, newer PrusaSlicer may extend the list of supported firmware flavors. One may decide to "
|
||||||
"bail out or to substitute an unknown value with a default silently or verbosely.");
|
"bail out or to substitute an unknown value with a default silently or verbosely.");
|
||||||
def->enum_keys_map = &ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>::get_enum_values();
|
def->set_enum<ForwardCompatibilitySubstitutionRule>({
|
||||||
def->enum_values.push_back("disable");
|
{ "disable", L("Bail out on unknown configuration values") },
|
||||||
def->enum_values.push_back("enable");
|
{ "enable", L("Enable reading unknown configuration values by verbosely substituting them with defaults.") },
|
||||||
def->enum_values.push_back("enable_silent");
|
{ "enable_silent", L("Enable reading unknown configuration values by silently substituting them with defaults.") }
|
||||||
def->enum_labels.push_back(L("Bail out on unknown configuration values"));
|
});
|
||||||
def->enum_labels.push_back(L("Enable reading unknown configuration values by verbosely substituting them with defaults."));
|
|
||||||
def->enum_labels.push_back(L("Enable reading unknown configuration values by silently substituting them with defaults."));
|
|
||||||
def->set_default_value(new ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>(ForwardCompatibilitySubstitutionRule::Enable));
|
def->set_default_value(new ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>(ForwardCompatibilitySubstitutionRule::Enable));
|
||||||
|
|
||||||
def = this->add("load", coStrings);
|
def = this->add("load", coStrings);
|
||||||
|
|
|
@ -1260,11 +1260,11 @@ namespace SupportMaterialInternal {
|
||||||
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
|
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_bridges_from_contacts(
|
void remove_bridges_from_contacts(
|
||||||
const PrintConfig &print_config,
|
const PrintConfig &print_config,
|
||||||
const Layer &lower_layer,
|
const Layer &lower_layer,
|
||||||
const Polygons &lower_layer_polygons,
|
|
||||||
const LayerRegion &layerm,
|
const LayerRegion &layerm,
|
||||||
float fw,
|
float fw,
|
||||||
Polygons &contact_polygons)
|
Polygons &contact_polygons)
|
||||||
|
@ -1273,7 +1273,7 @@ namespace SupportMaterialInternal {
|
||||||
Polygons bridges;
|
Polygons bridges;
|
||||||
{
|
{
|
||||||
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
|
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
|
||||||
Polygons lower_grown_slices = expand(lower_layer_polygons,
|
Polygons lower_grown_slices = expand(lower_layer.lslices,
|
||||||
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
|
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
|
||||||
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().perimeter_extruder-1))),
|
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().perimeter_extruder-1))),
|
||||||
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||||
|
@ -1341,7 +1341,6 @@ namespace SupportMaterialInternal {
|
||||||
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
||||||
#endif /* SLIC3R_DEBUG */
|
#endif /* SLIC3R_DEBUG */
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Polygons> PrintObjectSupportMaterial::buildplate_covered(const PrintObject &object) const
|
std::vector<Polygons> PrintObjectSupportMaterial::buildplate_covered(const PrintObject &object) const
|
||||||
{
|
{
|
||||||
|
@ -1558,8 +1557,7 @@ static inline std::tuple<Polygons, Polygons, Polygons, float> detect_overhangs(
|
||||||
|
|
||||||
if (object_config.dont_support_bridges)
|
if (object_config.dont_support_bridges)
|
||||||
//FIXME Expensive, potentially not precise enough. Misses gap fill extrusions, which bridge.
|
//FIXME Expensive, potentially not precise enough. Misses gap fill extrusions, which bridge.
|
||||||
SupportMaterialInternal::remove_bridges_from_contacts(
|
remove_bridges_from_contacts(print_config, lower_layer, *layerm, fw, diff_polygons);
|
||||||
print_config, lower_layer, lower_layer_polygons, *layerm, fw, diff_polygons);
|
|
||||||
|
|
||||||
if (diff_polygons.empty())
|
if (diff_polygons.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -147,6 +147,15 @@ struct SupportParameters {
|
||||||
bool with_sheath;
|
bool with_sheath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Remove bridges from support contact areas.
|
||||||
|
// To be called if PrintObjectConfig::dont_support_bridges.
|
||||||
|
void remove_bridges_from_contacts(
|
||||||
|
const PrintConfig &print_config,
|
||||||
|
const Layer &lower_layer,
|
||||||
|
const LayerRegion &layerm,
|
||||||
|
float fw,
|
||||||
|
Polygons &contact_polygons);
|
||||||
|
|
||||||
// Generate raft layers, also expand the 1st support layer
|
// Generate raft layers, also expand the 1st support layer
|
||||||
// in case there is no raft layer to improve support adhesion.
|
// in case there is no raft layer to improve support adhesion.
|
||||||
SupportGeneratorLayersPtr generate_raft_base(
|
SupportGeneratorLayersPtr generate_raft_base(
|
||||||
|
|
|
@ -954,7 +954,7 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject *po,
|
||||||
float unchecked_dist = params.min_distance_between_support_points + 1.0f;
|
float unchecked_dist = params.min_distance_between_support_points + 1.0f;
|
||||||
|
|
||||||
for (const ExtrusionLine &line : current_slice_ext_perims_lines) {
|
for (const ExtrusionLine &line : current_slice_ext_perims_lines) {
|
||||||
if ((unchecked_dist + line.len < params.min_distance_between_support_points && line.curled_up_height < 0.3f) ||
|
if ((unchecked_dist + line.len < params.min_distance_between_support_points && line.curled_up_height < params.curling_tolerance_limit) ||
|
||||||
line.len < EPSILON) {
|
line.len < EPSILON) {
|
||||||
unchecked_dist += line.len;
|
unchecked_dist += line.len;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1077,14 +1077,14 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ExtrusionLine &line : current_layer_lines) {
|
for (const ExtrusionLine &line : current_layer_lines) {
|
||||||
if (line.curled_up_height > 0.3f) {
|
if (line.curled_up_height > params.curling_tolerance_limit) {
|
||||||
l->malformed_lines.push_back(Line{Point::new_scale(line.a), Point::new_scale(line.b)});
|
l->malformed_lines.push_back(Line{Point::new_scale(line.a), Point::new_scale(line.b)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_FILES
|
#ifdef DEBUG_FILES
|
||||||
for (const ExtrusionLine &line : current_layer_lines) {
|
for (const ExtrusionLine &line : current_layer_lines) {
|
||||||
if (line.curled_up_height > 0.3f) {
|
if (line.curled_up_height > params.curling_tolerance_limit) {
|
||||||
Vec3f color = value_to_rgbf(-EPSILON, l->height * params.max_curled_height_factor, line.curled_up_height);
|
Vec3f color = value_to_rgbf(-EPSILON, l->height * params.max_curled_height_factor, line.curled_up_height);
|
||||||
fprintf(debug_file, "v %f %f %f %f %f %f\n", line.b[0], line.b[1], l->print_z, color[0], color[1], color[2]);
|
fprintf(debug_file, "v %f %f %f %f %f %f\n", line.b[0], line.b[1], l->print_z, color[0], color[1], color[2]);
|
||||||
}
|
}
|
||||||
|
@ -1150,14 +1150,14 @@ void estimate_malformations(LayerPtrs &layers, const Params ¶ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ExtrusionLine &line : current_layer_lines) {
|
for (const ExtrusionLine &line : current_layer_lines) {
|
||||||
if (line.curled_up_height > 0.3f) {
|
if (line.curled_up_height > params.curling_tolerance_limit) {
|
||||||
l->malformed_lines.push_back(Line{Point::new_scale(line.a), Point::new_scale(line.b)});
|
l->malformed_lines.push_back(Line{Point::new_scale(line.a), Point::new_scale(line.b)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_FILES
|
#ifdef DEBUG_FILES
|
||||||
for (const ExtrusionLine &line : current_layer_lines) {
|
for (const ExtrusionLine &line : current_layer_lines) {
|
||||||
if (line.curled_up_height > 0.3f) {
|
if (line.curled_up_height > params.curling_tolerance_limit) {
|
||||||
Vec3f color = value_to_rgbf(-EPSILON, l->height * params.max_curled_height_factor, line.curled_up_height);
|
Vec3f color = value_to_rgbf(-EPSILON, l->height * params.max_curled_height_factor, line.curled_up_height);
|
||||||
fprintf(debug_file, "v %f %f %f %f %f %f\n", line.b[0], line.b[1], l->print_z, color[0], color[1], color[2]);
|
fprintf(debug_file, "v %f %f %f %f %f %f\n", line.b[0], line.b[1], l->print_z, color[0], color[1], color[2]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct Params
|
||||||
|
|
||||||
const std::pair<float,float> malformation_distance_factors = std::pair<float, float> { 0.5, 1.1 };
|
const std::pair<float,float> malformation_distance_factors = std::pair<float, float> { 0.5, 1.1 };
|
||||||
const float max_curled_height_factor = 10.0f;
|
const float max_curled_height_factor = 10.0f;
|
||||||
|
const float curling_tolerance_limit = 0.1f;
|
||||||
|
|
||||||
const float min_distance_between_support_points = 3.0f; //mm
|
const float min_distance_between_support_points = 3.0f; //mm
|
||||||
const float support_points_interface_radius = 1.5f; // mm
|
const float support_points_interface_radius = 1.5f; // mm
|
||||||
|
|
|
@ -191,6 +191,26 @@ std::optional<std::string> get_current_thread_name()
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// To be called at the start of the application to save the current thread ID as the main (UI) thread ID.
|
||||||
|
static boost::thread::id g_main_thread_id;
|
||||||
|
|
||||||
|
void save_main_thread_id()
|
||||||
|
{
|
||||||
|
g_main_thread_id = boost::this_thread::get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the cached main (UI) thread ID.
|
||||||
|
boost::thread::id get_main_thread_id()
|
||||||
|
{
|
||||||
|
return g_main_thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether the main (UI) thread is active.
|
||||||
|
bool is_main_thread_active()
|
||||||
|
{
|
||||||
|
return get_main_thread_id() == boost::this_thread::get_id();
|
||||||
|
}
|
||||||
|
|
||||||
// Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID.
|
// Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID.
|
||||||
// Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator.
|
// Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator.
|
||||||
void name_tbb_thread_pool_threads_set_locale()
|
void name_tbb_thread_pool_threads_set_locale()
|
||||||
|
|
|
@ -29,6 +29,13 @@ inline bool set_thread_name(boost::thread &thread, const std::string &thread_nam
|
||||||
bool set_current_thread_name(const char *thread_name);
|
bool set_current_thread_name(const char *thread_name);
|
||||||
inline bool set_current_thread_name(const std::string &thread_name) { return set_current_thread_name(thread_name.c_str()); }
|
inline bool set_current_thread_name(const std::string &thread_name) { return set_current_thread_name(thread_name.c_str()); }
|
||||||
|
|
||||||
|
// To be called at the start of the application to save the current thread ID as the main (UI) thread ID.
|
||||||
|
void save_main_thread_id();
|
||||||
|
// Retrieve the cached main (UI) thread ID.
|
||||||
|
boost::thread::id get_main_thread_id();
|
||||||
|
// Checks whether the main (UI) thread is active.
|
||||||
|
bool is_main_thread_active();
|
||||||
|
|
||||||
// OSX specific: Set Quality of Service to "user initiated", so that the threads will be scheduled to high performance
|
// OSX specific: Set Quality of Service to "user initiated", so that the threads will be scheduled to high performance
|
||||||
// cores if available.
|
// cores if available.
|
||||||
void set_current_thread_qos();
|
void set_current_thread_qos();
|
||||||
|
|
|
@ -42,7 +42,7 @@ TreeSupportMeshGroupSettings::TreeSupportMeshGroupSettings(const PrintObject &pr
|
||||||
// const std::vector<unsigned int> printing_extruders = print_object.object_extruders();
|
// const std::vector<unsigned int> printing_extruders = print_object.object_extruders();
|
||||||
|
|
||||||
// Support must be enabled and set to Tree style.
|
// Support must be enabled and set to Tree style.
|
||||||
assert(config.support_material);
|
assert(config.support_material || config.support_material_enforce_layers > 0);
|
||||||
assert(config.support_material_style == smsTree || config.support_material_style == smsOrganic);
|
assert(config.support_material_style == smsTree || config.support_material_style == smsOrganic);
|
||||||
|
|
||||||
// Calculate maximum external perimeter width over all printing regions, taking into account the default layer height.
|
// Calculate maximum external perimeter width over all printing regions, taking into account the default layer height.
|
||||||
|
|
|
@ -154,7 +154,7 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
||||||
const PrintObjectConfig &object_config = print_object.config();
|
const PrintObjectConfig &object_config = print_object.config();
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
// Support must be enabled and set to Tree style.
|
// Support must be enabled and set to Tree style.
|
||||||
assert(object_config.support_material);
|
assert(object_config.support_material || object_config.support_material_enforce_layers > 0);
|
||||||
assert(object_config.support_material_style == smsTree || object_config.support_material_style == smsOrganic);
|
assert(object_config.support_material_style == smsTree || object_config.support_material_style == smsOrganic);
|
||||||
|
|
||||||
bool found_existing_group = false;
|
bool found_existing_group = false;
|
||||||
|
@ -226,8 +226,9 @@ void tree_supports_show_error(std::string_view message, bool critical)
|
||||||
{
|
{
|
||||||
std::vector<Polygons> out(print_object.layer_count(), Polygons{});
|
std::vector<Polygons> out(print_object.layer_count(), Polygons{});
|
||||||
|
|
||||||
|
const PrintConfig &print_config = print_object.print()->config();
|
||||||
const PrintObjectConfig &config = print_object.config();
|
const PrintObjectConfig &config = print_object.config();
|
||||||
const bool support_auto = config.support_material_auto.value;
|
const bool support_auto = config.support_material.value && config.support_material_auto.value;
|
||||||
const int support_enforce_layers = config.support_material_enforce_layers.value;
|
const int support_enforce_layers = config.support_material_enforce_layers.value;
|
||||||
std::vector<Polygons> enforcers_layers{ print_object.slice_support_enforcers() };
|
std::vector<Polygons> enforcers_layers{ print_object.slice_support_enforcers() };
|
||||||
std::vector<Polygons> blockers_layers{ print_object.slice_support_blockers() };
|
std::vector<Polygons> blockers_layers{ print_object.slice_support_blockers() };
|
||||||
|
@ -240,8 +241,10 @@ void tree_supports_show_error(std::string_view message, bool critical)
|
||||||
//FIXME this is a fudge constant!
|
//FIXME this is a fudge constant!
|
||||||
auto enforcer_overhang_offset = scaled<double>(config.support_tree_tip_diameter.value);
|
auto enforcer_overhang_offset = scaled<double>(config.support_tree_tip_diameter.value);
|
||||||
|
|
||||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(1, out.size()),
|
size_t num_overhang_layers = support_auto ? out.size() : std::max(size_t(support_enforce_layers), enforcers_layers.size());
|
||||||
[&print_object, &enforcers_layers, &blockers_layers, support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, &throw_on_cancel, &out]
|
tbb::parallel_for(tbb::blocked_range<LayerIndex>(1, num_overhang_layers),
|
||||||
|
[&print_object, &config, &print_config, &enforcers_layers, &blockers_layers,
|
||||||
|
support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, &throw_on_cancel, &out]
|
||||||
(const tbb::blocked_range<LayerIndex> &range) {
|
(const tbb::blocked_range<LayerIndex> &range) {
|
||||||
for (LayerIndex layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
for (LayerIndex layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
||||||
const Layer ¤t_layer = *print_object.get_layer(layer_id);
|
const Layer ¤t_layer = *print_object.get_layer(layer_id);
|
||||||
|
@ -274,6 +277,11 @@ void tree_supports_show_error(std::string_view message, bool critical)
|
||||||
}
|
}
|
||||||
if (! (enforced_layer || blockers_layers.empty() || blockers_layers[layer_id].empty()))
|
if (! (enforced_layer || blockers_layers.empty() || blockers_layers[layer_id].empty()))
|
||||||
overhangs = diff(overhangs, blockers_layers[layer_id], ApplySafetyOffset::Yes);
|
overhangs = diff(overhangs, blockers_layers[layer_id], ApplySafetyOffset::Yes);
|
||||||
|
if (config.dont_support_bridges) {
|
||||||
|
for (const LayerRegion *layerm : current_layer.regions())
|
||||||
|
remove_bridges_from_contacts(print_config, lower_layer, *layerm,
|
||||||
|
float(layerm->flow(frExternalPerimeter).scaled_width()), overhangs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//check_self_intersections(overhangs, "generate_overhangs1");
|
//check_self_intersections(overhangs, "generate_overhangs1");
|
||||||
if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) {
|
if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) {
|
||||||
|
@ -2936,7 +2944,11 @@ static void finalize_interface_and_support_areas(
|
||||||
|
|
||||||
std::function<void()> throw_on_cancel)
|
std::function<void()> throw_on_cancel)
|
||||||
{
|
{
|
||||||
InterfacePreference interface_pref = config.interface_preference; // InterfacePreference::SupportLinesOverwriteInterface;
|
assert(std::all_of(bottom_contacts.begin(), bottom_contacts.end(), [](auto *p) { return p == nullptr; }));
|
||||||
|
// assert(std::all_of(top_contacts.begin(), top_contacts.end(), [](auto* p) { return p == nullptr; }));
|
||||||
|
assert(std::all_of(intermediate_layers.begin(), intermediate_layers.end(), [](auto* p) { return p == nullptr; }));
|
||||||
|
|
||||||
|
InterfacePreference interface_pref = config.interface_preference; // InterfacePreference::InterfaceAreaOverwritesSupport;
|
||||||
|
|
||||||
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
double progress_total = TREE_PROGRESS_PRECALC_AVO + TREE_PROGRESS_PRECALC_COLL + TREE_PROGRESS_GENERATE_NODES + TREE_PROGRESS_AREA_CALC + TREE_PROGRESS_GENERATE_BRANCH_AREAS + TREE_PROGRESS_SMOOTH_BRANCH_AREAS;
|
double progress_total = TREE_PROGRESS_PRECALC_AVO + TREE_PROGRESS_PRECALC_COLL + TREE_PROGRESS_GENERATE_NODES + TREE_PROGRESS_AREA_CALC + TREE_PROGRESS_GENERATE_BRANCH_AREAS + TREE_PROGRESS_SMOOTH_BRANCH_AREAS;
|
||||||
|
@ -2947,29 +2959,41 @@ static void finalize_interface_and_support_areas(
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, support_layer_storage.size()),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, support_layer_storage.size()),
|
||||||
[&](const tbb::blocked_range<size_t> &range) {
|
[&](const tbb::blocked_range<size_t> &range) {
|
||||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||||
// Most of the time in this function is this union call. Can take 300+ ms when a lot of areas are to be unioned.
|
|
||||||
support_layer_storage[layer_idx] = smooth_outward(union_(support_layer_storage[layer_idx]), config.support_line_width); //FIXME was .smooth(50);
|
|
||||||
//smooth_outward(closing(std::move(bottom), closing_distance + minimum_island_radius, closing_distance, SUPPORT_SURFACES_OFFSET_PARAMETERS), smoothing_distance) :
|
|
||||||
|
|
||||||
// simplify a bit, to ensure the output does not contain outrageous amounts of vertices. Should not be necessary, just a precaution.
|
|
||||||
support_layer_storage[layer_idx] = polygons_simplify(support_layer_storage[layer_idx], std::min(scaled<double>(0.03), double(config.resolution)));
|
|
||||||
// Subtract support lines of the branches from the roof
|
// Subtract support lines of the branches from the roof
|
||||||
SupportGeneratorLayer*& support_roof = top_contacts[layer_idx];
|
SupportGeneratorLayer *support_roof = top_contacts[layer_idx];
|
||||||
if (! support_roof_storage[layer_idx].empty() || support_roof != nullptr) {
|
Polygons support_roof_polygons;
|
||||||
if (support_roof == nullptr) {
|
|
||||||
support_roof = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::TopContact, print_object.slicing_parameters(), layer_idx);
|
|
||||||
support_roof->polygons = union_(support_roof_storage[layer_idx]);
|
|
||||||
} else
|
|
||||||
support_roof->polygons = union_(support_roof->polygons, support_roof_storage[layer_idx]);
|
|
||||||
|
|
||||||
if (! support_roof->polygons.empty() &&
|
if (Polygons &src = support_roof_storage[layer_idx]; ! src.empty()) {
|
||||||
area(intersection(support_layer_storage[layer_idx], support_roof->polygons)) > tiny_area_threshold) {
|
if (support_roof != nullptr && ! support_roof->polygons.empty()) {
|
||||||
|
support_roof_polygons = union_(src, support_roof->polygons);
|
||||||
|
support_roof->polygons.clear();
|
||||||
|
} else
|
||||||
|
support_roof_polygons = std::move(src);
|
||||||
|
} else if (support_roof != nullptr) {
|
||||||
|
support_roof_polygons = std::move(support_roof->polygons);
|
||||||
|
support_roof->polygons.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(intermediate_layers[layer_idx] == nullptr);
|
||||||
|
Polygons base_layer_polygons = std::move(support_layer_storage[layer_idx]);
|
||||||
|
|
||||||
|
if (! base_layer_polygons.empty()) {
|
||||||
|
// Most of the time in this function is this union call. Can take 300+ ms when a lot of areas are to be unioned.
|
||||||
|
base_layer_polygons = smooth_outward(union_(base_layer_polygons), config.support_line_width); //FIXME was .smooth(50);
|
||||||
|
//smooth_outward(closing(std::move(bottom), closing_distance + minimum_island_radius, closing_distance, SUPPORT_SURFACES_OFFSET_PARAMETERS), smoothing_distance) :
|
||||||
|
// simplify a bit, to ensure the output does not contain outrageous amounts of vertices. Should not be necessary, just a precaution.
|
||||||
|
base_layer_polygons = polygons_simplify(base_layer_polygons, std::min(scaled<double>(0.03), double(config.resolution)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! support_roof_polygons.empty() && ! base_layer_polygons.empty()) {
|
||||||
|
// if (area(intersection(base_layer_polygons, support_roof_polygons)) > tiny_area_threshold)
|
||||||
|
{
|
||||||
switch (interface_pref) {
|
switch (interface_pref) {
|
||||||
case InterfacePreference::InterfaceAreaOverwritesSupport:
|
case InterfacePreference::InterfaceAreaOverwritesSupport:
|
||||||
support_layer_storage[layer_idx] = diff(support_layer_storage[layer_idx], support_roof->polygons);
|
base_layer_polygons = diff(base_layer_polygons, support_roof_polygons);
|
||||||
break;
|
break;
|
||||||
case InterfacePreference::SupportAreaOverwritesInterface:
|
case InterfacePreference::SupportAreaOverwritesInterface:
|
||||||
support_roof->polygons = diff(support_roof->polygons, support_layer_storage[layer_idx]);
|
support_roof_polygons = diff(support_roof_polygons, base_layer_polygons);
|
||||||
break;
|
break;
|
||||||
//FIXME
|
//FIXME
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -2984,14 +3008,14 @@ static void finalize_interface_and_support_areas(
|
||||||
Polygons interface_lines = offset(to_polylines(
|
Polygons interface_lines = offset(to_polylines(
|
||||||
generate_support_infill_lines(support_roof->polygons, true, layer_idx, config.support_roof_line_distance)),
|
generate_support_infill_lines(support_roof->polygons, true, layer_idx, config.support_roof_line_distance)),
|
||||||
config.support_roof_line_width / 2);
|
config.support_roof_line_width / 2);
|
||||||
support_layer_storage[layer_idx] = diff(support_layer_storage[layer_idx], interface_lines);
|
base_layer_polygons = diff(base_layer_polygons, interface_lines);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InterfacePreference::SupportLinesOverwriteInterface:
|
case InterfacePreference::SupportLinesOverwriteInterface:
|
||||||
{
|
{
|
||||||
// Hatch the support roof interfaces, offset them by their line width and subtract them from support base.
|
// Hatch the support roof interfaces, offset them by their line width and subtract them from support base.
|
||||||
Polygons tree_lines = union_(offset(to_polylines(
|
Polygons tree_lines = union_(offset(to_polylines(
|
||||||
generate_support_infill_lines(support_layer_storage[layer_idx], false, layer_idx, config.support_line_distance, true)),
|
generate_support_infill_lines(base_layer_polygons, false, layer_idx, config.support_line_distance, true)),
|
||||||
config.support_line_width / 2));
|
config.support_line_width / 2));
|
||||||
// do not draw roof where the tree is. I prefer it this way as otherwise the roof may cut of a branch from its support below.
|
// do not draw roof where the tree is. I prefer it this way as otherwise the roof may cut of a branch from its support below.
|
||||||
support_roof->polygons = diff(support_roof->polygons, tree_lines);
|
support_roof->polygons = diff(support_roof->polygons, tree_lines);
|
||||||
|
@ -3005,10 +3029,10 @@ static void finalize_interface_and_support_areas(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subtract support floors from the support area and add them to the support floor instead.
|
// Subtract support floors from the support area and add them to the support floor instead.
|
||||||
if (config.support_bottom_layers > 0 && !support_layer_storage[layer_idx].empty()) {
|
if (config.support_bottom_layers > 0 && ! base_layer_polygons.empty()) {
|
||||||
SupportGeneratorLayer*& support_bottom = bottom_contacts[layer_idx];
|
SupportGeneratorLayer*& support_bottom = bottom_contacts[layer_idx];
|
||||||
Polygons layer_outset = diff_clipped(
|
Polygons layer_outset = diff_clipped(
|
||||||
config.support_bottom_offset > 0 ? offset(support_layer_storage[layer_idx], config.support_bottom_offset, jtMiter, 1.2) : support_layer_storage[layer_idx],
|
config.support_bottom_offset > 0 ? offset(base_layer_polygons, config.support_bottom_offset, jtMiter, 1.2) : base_layer_polygons,
|
||||||
volumes.getCollision(0, layer_idx, false));
|
volumes.getCollision(0, layer_idx, false));
|
||||||
Polygons floor_layer;
|
Polygons floor_layer;
|
||||||
size_t layers_below = 0;
|
size_t layers_below = 0;
|
||||||
|
@ -3026,15 +3050,18 @@ static void finalize_interface_and_support_areas(
|
||||||
if (support_bottom == nullptr)
|
if (support_bottom == nullptr)
|
||||||
support_bottom = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::BottomContact, print_object.slicing_parameters(), layer_idx);
|
support_bottom = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::BottomContact, print_object.slicing_parameters(), layer_idx);
|
||||||
support_bottom->polygons = union_(floor_layer, support_bottom->polygons);
|
support_bottom->polygons = union_(floor_layer, support_bottom->polygons);
|
||||||
support_layer_storage[layer_idx] = diff_clipped(support_layer_storage[layer_idx], offset(support_bottom->polygons, scaled<float>(0.01), jtMiter, 1.2)); // Subtract the support floor from the normal support.
|
base_layer_polygons = diff_clipped(base_layer_polygons, offset(support_bottom->polygons, scaled<float>(0.01), jtMiter, 1.2)); // Subtract the support floor from the normal support.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! support_layer_storage[layer_idx].empty()) {
|
if (! support_roof_polygons.empty()) {
|
||||||
SupportGeneratorLayer *&l = intermediate_layers[layer_idx];
|
if (support_roof == nullptr)
|
||||||
if (l == nullptr)
|
support_roof = top_contacts[layer_idx] = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::TopContact, print_object.slicing_parameters(), layer_idx);
|
||||||
l = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::Base, print_object.slicing_parameters(), layer_idx);
|
support_roof->polygons = union_(support_roof_polygons);
|
||||||
append(l->polygons, union_(support_layer_storage[layer_idx]));
|
}
|
||||||
|
if (! base_layer_polygons.empty()) {
|
||||||
|
SupportGeneratorLayer *base_layer = intermediate_layers[layer_idx] = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::Base, print_object.slicing_parameters(), layer_idx);
|
||||||
|
base_layer->polygons = union_(base_layer_polygons);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
|
@ -3911,25 +3938,15 @@ static void slice_branches(
|
||||||
params.closing_radius = float(print_object.config().slice_closing_radius.value);
|
params.closing_radius = float(print_object.config().slice_closing_radius.value);
|
||||||
params.mode = MeshSlicingParams::SlicingMode::Positive;
|
params.mode = MeshSlicingParams::SlicingMode::Positive;
|
||||||
std::vector<ExPolygons> slices = slice_mesh_ex(cummulative_mesh, slice_z, params, throw_on_cancel);
|
std::vector<ExPolygons> slices = slice_mesh_ex(cummulative_mesh, slice_z, params, throw_on_cancel);
|
||||||
for (size_t layer_idx = 0; layer_idx < slice_z.size(); ++ layer_idx)
|
|
||||||
if (! slices[layer_idx].empty()) {
|
|
||||||
SupportGeneratorLayer *&l = intermediate_layers[layer_idx];
|
|
||||||
if (l == nullptr)
|
|
||||||
l = &layer_allocate(layer_storage, SupporLayerType::Base, slicing_params, layer_idx);
|
|
||||||
append(l->polygons, to_polygons(std::move(slices[layer_idx])));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim the slices.
|
// Trim the slices.
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, intermediate_layers.size()),
|
std::vector<Polygons> support_layer_storage(move_bounds.size());
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, slices.size()),
|
||||||
[&](const tbb::blocked_range<size_t> &range) {
|
[&](const tbb::blocked_range<size_t> &range) {
|
||||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx)
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx)
|
||||||
if (SupportGeneratorLayer *layer = intermediate_layers[layer_idx]; layer) {
|
if (ExPolygons &src = slices[layer_idx]; ! src.empty())
|
||||||
Polygons &poly = intermediate_layers[layer_idx]->polygons;
|
support_layer_storage[layer_idx] = diff_clipped(to_polygons(std::move(src)), volumes.getCollision(0, layer_idx, true));
|
||||||
poly = diff_clipped(poly, volumes.getCollision(0, layer_idx, true));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<Polygons> support_layer_storage(move_bounds.size());
|
|
||||||
std::vector<Polygons> support_roof_storage(move_bounds.size());
|
std::vector<Polygons> support_roof_storage(move_bounds.size());
|
||||||
finalize_interface_and_support_areas(print_object, volumes, config, overhangs, support_layer_storage, support_roof_storage,
|
finalize_interface_and_support_areas(print_object, volumes, config, overhangs, support_layer_storage, support_roof_storage,
|
||||||
bottom_contacts, top_contacts, intermediate_layers, layer_storage, throw_on_cancel);
|
bottom_contacts, top_contacts, intermediate_layers, layer_storage, throw_on_cancel);
|
||||||
|
|
|
@ -310,7 +310,8 @@ struct TreeSupportSettings
|
||||||
// interface_preference = interface_map.at(mesh_group_settings.get<std::string>("support_interface_priority"));
|
// interface_preference = interface_map.at(mesh_group_settings.get<std::string>("support_interface_priority"));
|
||||||
//FIXME this was the default
|
//FIXME this was the default
|
||||||
// interface_preference = InterfacePreference::SupportLinesOverwriteInterface;
|
// interface_preference = InterfacePreference::SupportLinesOverwriteInterface;
|
||||||
interface_preference = InterfacePreference::SupportAreaOverwritesInterface;
|
//interface_preference = InterfacePreference::SupportAreaOverwritesInterface;
|
||||||
|
interface_preference = InterfacePreference::InterfaceAreaOverwritesSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -386,7 +386,9 @@ void GLVolume::render()
|
||||||
if (shader == nullptr)
|
if (shader == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this->is_left_handed())
|
const bool is_left_handed = this->is_left_handed();
|
||||||
|
|
||||||
|
if (is_left_handed)
|
||||||
glsafe(::glFrontFace(GL_CW));
|
glsafe(::glFrontFace(GL_CW));
|
||||||
glsafe(::glCullFace(GL_BACK));
|
glsafe(::glCullFace(GL_BACK));
|
||||||
|
|
||||||
|
@ -395,7 +397,7 @@ void GLVolume::render()
|
||||||
else
|
else
|
||||||
model.render(this->tverts_range);
|
model.render(this->tverts_range);
|
||||||
|
|
||||||
if (this->is_left_handed())
|
if (is_left_handed)
|
||||||
glsafe(::glFrontFace(GL_CCW));
|
glsafe(::glFrontFace(GL_CCW));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,6 +795,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
glsafe(::glDisable(GL_CULL_FACE));
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
|
const Transform3d& world_matrix = volume.first->world_matrix();
|
||||||
volume.first->set_render_color(true);
|
volume.first->set_render_color(true);
|
||||||
|
|
||||||
// render sinking contours of non-hovered volumes
|
// render sinking contours of non-hovered volumes
|
||||||
|
@ -814,9 +817,9 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
||||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||||
shader->set_uniform("print_volume.z_data", m_print_volume.zs);
|
shader->set_uniform("print_volume.z_data", m_print_volume.zs);
|
||||||
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
|
shader->set_uniform("volume_world_matrix", world_matrix);
|
||||||
shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower);
|
shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower);
|
||||||
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
|
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(world_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
|
||||||
shader->set_uniform("slope.normal_z", m_slope.normal_z);
|
shader->set_uniform("slope.normal_z", m_slope.normal_z);
|
||||||
|
|
||||||
#if ENABLE_ENVIRONMENT_MAP
|
#if ENABLE_ENVIRONMENT_MAP
|
||||||
|
@ -829,7 +832,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
glcheck();
|
glcheck();
|
||||||
|
|
||||||
volume.first->model.set_color(volume.first->render_color);
|
volume.first->model.set_color(volume.first->render_color);
|
||||||
const Transform3d model_matrix = volume.first->world_matrix();
|
const Transform3d model_matrix = world_matrix;
|
||||||
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
|
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
|
||||||
shader->set_uniform("projection_matrix", projection_matrix);
|
shader->set_uniform("projection_matrix", projection_matrix);
|
||||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||||
|
|
|
@ -116,9 +116,30 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto style = config->opt_enum<SupportMaterialStyle>("support_material_style");
|
||||||
|
|
||||||
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
||||||
config->opt_float("support_material_contact_distance") > 0. &&
|
// Organic supports are always synchronized with object layers as of now.
|
||||||
(config->opt_int("support_material_extruder") != 0 || config->opt_int("support_material_interface_extruder") != 0)) {
|
config->opt_enum<SupportMaterialStyle>("support_material_style") != smsOrganic) {
|
||||||
|
if (config->opt_float("support_material_contact_distance") == 0) {
|
||||||
|
if (!config->opt_bool("support_material_synchronize_layers")) {
|
||||||
|
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
"need to be synchronized with the object layers."));
|
||||||
|
if (is_global_config)
|
||||||
|
msg_text += "\n\n" + _(L("Shall I synchronize support layers in order to enable the Wipe Tower?"));
|
||||||
|
MessageDialog dialog(m_msg_dlg_parent, msg_text, _(L("Wipe Tower")),
|
||||||
|
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
||||||
|
DynamicPrintConfig new_conf = *config;
|
||||||
|
auto answer = dialog.ShowModal();
|
||||||
|
if (!is_global_config || answer == wxID_YES) {
|
||||||
|
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||||
|
apply(config, &new_conf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((config->opt_int("support_material_extruder") != 0 || config->opt_int("support_material_interface_extruder") != 0)) {
|
||||||
wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n"
|
wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n"
|
||||||
"if they are printed with the current extruder without triggering a tool change.\n"
|
"if they are printed with the current extruder without triggering a tool change.\n"
|
||||||
"(both support_material_extruder and support_material_interface_extruder need to be set to 0)."));
|
"(both support_material_extruder and support_material_interface_extruder need to be set to 0)."));
|
||||||
|
@ -136,24 +157,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||||
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||||
apply(config, &new_conf);
|
apply(config, &new_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
|
||||||
config->opt_float("support_material_contact_distance") == 0 &&
|
|
||||||
!config->opt_bool("support_material_synchronize_layers")) {
|
|
||||||
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
|
|
||||||
"need to be synchronized with the object layers."));
|
|
||||||
if (is_global_config)
|
|
||||||
msg_text += "\n\n" + _(L("Shall I synchronize support layers in order to enable the Wipe Tower?"));
|
|
||||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, _(L("Wipe Tower")),
|
|
||||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
|
|
||||||
DynamicPrintConfig new_conf = *config;
|
|
||||||
auto answer = dialog.ShowModal();
|
|
||||||
if (!is_global_config || answer == wxID_YES) {
|
|
||||||
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
|
||||||
apply(config, &new_conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check "support_material" and "overhangs" relations only on global settings level
|
// Check "support_material" and "overhangs" relations only on global settings level
|
||||||
|
@ -183,18 +187,14 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->option<ConfigOptionPercent>("fill_density")->value == 100) {
|
if (config->option<ConfigOptionPercent>("fill_density")->value == 100) {
|
||||||
std::string fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->serialize();
|
const int fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->value;
|
||||||
const auto &top_fill_pattern_values = config->def()->get("top_fill_pattern")->enum_values;
|
if (bool correct_100p_fill = config->option_def("top_fill_pattern")->enum_def->enum_to_index(fill_pattern).has_value();
|
||||||
bool correct_100p_fill = std::find(top_fill_pattern_values.begin(), top_fill_pattern_values.end(), fill_pattern) != top_fill_pattern_values.end();
|
! correct_100p_fill) {
|
||||||
if (!correct_100p_fill) {
|
|
||||||
// get fill_pattern name from enum_labels for using this one at dialog_msg
|
// get fill_pattern name from enum_labels for using this one at dialog_msg
|
||||||
const ConfigOptionDef *fill_pattern_def = config->def()->get("fill_pattern");
|
const ConfigOptionDef *fill_pattern_def = config->option_def("fill_pattern");
|
||||||
assert(fill_pattern_def != nullptr);
|
assert(fill_pattern_def != nullptr);
|
||||||
auto it_pattern = std::find(fill_pattern_def->enum_values.begin(), fill_pattern_def->enum_values.end(), fill_pattern);
|
if (auto label = fill_pattern_def->enum_def->enum_to_label(fill_pattern); label.has_value()) {
|
||||||
assert(it_pattern != fill_pattern_def->enum_values.end());
|
wxString msg_text = GUI::format_wxstr(_L("The %1% infill pattern is not supposed to work at 100%% density."), _(*label));
|
||||||
if (it_pattern != fill_pattern_def->enum_values.end()) {
|
|
||||||
wxString msg_text = GUI::format_wxstr(_L("The %1% infill pattern is not supposed to work at 100%% density."),
|
|
||||||
_(fill_pattern_def->enum_labels[it_pattern - fill_pattern_def->enum_values.begin()]));
|
|
||||||
if (is_global_config)
|
if (is_global_config)
|
||||||
msg_text += "\n\n" + _L("Shall I switch to rectilinear fill pattern?");
|
msg_text += "\n\n" + _L("Shall I switch to rectilinear fill pattern?");
|
||||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, _L("Infill"),
|
MessageDialog dialog(m_msg_dlg_parent, msg_text, _L("Infill"),
|
||||||
|
|
|
@ -1132,13 +1132,12 @@ void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool mat
|
||||||
if (material_type_ordering) {
|
if (material_type_ordering) {
|
||||||
|
|
||||||
const ConfigOptionDef* def = print_config_def.get("filament_type");
|
const ConfigOptionDef* def = print_config_def.get("filament_type");
|
||||||
std::vector<std::string>enum_values = def->enum_values;
|
|
||||||
size_t end_of_sorted = 0;
|
size_t end_of_sorted = 0;
|
||||||
for (size_t vals = 0; vals < enum_values.size(); vals++) {
|
for (const std::string &value : def->enum_def->values()) {
|
||||||
for (size_t profs = end_of_sorted; profs < other_profiles.size(); profs++)
|
for (size_t profs = end_of_sorted; profs < other_profiles.size(); profs++)
|
||||||
{
|
{
|
||||||
// find instead compare because PET vs PETG
|
// find instead compare because PET vs PETG
|
||||||
if (other_profiles[profs].get().find(enum_values[vals]) != std::string::npos) {
|
if (other_profiles[profs].get().find(value) != std::string::npos) {
|
||||||
//swap
|
//swap
|
||||||
if(profs != end_of_sorted) {
|
if(profs != end_of_sorted) {
|
||||||
std::reference_wrapper<const std::string> aux = other_profiles[end_of_sorted];
|
std::reference_wrapper<const std::string> aux = other_profiles[end_of_sorted];
|
||||||
|
@ -1660,14 +1659,14 @@ PageFirmware::PageFirmware(ConfigWizard *parent)
|
||||||
append_text(_(gcode_opt.tooltip));
|
append_text(_(gcode_opt.tooltip));
|
||||||
|
|
||||||
wxArrayString choices;
|
wxArrayString choices;
|
||||||
choices.Alloc(gcode_opt.enum_labels.size());
|
choices.Alloc(gcode_opt.enum_def->labels().size());
|
||||||
for (const auto &label : gcode_opt.enum_labels) {
|
for (const auto &label : gcode_opt.enum_def->labels()) {
|
||||||
choices.Add(label);
|
choices.Add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
||||||
wxGetApp().UpdateDarkUI(gcode_picker);
|
wxGetApp().UpdateDarkUI(gcode_picker);
|
||||||
const auto &enum_values = gcode_opt.enum_values;
|
const auto &enum_values = gcode_opt.enum_def->values();
|
||||||
auto needle = enum_values.cend();
|
auto needle = enum_values.cend();
|
||||||
if (gcode_opt.default_value) {
|
if (gcode_opt.default_value) {
|
||||||
needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
|
needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
|
||||||
|
@ -1684,7 +1683,7 @@ PageFirmware::PageFirmware(ConfigWizard *parent)
|
||||||
void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
|
void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
|
||||||
{
|
{
|
||||||
auto sel = gcode_picker->GetSelection();
|
auto sel = gcode_picker->GetSelection();
|
||||||
if (sel >= 0 && (size_t)sel < gcode_opt.enum_labels.size()) {
|
if (sel >= 0 && (size_t)sel < gcode_opt.enum_def->labels().size()) {
|
||||||
auto *opt = new ConfigOptionEnum<GCodeFlavor>(static_cast<GCodeFlavor>(sel));
|
auto *opt = new ConfigOptionEnum<GCodeFlavor>(static_cast<GCodeFlavor>(sel));
|
||||||
config.set_key_value("gcode_flavor", opt);
|
config.set_key_value("gcode_flavor", opt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -598,6 +598,10 @@ bool TextCtrl::value_was_changed()
|
||||||
|
|
||||||
void TextCtrl::propagate_value()
|
void TextCtrl::propagate_value()
|
||||||
{
|
{
|
||||||
|
wxString val = dynamic_cast<wxTextCtrl*>(window)->GetValue();
|
||||||
|
if (m_opt.nullable && val != na_value())
|
||||||
|
m_last_meaningful_value = val;
|
||||||
|
|
||||||
if (!is_defined_input_value<wxTextCtrl>(window, m_opt.type) )
|
if (!is_defined_input_value<wxTextCtrl>(window, m_opt.type) )
|
||||||
// on_kill_focus() cause a call of OptionsGroup::reload_config(),
|
// on_kill_focus() cause a call of OptionsGroup::reload_config(),
|
||||||
// Thus, do it only when it's really needed (when undefined value was input)
|
// Thus, do it only when it's really needed (when undefined value was input)
|
||||||
|
@ -778,8 +782,12 @@ void SpinCtrl::BUILD() {
|
||||||
case coInts:
|
case coInts:
|
||||||
{
|
{
|
||||||
default_value = m_opt.get_default_value<ConfigOptionInts>()->get_at(m_opt_idx);
|
default_value = m_opt.get_default_value<ConfigOptionInts>()->get_at(m_opt_idx);
|
||||||
if (m_opt.nullable)
|
if (m_opt.nullable) {
|
||||||
m_last_meaningful_value = default_value == ConfigOptionIntsNullable::nil_value() ? static_cast<int>(m_opt.max) : default_value;
|
if (default_value == ConfigOptionIntsNullable::nil_value())
|
||||||
|
m_last_meaningful_value = m_opt.opt_key == "idle_temperature" ? 30 : static_cast<int>(m_opt.max);
|
||||||
|
else
|
||||||
|
m_last_meaningful_value = default_value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -937,6 +945,9 @@ void SpinCtrl::propagate_value()
|
||||||
if (boost::any_cast<int>(m_value) == tmp_value)
|
if (boost::any_cast<int>(m_value) == tmp_value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (m_opt.nullable && tmp_value != ConfigOptionIntsNullable::nil_value())
|
||||||
|
m_last_meaningful_value = tmp_value;
|
||||||
|
|
||||||
if (tmp_value == UNDEF_VALUE) {
|
if (tmp_value == UNDEF_VALUE) {
|
||||||
on_kill_focus();
|
on_kill_focus();
|
||||||
} else {
|
} else {
|
||||||
|
@ -980,7 +991,9 @@ void Choice::BUILD() {
|
||||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
|
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
|
||||||
|
|
||||||
choice_ctrl* temp;
|
choice_ctrl* temp;
|
||||||
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open) {
|
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined
|
||||||
|
&& m_opt.gui_type != ConfigOptionDef::GUIType::select_open
|
||||||
|
&& m_opt.gui_type != ConfigOptionDef::GUIType::select_close) {
|
||||||
m_is_editable = true;
|
m_is_editable = true;
|
||||||
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
|
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
|
||||||
}
|
}
|
||||||
|
@ -1010,18 +1023,14 @@ void Choice::BUILD() {
|
||||||
// recast as a wxWindow to fit the calling convention
|
// recast as a wxWindow to fit the calling convention
|
||||||
window = dynamic_cast<wxWindow*>(temp);
|
window = dynamic_cast<wxWindow*>(temp);
|
||||||
|
|
||||||
if (! m_opt.enum_labels.empty() || ! m_opt.enum_values.empty()) {
|
if (m_opt.enum_def) {
|
||||||
if (m_opt.enum_labels.empty()) {
|
if (auto& labels = m_opt.enum_def->labels(); !labels.empty()) {
|
||||||
// Append non-localized enum_values
|
bool localized = m_opt.enum_def->has_labels();
|
||||||
for (auto el : m_opt.enum_values)
|
for (const std::string& el : labels)
|
||||||
temp->Append(el);
|
temp->Append(localized ? _(from_u8(el)) : from_u8(el));
|
||||||
} else {
|
|
||||||
// Append localized enum_labels
|
|
||||||
for (auto el : m_opt.enum_labels)
|
|
||||||
temp->Append(_(el));
|
|
||||||
}
|
|
||||||
set_selection();
|
set_selection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) {
|
temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) {
|
||||||
if (m_suppress_scroll && !m_is_dropped)
|
if (m_suppress_scroll && !m_is_dropped)
|
||||||
|
@ -1130,33 +1139,23 @@ void Choice::set_selection()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!text_value.IsEmpty()) {
|
if (!text_value.IsEmpty()) {
|
||||||
size_t idx = 0;
|
if (auto opt = m_opt.enum_def->value_to_index(into_u8(text_value)); opt.has_value())
|
||||||
for (auto el : m_opt.enum_values) {
|
// This enum has a value field of the same content as text_value. Select it.
|
||||||
if (el == text_value)
|
field->SetSelection(*opt);
|
||||||
break;
|
else
|
||||||
++idx;
|
field->SetValue(text_value);
|
||||||
}
|
|
||||||
idx == m_opt.enum_values.size() ? field->SetValue(text_value) : field->SetSelection(idx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Choice::set_value(const std::string& value, bool change_event) //! Redundant?
|
void Choice::set_value(const std::string& value, bool change_event) //! Redundant?
|
||||||
{
|
{
|
||||||
m_disable_change_event = !change_event;
|
m_disable_change_event = !change_event;
|
||||||
|
|
||||||
size_t idx=0;
|
|
||||||
for (auto el : m_opt.enum_values)
|
|
||||||
{
|
|
||||||
if (el == value)
|
|
||||||
break;
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
|
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
|
||||||
idx == m_opt.enum_values.size() ?
|
if (auto opt = m_opt.enum_def->value_to_index(value); opt.has_value())
|
||||||
field->SetValue(value) :
|
// This enum has a value field of the same content as text_value. Select it.
|
||||||
field->SetSelection(idx);
|
field->SetSelection(*opt);
|
||||||
|
else
|
||||||
|
field->SetValue(value);
|
||||||
m_disable_change_event = false;
|
m_disable_change_event = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,27 +1172,25 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
||||||
case coFloatOrPercent:
|
case coFloatOrPercent:
|
||||||
case coString:
|
case coString:
|
||||||
case coStrings: {
|
case coStrings: {
|
||||||
wxString text_value;
|
wxString text_value = m_opt.type == coInt ?
|
||||||
if (m_opt.type == coInt)
|
wxString::Format(_T("%i"), int(boost::any_cast<int>(value))) :
|
||||||
text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value)));
|
boost::any_cast<wxString>(value);
|
||||||
else
|
int sel_idx = -1;
|
||||||
text_value = boost::any_cast<wxString>(value);
|
if (m_opt.enum_def) {
|
||||||
size_t idx = 0;
|
if (auto idx = m_opt.enum_def->label_to_index(into_u8(text_value)); idx.has_value())
|
||||||
const std::vector<std::string>& enums = m_opt.enum_values.empty() ? m_opt.enum_labels : m_opt.enum_values;
|
sel_idx = *idx;
|
||||||
for (auto el : enums)
|
else if (idx = m_opt.enum_def->value_to_index(into_u8(text_value)); idx.has_value())
|
||||||
{
|
sel_idx = *idx;
|
||||||
if (el == text_value)
|
|
||||||
break;
|
|
||||||
++idx;
|
|
||||||
}
|
}
|
||||||
if (idx == enums.size()) {
|
|
||||||
|
if (sel_idx >= 0 )
|
||||||
|
field->SetSelection(sel_idx);
|
||||||
|
else {
|
||||||
// For editable Combobox under OSX is needed to set selection to -1 explicitly,
|
// For editable Combobox under OSX is needed to set selection to -1 explicitly,
|
||||||
// otherwise selection doesn't be changed
|
// otherwise selection doesn't be changed
|
||||||
field->SetSelection(-1);
|
field->SetSelection(-1);
|
||||||
field->SetValue(text_value);
|
field->SetValue(text_value);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
field->SetSelection(idx);
|
|
||||||
|
|
||||||
if (!m_value.empty() && m_opt.opt_key == "fill_density") {
|
if (!m_value.empty() && m_opt.opt_key == "fill_density") {
|
||||||
// If m_value was changed before, then update m_value here too to avoid case
|
// If m_value was changed before, then update m_value here too to avoid case
|
||||||
|
@ -1206,36 +1203,9 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case coEnum: {
|
case coEnum: {
|
||||||
int val = boost::any_cast<int>(value);
|
auto val = m_opt.enum_def->enum_to_index(boost::any_cast<int>(value));
|
||||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern")
|
assert(val.has_value());
|
||||||
{
|
field->SetSelection(val.has_value() ? *val : 0);
|
||||||
std::string key;
|
|
||||||
const t_config_enum_values& map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
|
|
||||||
for (auto it : map_names)
|
|
||||||
if (val == it.second) {
|
|
||||||
key = it.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& values = m_opt.enum_values;
|
|
||||||
auto it = std::find(values.begin(), values.end(), key);
|
|
||||||
val = it == values.end() ? 0 : it - values.begin();
|
|
||||||
}
|
|
||||||
else if (m_opt_id == "support_material_style")
|
|
||||||
{
|
|
||||||
std::string key;
|
|
||||||
const t_config_enum_values& map_names = ConfigOptionEnum<SupportMaterialStyle>::get_enum_values();
|
|
||||||
for (auto it : map_names)
|
|
||||||
if (val == it.second) {
|
|
||||||
key = it.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& values = m_opt.enum_values;
|
|
||||||
auto it = std::find(values.begin(), values.end(), key);
|
|
||||||
val = it == values.end() ? 0 : it - values.begin();
|
|
||||||
}
|
|
||||||
field->SetSelection(val);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -1298,28 +1268,21 @@ boost::any& Choice::get_value()
|
||||||
return m_value = boost::any(ret_str);
|
return m_value = boost::any(ret_str);
|
||||||
|
|
||||||
if (m_opt.type == coEnum)
|
if (m_opt.type == coEnum)
|
||||||
{
|
// Closed enum: The combo box item index returned by the field must be convertible to an enum value.
|
||||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern") {
|
m_value = m_opt.enum_def->index_to_enum(field->GetSelection());
|
||||||
const std::string& key = m_opt.enum_values[field->GetSelection()];
|
|
||||||
m_value = int(ConfigOptionEnum<InfillPattern>::get_enum_values().at(key));
|
|
||||||
} else if (m_opt_id == "support_material_style") {
|
|
||||||
m_value = int(ConfigOptionEnum<SupportMaterialStyle>::get_enum_values().at(m_opt.enum_values[field->GetSelection()]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_value = field->GetSelection();
|
|
||||||
}
|
|
||||||
else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) {
|
else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) {
|
||||||
|
// Open enum: The combo box item index returned by the field
|
||||||
const int ret_enum = field->GetSelection();
|
const int ret_enum = field->GetSelection();
|
||||||
if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings ||
|
if (ret_enum < 0 || ! m_opt.enum_def->has_values() || m_opt.type == coStrings ||
|
||||||
(ret_str != m_opt.enum_values[ret_enum] && ret_str != _(m_opt.enum_labels[ret_enum])))
|
(into_u8(ret_str) != m_opt.enum_def->value(ret_enum) && ret_str != _(m_opt.enum_def->label(ret_enum))))
|
||||||
// modifies ret_string!
|
// modifies ret_string!
|
||||||
get_value_by_opt_type(ret_str);
|
get_value_by_opt_type(ret_str);
|
||||||
else if (m_opt.type == coFloatOrPercent)
|
else if (m_opt.type == coFloatOrPercent)
|
||||||
m_value = m_opt.enum_values[ret_enum];
|
m_value = m_opt.enum_def->value(ret_enum);
|
||||||
else if (m_opt.type == coInt)
|
else if (m_opt.type == coInt)
|
||||||
m_value = atoi(m_opt.enum_values[ret_enum].c_str());
|
m_value = atoi(m_opt.enum_def->value(ret_enum).c_str());
|
||||||
else
|
else
|
||||||
m_value = string_to_double_decimal_point(m_opt.enum_values[ret_enum]);
|
m_value = string_to_double_decimal_point(m_opt.enum_def->value(ret_enum));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// modifies ret_string!
|
// modifies ret_string!
|
||||||
|
@ -1354,22 +1317,19 @@ void Choice::msw_rescale()
|
||||||
// Set rescaled size
|
// Set rescaled size
|
||||||
field->SetSize(size);
|
field->SetSize(size);
|
||||||
|
|
||||||
size_t idx = 0;
|
if (m_opt.enum_def) {
|
||||||
if (! m_opt.enum_labels.empty() || ! m_opt.enum_values.empty()) {
|
if (auto& labels = m_opt.enum_def->labels(); !labels.empty()) {
|
||||||
size_t counter = 0;
|
const bool localized = m_opt.enum_def->has_labels();
|
||||||
bool labels = ! m_opt.enum_labels.empty();
|
for (const std::string& el : labels)
|
||||||
for (const std::string &el : labels ? m_opt.enum_labels : m_opt.enum_values) {
|
field->Append(localized ? _(from_u8(el)) : from_u8(el));
|
||||||
wxString text = labels ? _(el) : from_u8(el);
|
|
||||||
field->Append(text);
|
|
||||||
if (text == selection)
|
|
||||||
idx = counter;
|
|
||||||
++ counter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idx == m_opt.enum_values.size() ?
|
if (auto opt = m_opt.enum_def->label_to_index(into_u8(selection)); opt.has_value())
|
||||||
field->SetValue(selection) :
|
// This enum has a value field of the same content as text_value. Select it.
|
||||||
field->SetSelection(idx);
|
field->SetSelection(*opt);
|
||||||
|
else
|
||||||
|
field->SetValue(selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
field->Rescale();
|
field->Rescale();
|
||||||
|
|
|
@ -818,9 +818,12 @@ static float get_cursor_height()
|
||||||
void GLCanvas3D::Tooltip::set_text(const std::string& text)
|
void GLCanvas3D::Tooltip::set_text(const std::string& text)
|
||||||
{
|
{
|
||||||
// If the mouse is inside an ImGUI dialog, then the tooltip is suppressed.
|
// If the mouse is inside an ImGUI dialog, then the tooltip is suppressed.
|
||||||
m_text = m_in_imgui ? std::string() : text;
|
const std::string& new_text = m_in_imgui ? std::string() : text;
|
||||||
|
if (m_text != new_text) { // To avoid calling the expensive call to get_cursor_height.
|
||||||
|
m_text = new_text;
|
||||||
m_cursor_height = get_cursor_height();
|
m_cursor_height = get_cursor_height();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas)
|
void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
|
|
|
@ -280,34 +280,11 @@ static void add_config_substitutions(const ConfigSubstitutions& conf_substitutio
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case coEnum:
|
case coEnum:
|
||||||
{
|
{
|
||||||
const std::vector<std::string>& labels = def->enum_labels;
|
auto opt = def->enum_def->enum_to_index(conf_substitution.new_value->getInt());
|
||||||
const std::vector<std::string>& values = def->enum_values;
|
new_val = opt.has_value() ?
|
||||||
int val = conf_substitution.new_value->getInt();
|
wxString("\"") + def->enum_def->value(*opt) + "\"" + " (" +
|
||||||
|
_(from_u8(def->enum_def->label(*opt))) + ")" :
|
||||||
bool is_infill = def->opt_key == "top_fill_pattern" ||
|
_L("Undefined");
|
||||||
def->opt_key == "bottom_fill_pattern" ||
|
|
||||||
def->opt_key == "fill_pattern" ||
|
|
||||||
def->opt_key == "support_material_style";
|
|
||||||
|
|
||||||
// Each infill doesn't use all list of infill declared in PrintConfig.hpp.
|
|
||||||
// So we should "convert" val to the correct one
|
|
||||||
if (is_infill) {
|
|
||||||
for (const auto& key_val : *def->enum_keys_map)
|
|
||||||
if ((int)key_val.second == val) {
|
|
||||||
auto it = std::find(values.begin(), values.end(), key_val.first);
|
|
||||||
if (it == values.end())
|
|
||||||
break;
|
|
||||||
auto idx = it - values.begin();
|
|
||||||
new_val = wxString("\"") + values[idx] + "\"" + " (" + from_u8(_utf8(labels[idx])) + ")";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (new_val.IsEmpty()) {
|
|
||||||
assert(false);
|
|
||||||
new_val = _L("Undefined");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
new_val = wxString("\"") + values[val] + "\"" + " (" + from_u8(_utf8(labels[val])) + ")";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case coBool:
|
case coBool:
|
||||||
|
|
|
@ -656,7 +656,7 @@ void GLGizmoCut3D::render_cut_plane()
|
||||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
|
|
||||||
if (can_perform_cut())
|
if (can_perform_cut() && has_valid_contour())
|
||||||
// m_plane.set_color({ 0.8f, 0.8f, 0.8f, 0.5f });
|
// m_plane.set_color({ 0.8f, 0.8f, 0.8f, 0.5f });
|
||||||
m_plane.set_color({ 0.9f, 0.9f, 0.9f, 0.5f });
|
m_plane.set_color({ 0.9f, 0.9f, 0.9f, 0.5f });
|
||||||
else
|
else
|
||||||
|
@ -669,9 +669,19 @@ void GLGizmoCut3D::render_cut_plane()
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
|
|
||||||
static float get_grabber_mean_size(const BoundingBoxf3& bb)
|
static double get_grabber_mean_size(const BoundingBoxf3& bb)
|
||||||
{
|
{
|
||||||
return float((bb.size().x() + bb.size().y() + bb.size().z()) / 3.0);
|
return (bb.size().x() + bb.size().y() + bb.size().z()) / 30.;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double get_half_size(double size)
|
||||||
|
{
|
||||||
|
return std::max(size * 0.35, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double get_dragging_half_size(double size)
|
||||||
|
{
|
||||||
|
return get_half_size(size) * 1.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::render_model(GLModel& model, const ColorRGBA& color, Transform3d view_model_matrix)
|
void GLGizmoCut3D::render_model(GLModel& model, const ColorRGBA& color, Transform3d view_model_matrix)
|
||||||
|
@ -754,10 +764,9 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
||||||
|
|
||||||
const Transform3d view_matrix = wxGetApp().plater()->get_camera().get_view_matrix() * translation_transform(m_plane_center) * m_rotation_m;
|
const Transform3d view_matrix = wxGetApp().plater()->get_camera().get_view_matrix() * translation_transform(m_plane_center) * m_rotation_m;
|
||||||
|
|
||||||
const Grabber& grabber = m_grabbers.front();
|
const double mean_size = get_grabber_mean_size(bounding_box());
|
||||||
const float mean_size = get_grabber_mean_size(bounding_box());
|
|
||||||
|
|
||||||
double size = m_dragging && m_hover_id == Z ? double(grabber.get_dragging_half_size(mean_size)) : double(grabber.get_half_size(mean_size));
|
double size = m_dragging && m_hover_id == Z ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||||
|
|
||||||
Vec3d cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
Vec3d cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||||
Vec3d offset = 1.25 * size * Vec3d::UnitZ();
|
Vec3d offset = 1.25 * size * Vec3d::UnitZ();
|
||||||
|
@ -782,7 +791,7 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
||||||
|
|
||||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == X || m_hover_id == Y)
|
if ((!m_dragging && m_hover_id < 0) || m_hover_id == X || m_hover_id == Y)
|
||||||
{
|
{
|
||||||
size = m_dragging ? double(grabber.get_dragging_half_size(mean_size)) : double(grabber.get_half_size(mean_size));
|
size = m_dragging ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||||
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) :
|
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) :
|
||||||
m_hover_id == X ? complementary(ColorRGBA::RED()) : ColorRGBA::GRAY();
|
m_hover_id == X ? complementary(ColorRGBA::RED()) : ColorRGBA::GRAY();
|
||||||
render_model(m_sphere.model, color, view_matrix * translation_transform(m_grabber_connection_len * Vec3d::UnitZ()) * scale_transform(size));
|
render_model(m_sphere.model, color, view_matrix * translation_transform(m_grabber_connection_len * Vec3d::UnitZ()) * scale_transform(size));
|
||||||
|
@ -792,7 +801,7 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
||||||
|
|
||||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == X)
|
if ((!m_dragging && m_hover_id < 0) || m_hover_id == X)
|
||||||
{
|
{
|
||||||
size = m_dragging && m_hover_id == X ? double(grabber.get_dragging_half_size(mean_size)) : double(grabber.get_half_size(mean_size));
|
size = m_dragging && m_hover_id == X ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||||
cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||||
color = m_hover_id == X ? complementary(ColorRGBA::RED()) : ColorRGBA::RED();
|
color = m_hover_id == X ? complementary(ColorRGBA::RED()) : ColorRGBA::RED();
|
||||||
|
|
||||||
|
@ -811,7 +820,7 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
||||||
|
|
||||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == Y)
|
if ((!m_dragging && m_hover_id < 0) || m_hover_id == Y)
|
||||||
{
|
{
|
||||||
size = m_dragging && m_hover_id == Y ? double(grabber.get_dragging_half_size(mean_size)) : double(grabber.get_half_size(mean_size));
|
size = m_dragging && m_hover_id == Y ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||||
cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||||
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) : ColorRGBA::GREEN();
|
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) : ColorRGBA::GREEN();
|
||||||
|
|
||||||
|
@ -1005,9 +1014,8 @@ void GLGizmoCut3D::update_raycasters_for_picking_transform()
|
||||||
const Transform3d trafo = translation_transform(m_plane_center) * m_rotation_m;
|
const Transform3d trafo = translation_transform(m_plane_center) * m_rotation_m;
|
||||||
|
|
||||||
const BoundingBoxf3 box = bounding_box();
|
const BoundingBoxf3 box = bounding_box();
|
||||||
const float mean_size = get_grabber_mean_size(box);
|
|
||||||
|
|
||||||
double size = double(m_grabbers.front().get_half_size(mean_size));
|
const double size = get_half_size(get_grabber_mean_size(box));
|
||||||
Vec3d scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
Vec3d scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||||
|
|
||||||
Vec3d offset = Vec3d(0.0, 1.25 * size, m_grabber_connection_len);
|
Vec3d offset = Vec3d(0.0, 1.25 * size, m_grabber_connection_len);
|
||||||
|
@ -1387,7 +1395,8 @@ void GLGizmoCut3D::init_rendering_items()
|
||||||
|
|
||||||
if (!m_plane.is_initialized() && !m_hide_cut_plane && !m_connectors_editing) {
|
if (!m_plane.is_initialized() && !m_hide_cut_plane && !m_connectors_editing) {
|
||||||
#if 1
|
#if 1
|
||||||
m_plane.init_from(its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, 0.3, m_cut_plane_as_circle ? 180 : 4));
|
const double cp_width = 0.02 * get_grabber_mean_size(bounding_box());
|
||||||
|
m_plane.init_from(its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, cp_width, m_cut_plane_as_circle ? 180 : 4));
|
||||||
#else
|
#else
|
||||||
if (m_cut_plane_as_circle)
|
if (m_cut_plane_as_circle)
|
||||||
m_plane.init_from(its_make_frustum_dowel(2. * m_radius, 0.3, 180));
|
m_plane.init_from(its_make_frustum_dowel(2. * m_radius, 0.3, 180));
|
||||||
|
@ -1825,6 +1834,8 @@ void GLGizmoCut3D::render_input_window_warning() const
|
||||||
}
|
}
|
||||||
if (!m_keep_upper && !m_keep_lower)
|
if (!m_keep_upper && !m_keep_lower)
|
||||||
m_imgui->text(wxString(ImGui::WarningMarkerSmall) + _L("Invalid state. \nNo one part is selected for keep after cut"));
|
m_imgui->text(wxString(ImGui::WarningMarkerSmall) + _L("Invalid state. \nNo one part is selected for keep after cut"));
|
||||||
|
if (!has_valid_contour())
|
||||||
|
m_imgui->text(wxString(ImGui::WarningMarkerSmall) + _L("Warning state. \nCut plane is placed out of object"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
||||||
|
@ -2029,6 +2040,11 @@ bool GLGizmoCut3D::can_perform_cut() const
|
||||||
if (m_has_invalid_connector || (!m_keep_upper && !m_keep_lower) || m_connectors_editing)
|
if (m_has_invalid_connector || (!m_keep_upper && !m_keep_lower) || m_connectors_editing)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
return true;// has_valid_contour();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLGizmoCut3D::has_valid_contour() const
|
||||||
|
{
|
||||||
const auto clipper = m_c->object_clipper();
|
const auto clipper = m_c->object_clipper();
|
||||||
return clipper && clipper->has_valid_contour();
|
return clipper && clipper->has_valid_contour();
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,6 +250,7 @@ private:
|
||||||
void render_connectors();
|
void render_connectors();
|
||||||
|
|
||||||
bool can_perform_cut() const;
|
bool can_perform_cut() const;
|
||||||
|
bool has_valid_contour() const;
|
||||||
void apply_connectors_in_model(ModelObject* mo, bool &create_dowels_as_separate_object);
|
void apply_connectors_in_model(ModelObject* mo, bool &create_dowels_as_separate_object);
|
||||||
bool cut_line_processing() const;
|
bool cut_line_processing() const;
|
||||||
void discard_cut_line_processing();
|
void discard_cut_line_processing();
|
||||||
|
|
|
@ -511,14 +511,14 @@ GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
|
||||||
|
|
||||||
for (const std::string& key : keys) {
|
for (const std::string& key : keys) {
|
||||||
if (object_cfg.has(key))
|
if (object_cfg.has(key))
|
||||||
out.emplace_back(object_cfg.option(key), &object_cfg.def()->options.at(key)); // at() needed for const map
|
out.emplace_back(object_cfg.option(key), object_cfg.option_def(key));
|
||||||
else
|
else
|
||||||
if (print_cfg.has(key))
|
if (print_cfg.has(key))
|
||||||
out.emplace_back(print_cfg.option(key), &print_cfg.def()->options.at(key));
|
out.emplace_back(print_cfg.option(key), print_cfg.option_def(key));
|
||||||
else { // we must get it from defaults
|
else { // we must get it from defaults
|
||||||
if (default_cfg == nullptr)
|
if (default_cfg == nullptr)
|
||||||
default_cfg.reset(DynamicPrintConfig::new_from_defaults_keys(keys));
|
default_cfg.reset(DynamicPrintConfig::new_from_defaults_keys(keys));
|
||||||
out.emplace_back(default_cfg->option(key), &default_cfg->def()->options.at(key));
|
out.emplace_back(default_cfg->option(key), default_cfg->option_def(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,16 +32,15 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
||||||
// Check the gui_type field first, fall through
|
// Check the gui_type field first, fall through
|
||||||
// is the normal type.
|
// is the normal type.
|
||||||
switch (opt.gui_type) {
|
switch (opt.gui_type) {
|
||||||
|
case ConfigOptionDef::GUIType::select_close:
|
||||||
case ConfigOptionDef::GUIType::select_open:
|
case ConfigOptionDef::GUIType::select_open:
|
||||||
|
case ConfigOptionDef::GUIType::f_enum_open:
|
||||||
|
case ConfigOptionDef::GUIType::i_enum_open:
|
||||||
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
|
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
|
||||||
break;
|
break;
|
||||||
case ConfigOptionDef::GUIType::color:
|
case ConfigOptionDef::GUIType::color:
|
||||||
m_fields.emplace(id, ColourPicker::Create<ColourPicker>(this->ctrl_parent(), opt, id));
|
m_fields.emplace(id, ColourPicker::Create<ColourPicker>(this->ctrl_parent(), opt, id));
|
||||||
break;
|
break;
|
||||||
case ConfigOptionDef::GUIType::f_enum_open:
|
|
||||||
case ConfigOptionDef::GUIType::i_enum_open:
|
|
||||||
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
|
|
||||||
break;
|
|
||||||
case ConfigOptionDef::GUIType::slider:
|
case ConfigOptionDef::GUIType::slider:
|
||||||
m_fields.emplace(id, SliderCtrl::Create<SliderCtrl>(this->ctrl_parent(), opt, id));
|
m_fields.emplace(id, SliderCtrl::Create<SliderCtrl>(this->ctrl_parent(), opt, id));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -613,32 +613,33 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change)
|
||||||
|
|
||||||
|
|
||||||
// Append localized enum_labels
|
// Append localized enum_labels
|
||||||
assert(ht->m_opt.enum_labels.size() == ht->m_opt.enum_values.size());
|
assert(ht->m_opt.enum_def->labels().size() == ht->m_opt.enum_def->values().size());
|
||||||
for (size_t i = 0; i < ht->m_opt.enum_labels.size(); i++) {
|
for (size_t i = 0; i < ht->m_opt.enum_def->labels().size(); ++ i) {
|
||||||
if (ht->m_opt.enum_values[i] == "prusalink"){
|
wxString label = _(ht->m_opt.enum_def->label(i));
|
||||||
link.label = _(ht->m_opt.enum_labels[i]);
|
if (const std::string &value = ht->m_opt.enum_def->value(i);
|
||||||
|
value == "prusalink") {
|
||||||
|
link.label = label;
|
||||||
if (!link.supported)
|
if (!link.supported)
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (value == "prusaconnect") {
|
||||||
if (ht->m_opt.enum_values[i] == "prusaconnect") {
|
connect.label = label;
|
||||||
connect.label = _(ht->m_opt.enum_labels[i]);
|
|
||||||
if (!connect.supported)
|
if (!connect.supported)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
types.Add(_(ht->m_opt.enum_labels[i]));
|
types.Add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
Choice* choice = dynamic_cast<Choice*>(ht);
|
Choice* choice = dynamic_cast<Choice*>(ht);
|
||||||
choice->set_values(types);
|
choice->set_values(types);
|
||||||
int index_in_choice = (printer_change ? 0 : last_in_conf);
|
int index_in_choice = (printer_change ? 0 : last_in_conf);
|
||||||
choice->set_value(index_in_choice);
|
choice->set_value(index_in_choice);
|
||||||
if (link.supported && link.label == _(ht->m_opt.enum_labels[index_in_choice]))
|
if (link.supported && link.label == _(ht->m_opt.enum_def->label(index_in_choice)))
|
||||||
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaLink));
|
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaLink));
|
||||||
else if (link.supported && link.label == _(ht->m_opt.enum_labels[index_in_choice]))
|
else if (link.supported && link.label == _(ht->m_opt.enum_def->label(index_in_choice)))
|
||||||
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnect));
|
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnect));
|
||||||
else {
|
else {
|
||||||
int host_type = std::clamp(index_in_choice + ((int)ht->m_opt.enum_values.size() - (int)types.size()), 0, (int)ht->m_opt.enum_values.size() - 1);
|
int host_type = std::clamp(index_in_choice + ((int)ht->m_opt.enum_def->values().size() - (int)types.size()), 0, (int)ht->m_opt.enum_def->values().size() - 1);
|
||||||
PrintHostType type = static_cast<PrintHostType>(host_type);
|
PrintHostType type = static_cast<PrintHostType>(host_type);
|
||||||
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(type));
|
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(type));
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,12 +433,13 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
|
||||||
ConfigOptionDef support_def;
|
ConfigOptionDef support_def;
|
||||||
support_def.label = L("Supports");
|
support_def.label = L("Supports");
|
||||||
support_def.type = coStrings;
|
support_def.type = coStrings;
|
||||||
support_def.gui_type = ConfigOptionDef::GUIType::select_open;
|
|
||||||
support_def.tooltip = L("Select what kind of support do you need");
|
support_def.tooltip = L("Select what kind of support do you need");
|
||||||
support_def.enum_labels.push_back(L("None"));
|
support_def.set_enum_labels(ConfigOptionDef::GUIType::select_open, {
|
||||||
support_def.enum_labels.push_back(L("Support on build plate only"));
|
L("None"),
|
||||||
support_def.enum_labels.push_back(L("For support enforcers only"));
|
L("Support on build plate only"),
|
||||||
support_def.enum_labels.push_back(L("Everywhere"));
|
L("For support enforcers only"),
|
||||||
|
L("Everywhere")
|
||||||
|
});
|
||||||
support_def.set_default_value(new ConfigOptionStrings{ "None" });
|
support_def.set_default_value(new ConfigOptionStrings{ "None" });
|
||||||
Option option = Option(support_def, "support");
|
Option option = Option(support_def, "support");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
|
@ -587,11 +588,12 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
|
||||||
ConfigOptionDef pad_def;
|
ConfigOptionDef pad_def;
|
||||||
pad_def.label = L("Pad");
|
pad_def.label = L("Pad");
|
||||||
pad_def.type = coStrings;
|
pad_def.type = coStrings;
|
||||||
pad_def.gui_type = ConfigOptionDef::GUIType::select_open;
|
|
||||||
pad_def.tooltip = L("Select what kind of pad do you need");
|
pad_def.tooltip = L("Select what kind of pad do you need");
|
||||||
pad_def.enum_labels.push_back(L("None"));
|
pad_def.set_enum_labels(ConfigOptionDef::GUIType::select_open, {
|
||||||
pad_def.enum_labels.push_back(L("Below object"));
|
L("None"),
|
||||||
pad_def.enum_labels.push_back(L("Around object"));
|
L("Below object"),
|
||||||
|
L("Around object")
|
||||||
|
});
|
||||||
pad_def.set_default_value(new ConfigOptionStrings{ "Below object" });
|
pad_def.set_default_value(new ConfigOptionStrings{ "Below object" });
|
||||||
option = Option(pad_def, "pad");
|
option = Option(pad_def, "pad");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
|
|
|
@ -165,23 +165,20 @@ static void append_bool_option( std::shared_ptr<ConfigOptionsGroup> optgroup,
|
||||||
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
|
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
static void append_enum_option( std::shared_ptr<ConfigOptionsGroup> optgroup,
|
static void append_enum_option( std::shared_ptr<ConfigOptionsGroup> optgroup,
|
||||||
const std::string& opt_key,
|
const std::string& opt_key,
|
||||||
const std::string& label,
|
const std::string& label,
|
||||||
const std::string& tooltip,
|
const std::string& tooltip,
|
||||||
const ConfigOption* def_val,
|
const ConfigOption* def_val,
|
||||||
const t_config_enum_values *enum_keys_map,
|
std::initializer_list<std::pair<std::string_view, std::string_view>> enum_values,
|
||||||
std::initializer_list<std::string> enum_values,
|
|
||||||
std::initializer_list<std::string> enum_labels,
|
|
||||||
ConfigOptionMode mode = comSimple)
|
ConfigOptionMode mode = comSimple)
|
||||||
{
|
{
|
||||||
ConfigOptionDef def = {opt_key, coEnum };
|
ConfigOptionDef def = {opt_key, coEnum };
|
||||||
def.label = label;
|
def.label = label;
|
||||||
def.tooltip = tooltip;
|
def.tooltip = tooltip;
|
||||||
def.mode = mode;
|
def.mode = mode;
|
||||||
def.enum_keys_map = enum_keys_map;
|
def.set_enum<EnumType>(enum_values);
|
||||||
def.enum_values = std::vector<std::string>(enum_values);
|
|
||||||
def.enum_labels = std::vector<std::string>(enum_labels);
|
|
||||||
|
|
||||||
def.set_default_value(def_val);
|
def.set_default_value(def_val);
|
||||||
Option option(def, opt_key);
|
Option option(def, opt_key);
|
||||||
|
@ -210,7 +207,7 @@ static void append_string_option(std::shared_ptr<ConfigOptionsGroup> optgroup,
|
||||||
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
|
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_preferences_option_to_searcer(std::shared_ptr<ConfigOptionsGroup> optgroup,
|
static void append_preferences_option_to_searcher(std::shared_ptr<ConfigOptionsGroup> optgroup,
|
||||||
const std::string& opt_key,
|
const std::string& opt_key,
|
||||||
const wxString& label)
|
const wxString& label)
|
||||||
{
|
{
|
||||||
|
@ -547,13 +544,14 @@ void PreferencesDialog::build()
|
||||||
L("If enabled, useful hints are displayed at startup."),
|
L("If enabled, useful hints are displayed at startup."),
|
||||||
app_config->get("show_hints") == "1");
|
app_config->get("show_hints") == "1");
|
||||||
|
|
||||||
append_enum_option(m_optgroup_gui, "notify_release",
|
append_enum_option<NotifyReleaseMode>(m_optgroup_gui, "notify_release",
|
||||||
L("Notify about new releases"),
|
L("Notify about new releases"),
|
||||||
L("You will be notified about new release after startup acordingly: All = Regular release and alpha / beta releases. Release only = regular release."),
|
L("You will be notified about new release after startup acordingly: All = Regular release and alpha / beta releases. Release only = regular release."),
|
||||||
new ConfigOptionEnum<NotifyReleaseMode>(static_cast<NotifyReleaseMode>(s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release")))),
|
new ConfigOptionEnum<NotifyReleaseMode>(static_cast<NotifyReleaseMode>(s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release")))),
|
||||||
&ConfigOptionEnum<NotifyReleaseMode>::get_enum_values(),
|
{ { "all", L("All") },
|
||||||
{"all", "release", "none"},
|
{ "release", L("Release only") },
|
||||||
{L("All"), L("Release only"), L("None")});
|
{ "none", L("None") }
|
||||||
|
});
|
||||||
|
|
||||||
m_optgroup_gui->append_separator();
|
m_optgroup_gui->append_separator();
|
||||||
|
|
||||||
|
@ -1026,7 +1024,7 @@ void PreferencesDialog::create_settings_mode_widget()
|
||||||
sizer->Add(stb_sizer, 1, wxALIGN_CENTER_VERTICAL);
|
sizer->Add(stb_sizer, 1, wxALIGN_CENTER_VERTICAL);
|
||||||
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
||||||
|
|
||||||
append_preferences_option_to_searcer(m_optgroup_gui, opt_key, title);
|
append_preferences_option_to_searcher(m_optgroup_gui, opt_key, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::create_settings_text_color_widget()
|
void PreferencesDialog::create_settings_text_color_widget()
|
||||||
|
@ -1050,7 +1048,7 @@ void PreferencesDialog::create_settings_text_color_widget()
|
||||||
|
|
||||||
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
||||||
|
|
||||||
append_preferences_option_to_searcer(m_optgroup_gui, opt_key, title);
|
append_preferences_option_to_searcher(m_optgroup_gui, opt_key, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::create_settings_mode_color_widget()
|
void PreferencesDialog::create_settings_mode_color_widget()
|
||||||
|
@ -1077,7 +1075,7 @@ void PreferencesDialog::create_settings_mode_color_widget()
|
||||||
|
|
||||||
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
||||||
|
|
||||||
append_preferences_option_to_searcer(m_optgroup_gui, opt_key, title);
|
append_preferences_option_to_searcher(m_optgroup_gui, opt_key, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::create_downloader_path_sizer()
|
void PreferencesDialog::create_downloader_path_sizer()
|
||||||
|
@ -1096,7 +1094,7 @@ void PreferencesDialog::create_downloader_path_sizer()
|
||||||
|
|
||||||
m_optgroup_other->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
m_optgroup_other->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
|
||||||
|
|
||||||
append_preferences_option_to_searcer(m_optgroup_other, opt_key, title);
|
append_preferences_option_to_searcher(m_optgroup_other, opt_key, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::init_highlighter(const t_config_option_key& opt_key)
|
void PreferencesDialog::init_highlighter(const t_config_option_key& opt_key)
|
||||||
|
|
|
@ -111,7 +111,7 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
|
||||||
|
|
||||||
for (std::string opt_key : config->keys())
|
for (std::string opt_key : config->keys())
|
||||||
{
|
{
|
||||||
const ConfigOptionDef& opt = config->def()->options.at(opt_key);
|
const ConfigOptionDef& opt = *config->option_def(opt_key);
|
||||||
if (opt.mode > mode)
|
if (opt.mode > mode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -1056,27 +1056,6 @@ bool UnsavedChangesDialog::save(PresetCollection* dependent_presets, bool show_s
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConfig& config, bool is_infill = false)
|
|
||||||
{
|
|
||||||
const ConfigOptionDef& def = config.def()->options.at(opt_key);
|
|
||||||
const std::vector<std::string>& names = def.enum_labels.empty() ? def.enum_values : def.enum_labels;
|
|
||||||
int val = config.option(opt_key)->getInt();
|
|
||||||
|
|
||||||
// Each infill doesn't use all list of infill declared in PrintConfig.hpp.
|
|
||||||
// So we should "convert" val to the correct one
|
|
||||||
if (is_infill) {
|
|
||||||
for (auto key_val : *def.enum_keys_map)
|
|
||||||
if (int(key_val.second) == val) {
|
|
||||||
auto it = std::find(def.enum_values.begin(), def.enum_values.end(), key_val.first);
|
|
||||||
if (it == def.enum_values.end())
|
|
||||||
return "";
|
|
||||||
return from_u8(_utf8(names[it - def.enum_values.begin()]));
|
|
||||||
}
|
|
||||||
return _L("Undef");
|
|
||||||
}
|
|
||||||
return from_u8(_utf8(names[val]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t get_id_from_opt_key(std::string opt_key)
|
static size_t get_id_from_opt_key(std::string opt_key)
|
||||||
{
|
{
|
||||||
int pos = opt_key.find("#");
|
int pos = opt_key.find("#");
|
||||||
|
@ -1214,11 +1193,8 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
case coEnum: {
|
case coEnum: {
|
||||||
return get_string_from_enum(opt_key, config,
|
auto opt = config.option_def(opt_key)->enum_def->enum_to_label(config.option(opt_key)->getInt());
|
||||||
opt_key == "top_fill_pattern" ||
|
return opt.has_value() ? _(from_u8(*opt)) : _L("Undef");
|
||||||
opt_key == "bottom_fill_pattern" ||
|
|
||||||
opt_key == "fill_pattern" ||
|
|
||||||
opt_key == "support_material_style");
|
|
||||||
}
|
}
|
||||||
case coPoints: {
|
case coPoints: {
|
||||||
if (opt_key == "bed_shape") {
|
if (opt_key == "bed_shape") {
|
||||||
|
|
|
@ -190,20 +190,20 @@ print_config_def()
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum_values
|
// enum_values
|
||||||
if (!optdef->enum_values.empty()) {
|
if (optdef->enum_def && !optdef->enum_def->values().empty()) {
|
||||||
AV* av = newAV();
|
AV* av = newAV();
|
||||||
av_fill(av, optdef->enum_values.size()-1);
|
av_fill(av, optdef->enum_def->values().size()-1);
|
||||||
for (std::vector<std::string>::iterator it = optdef->enum_values.begin(); it != optdef->enum_values.end(); ++it)
|
for (std::vector<std::string>::const_iterator it = optdef->enum_def->values().begin(); it != optdef->enum_def->values().end(); ++it)
|
||||||
av_store(av, it - optdef->enum_values.begin(), newSVpvn(it->c_str(), it->length()));
|
av_store(av, it - optdef->enum_def->values().begin(), newSVpvn(it->c_str(), it->length()));
|
||||||
(void)hv_stores( hv, "values", newRV_noinc((SV*)av) );
|
(void)hv_stores( hv, "values", newRV_noinc((SV*)av) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum_labels
|
// enum_labels
|
||||||
if (!optdef->enum_labels.empty()) {
|
if (optdef->enum_def && !optdef->enum_def->labels().empty()) {
|
||||||
AV* av = newAV();
|
AV* av = newAV();
|
||||||
av_fill(av, optdef->enum_labels.size()-1);
|
av_fill(av, optdef->enum_def->labels().size()-1);
|
||||||
for (std::vector<std::string>::iterator it = optdef->enum_labels.begin(); it != optdef->enum_labels.end(); ++it)
|
for (std::vector<std::string>::const_iterator it = optdef->enum_def->labels().begin(); it != optdef->enum_def->labels().end(); ++it)
|
||||||
av_store(av, it - optdef->enum_labels.begin(), newSVpvn_utf8(it->c_str(), it->length(), true));
|
av_store(av, it - optdef->enum_def->labels().begin(), newSVpvn_utf8(it->c_str(), it->length(), true));
|
||||||
(void)hv_stores( hv, "labels", newRV_noinc((SV*)av) );
|
(void)hv_stores( hv, "labels", newRV_noinc((SV*)av) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue