Merge branch 'master' into fs_emboss
@ -237,14 +237,14 @@ documentation_link = https://help.prusa3d.com/article/prusaslicer-printables-com
|
||||
weight = 3
|
||||
|
||||
[hint:Cut tool]
|
||||
text = Cut tool\nDid you know that you can cut a model at any angle and even create aligning pins with the updated Cut tool? Learn more in the documentation.
|
||||
text = Cut tool\nDid you know that you can cut a model at any angle and even create aligning pins with the updated <a>Cut tool</a>? Learn more in the documentation.
|
||||
documentation_link = https://help.prusa3d.com/article/cut-tool_1779
|
||||
hypertext_type = gizmo
|
||||
hypertext_gizmo_item = cut
|
||||
weight = 3
|
||||
|
||||
[hint:Measurement tool]
|
||||
text = Measurement tool\nDid you know that you can measure the distances between points, edges and planes, the radius of a hole or the angle between edges or planes? Learn more in the documentation.
|
||||
text = Measurement tool\nDid you know that you can <a>measure</a> the distances between points, edges and planes, the radius of a hole or the angle between edges or planes? Learn more in the documentation.
|
||||
documentation_link = https://help.prusa3d.com/article/measurement-tool_399451
|
||||
hypertext_type = gizmo
|
||||
hypertext_gizmo_item = measure
|
||||
|
15
resources/icons/dowel.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 27.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<g>
|
||||
<path fill = "#ED6B21" d="M9,12H7c-0.5522847,0-1-0.4477148-1-1V5c0-0.5522847,0.4477153-1,1-1h2c0.5522852,0,1,0.4477153,1,1v6
|
||||
C10,11.5522852,9.5522852,12,9,12z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="none" stroke="#808080" stroke-linecap="round" stroke-miterlimit="10" d="M1.5,6.5h2v-3c0-1.1045694,0.8954306-2,2-2h5c1.1045694,0,2,0.8954306,2,2v3h2"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="none" stroke="#808080" stroke-linecap="round" stroke-miterlimit="10" d="M1.5,9.5h2v3c0,1.1045694,0.8954306,2,2,2h5c1.1045694,0,2-0.8954306,2-2v-3h2"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 899 B |
13
resources/icons/plug.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 27.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#ED6B21" d="M9,15H7c-0.5522847,0-1-0.4477148-1-1V5c0-0.5522847,0.4477153-1,1-1h2c0.5522852,0,1,0.4477153,1,1v9
|
||||
C10,14.5522852,9.5522852,15,9,15z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="none" stroke="#808080" stroke-linecap="round" stroke-miterlimit="10" d="M1.5,11.5h2v-8c0-1.1045694,0.8954306-2,2-2h5c1.1045694,0,2,0.8954306,2,2v8h2"/>
|
||||
</g>
|
||||
<line fill="none" stroke="#ED6B21" stroke-linecap="round" stroke-miterlimit="10" x1="1.5" y1="14.5" x2="14.5" y2="14.5"/>
|
||||
</svg>
|
After Width: | Height: | Size: 847 B |
@ -2392,7 +2392,7 @@ msgstr "Zálohy konfigurace"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"Aktualizace konfigurace způsobí ztrátu změn v přednastaveních.\n"
|
||||
|
@ -2392,7 +2392,7 @@ msgstr "Konfigurations-Momentaufnahmen"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"Bei einer Konfigurationsaktualisierung gehen voreingestellte Änderungen "
|
||||
|
@ -2372,7 +2372,7 @@ msgstr "Instantáneas de la Configuración"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"La actualización de la configuración hace que se pierda la modificación de "
|
||||
|
@ -2399,7 +2399,7 @@ msgstr "Instantanés de Configuration capturés"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"Les mises à jour de configuration entraînent une perte de modification des "
|
||||
|
@ -2379,7 +2379,7 @@ msgstr "Istantanee di Configurazione"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"Gli aggiornamenti di configurazione causano la perdita della modifica del "
|
||||
|
@ -2338,7 +2338,7 @@ msgstr "設定のスナップショット"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"構成のアップデートをすると、プリセットの変更が失われます。\n"
|
||||
|
@ -2403,7 +2403,7 @@ msgstr "Zrzuty konfiguracji"
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:777
|
||||
msgid ""
|
||||
"Configuration Updates causes a lost of preset modification.\n"
|
||||
"Configuration Updates causes a loss of preset modification.\n"
|
||||
"So, check unsaved changes and save them if necessary."
|
||||
msgstr ""
|
||||
"Aktualizacja konfiguracji spowoduje utratę zmian w zestawach ustawień.\n"
|
||||
|
@ -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
|
||||
0.1.2 Added VOXELPLA filament profile.
|
||||
0.1.1 Fixed before layer change g-code for Mega Zero.
|
||||
0.1.0 Added Anycubic 4Max Pro 2.0
|
||||
min_slic3r_version = 2.3.2-alpha0
|
||||
|
@ -1,4 +1,6 @@
|
||||
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
|
||||
min_slic3r_version = 2.3.1-beta
|
||||
0.0.4 Fixed first layer height in 0.28mm profile.
|
||||
|
@ -12,7 +12,7 @@
|
||||
name = Artillery
|
||||
# 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.
|
||||
config_version = 0.0.5
|
||||
config_version = 0.0.7
|
||||
# Where to get the updates from?
|
||||
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%
|
||||
@ -89,7 +89,7 @@ remaining_times = 0
|
||||
retract_before_travel = 1
|
||||
retract_before_wipe = 0%
|
||||
retract_layer_change = 1
|
||||
retract_length = 1.9
|
||||
retract_length = 0.8
|
||||
retract_length_toolchange = 4
|
||||
retract_lift = 0.6
|
||||
retract_lift_above = 0
|
||||
@ -512,4 +512,65 @@ filament_vendor = Generic
|
||||
|
||||
[filament:Generic TPU @Artillery]
|
||||
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
|
||||
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.
|
||||
min_slic3r_version = 2.5.0-alpha0
|
||||
0.2.4 Add SPEED presets. More conservative extruder clearance.
|
||||
|
@ -5,7 +5,7 @@
|
||||
name = Creality
|
||||
# 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.
|
||||
config_version = 0.2.6
|
||||
config_version = 0.2.7
|
||||
# Where to get the updates from?
|
||||
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%
|
||||
@ -1510,7 +1510,66 @@ filament_cost = 28.99
|
||||
filament_density = 1.12
|
||||
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
|
||||
[printer:*common*]
|
||||
|
@ -1,5 +1,6 @@
|
||||
min_slic3r_version = 2.6.0-alpha1
|
||||
1.0.2 Added new printer models.
|
||||
min_slic3r_version = 2.5.0-alpha3
|
||||
1.0.1 Decreased bed size to 220x220.
|
||||
1.0.0 Initial version
|
||||
min_slic3r_version = 2.6.0-alpha1
|
||||
1.0.3 Added Eolas Prints filaments.
|
||||
1.0.2 Added new printer models.
|
||||
min_slic3r_version = 2.5.0-alpha3
|
||||
1.0.1 Decreased bed size to 220x220.
|
||||
1.0.0 Initial version
|
||||
|
2
resources/profiles/MakerGear.idx
Normal file
@ -0,0 +1,2 @@
|
||||
min_slic3r_version = 2.6.0-alpha1
|
||||
0.1.0 Initial version
|
1754
resources/profiles/MakerGear.ini
Normal file
BIN
resources/profiles/MakerGear/M2_M3.stl
Normal file
1
resources/profiles/MakerGear/M2_M3.svg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
resources/profiles/MakerGear/MAKERGEAR_M2_DUAL_thumbnail.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
resources/profiles/MakerGear/MAKERGEAR_M2_thumbnail.png
Normal file
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 32 KiB |
BIN
resources/profiles/MakerGear/MAKERGEAR_M3_SE_thumbnail.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
resources/profiles/MakerGear/MAKERGEAR_M3_thumbnail.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
resources/profiles/MakerGear/MAKERGEAR_MICRO_thumbnail.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
resources/profiles/MakerGear/MAKERGEAR_U1_thumbnail.png
Normal file
After Width: | Height: | Size: 46 KiB |
@ -1,6 +1,8 @@
|
||||
min_slic3r_version = 2.6.0-alpha1
|
||||
1.6.0-alpha1 Updated FW version notification. Decreased min layer time for PLA.
|
||||
1.6.0-alpha0 Default top fill set to monotonic lines. Updated infill/perimeter overlap values. Updated output filename format. Enabled dynamic overhang speeds.
|
||||
min_slic3r_version = 2.5.0-alpha0
|
||||
1.5.6 Updated FW version notification (MK2.5/MK3 family). Added filament profile for Kimya PEBA-S.
|
||||
1.5.5 Added new Prusament Resin material profiles. Enabled g-code thumbnails for MK2.5 family printers.
|
||||
1.5.4 Added material profiles for Prusament Resin BioBased60.
|
||||
1.5.3 Added filament profiles for ColorFabb VarioShore TPU, FormFutura PP, NinjaTek NinjaFlex/Cheetah TPU and for multiple Eolas Prints filaments. Updated bridging settings in 50um and 70um profiles.
|
||||
@ -10,6 +12,7 @@ min_slic3r_version = 2.5.0-alpha0
|
||||
1.5.0-alpha1 Added filament profile for Prusament PA11 Carbon Fiber. Added profiles for multiple 3D-Fuel filaments.
|
||||
1.5.0-alpha0 Added parameters for Arachne perimeter generator. Changed default seam position. Updated output filename format.
|
||||
min_slic3r_version = 2.4.0-rc
|
||||
1.4.9 Updated FW version notification.
|
||||
1.4.8 Added filament and SLA material profiles. Updated settings.
|
||||
1.4.7 Added filament profile for Prusament PA11 Carbon Fiber. Added profiles for multiple 3D-Fuel filaments.
|
||||
1.4.6 Added SLA materials. Updated filament profiles.
|
||||
@ -39,6 +42,7 @@ min_slic3r_version = 2.4.0-alpha0
|
||||
1.3.0-alpha1 Added Prusament PCCF. Increased travel acceleration for Prusa MINI. Updated start g-code for Prusa MINI. Added multiple add:north and Extrudr filament profiles. Updated Z travel speed values.
|
||||
1.3.0-alpha0 Disabled thick bridges, updated support settings.
|
||||
min_slic3r_version = 2.3.2-alpha0
|
||||
1.3.8 Updated FW version notification.
|
||||
1.3.7 Updated firmware version.
|
||||
1.3.6 Updated firmware version.
|
||||
1.3.5 Added material profiles for Prusament Resins.
|
||||
@ -48,6 +52,7 @@ min_slic3r_version = 2.3.2-alpha0
|
||||
1.3.1 Added multiple add:north and Extrudr filament profiles. Updated support head settings (SL1S).
|
||||
1.3.0 Added SL1S SPEED profiles.
|
||||
min_slic3r_version = 2.3.0-rc1
|
||||
1.2.13 Updated FW version notification.
|
||||
1.2.12 Updated firmware version.
|
||||
1.2.11 Updated firmware version.
|
||||
1.2.10 Added multiple profiles for Filatech filaments. Updated SLA print settings (pad wall slope angle).
|
||||
@ -69,6 +74,7 @@ min_slic3r_version = 2.3.0-alpha4
|
||||
1.2.0-alpha1 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
|
||||
1.2.0-alpha0 Added filament spool weights
|
||||
min_slic3r_version = 2.2.0-alpha3
|
||||
1.1.17 Updated FW version notification.
|
||||
1.1.16 Updated firmware version.
|
||||
1.1.15 Updated firmware version.
|
||||
1.1.14 Updated firmware version.
|
||||
@ -95,6 +101,7 @@ min_slic3r_version = 2.2.0-alpha0
|
||||
1.1.1-alpha2 Bumped up config version, so our in house customer will get updated profiles.
|
||||
1.1.0 Filament aliases, Creality profiles and other goodies for PrusaSlicer 2.2.0-alpha0
|
||||
min_slic3r_version = 2.1.1-beta0
|
||||
1.0.13 Updated FW version notification.
|
||||
1.0.12 Updated firmware version.
|
||||
1.0.11 Updated firmware version.
|
||||
1.0.10 Updated firmware version for MK2.5/S and MK3/S.
|
||||
|
@ -5,7 +5,7 @@
|
||||
name = Prusa Research
|
||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||
config_version = 1.6.0-alpha0
|
||||
config_version = 1.6.0-alpha1
|
||||
# Where to get the updates from?
|
||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
|
||||
changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||
@ -1589,6 +1589,7 @@ first_layer_temperature = 215
|
||||
max_fan_speed = 100
|
||||
min_fan_speed = 100
|
||||
temperature = 210
|
||||
slowdown_below_layer_time = 10
|
||||
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0"
|
||||
|
||||
[filament:*PET*]
|
||||
@ -9491,7 +9492,7 @@ inherits = Original Prusa i3 MK2S
|
||||
printer_model = MK2.5
|
||||
remaining_times = 1
|
||||
machine_max_jerk_e = 4.5
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y200 F3600 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
thumbnails = 160x120
|
||||
|
||||
@ -9500,7 +9501,7 @@ inherits = Original Prusa i3 MK2S 0.25 nozzle
|
||||
printer_model = MK2.5
|
||||
remaining_times = 1
|
||||
machine_max_jerk_e = 4.5
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\nG92 E0
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y200 F3600 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
thumbnails = 160x120
|
||||
|
||||
@ -9510,7 +9511,7 @@ printer_model = MK2.5
|
||||
remaining_times = 1
|
||||
machine_max_jerk_e = 4.5
|
||||
deretract_speed = 25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y200 F3600 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
thumbnails = 160x120
|
||||
|
||||
@ -9527,7 +9528,7 @@ deretract_speed = 20
|
||||
retract_lift = 0.25
|
||||
remaining_times = 1
|
||||
machine_max_jerk_e = 4.5
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y200 F3600 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
default_filament_profile = Prusament PLA @0.8 nozzle
|
||||
@ -9542,7 +9543,7 @@ max_print_height = 200
|
||||
default_print_profile = 0.15mm OPTIMAL @MK2.5
|
||||
default_filament_profile = Prusament PLA
|
||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2.5\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; load to nozzle\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.20 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; load to nozzle\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.20 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM104 S0 ; turn off temperature\nM900 K0 ; reset LA\nM84 ; disable motors
|
||||
|
||||
[printer:Original Prusa i3 MK2.5 MMU2 Single 0.8 nozzle]
|
||||
@ -9566,7 +9567,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
|
||||
single_extruder_multi_material = 1
|
||||
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
|
||||
extruder_colour = #FF8000;#DB5182;#3EC0FF;#FF4F4F;#FBEB7D
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E32 F1073\nG1 X5 E32 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\nG92 E0\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E32 F1073\nG1 X5 E32 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\nG92 E0\n
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\n{if has_wipe_tower}\nG1 E-15 F3000\n{else}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
[printer:Original Prusa i3 MK2.5S]
|
||||
@ -9593,7 +9594,7 @@ max_print_height = 200
|
||||
default_print_profile = 0.15mm OPTIMAL @MK2.5
|
||||
default_filament_profile = Prusament PLA
|
||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2.5\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM104 S0 ; turn off temperature\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
[printer:Original Prusa i3 MK2.5S MMU2S Single 0.8 nozzle]
|
||||
@ -9607,7 +9608,7 @@ retract_length = 0.7
|
||||
retract_speed = 35
|
||||
deretract_speed = 20
|
||||
retract_lift = 0.25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
default_filament_profile = Prusament PLA @0.8 nozzle
|
||||
color_change_gcode = M600\nG1 E0.6 F1500 ; prime after color change
|
||||
@ -9632,7 +9633,7 @@ nozzle_diameter = 0.25
|
||||
printer_variant = 0.25
|
||||
retract_lift = 0.15
|
||||
default_print_profile = 0.10mm DETAIL 0.25 nozzle
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F1400\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F1400\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n
|
||||
color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
|
||||
[printer:Original Prusa i3 MK2.5S MMU2S]
|
||||
@ -9644,7 +9645,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
|
||||
single_extruder_multi_material = 1
|
||||
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
|
||||
extruder_colour = #FF8000;#DB5182;#3EC0FF;#FF4F4F;#FBEB7D
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E29 F1073\nG1 X5 E29 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\nG92 E0\n
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E29 F1073\nG1 X5 E29 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\nG92 E0\n
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\n{if has_wipe_tower}\nG1 E-15 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
[printer:Original Prusa i3 MK2.5S MMU2S 0.6 nozzle]
|
||||
@ -9697,7 +9698,7 @@ color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
## printer_variant = 0.8
|
||||
## retract_length = 1
|
||||
## default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
|
||||
|
||||
## [printer:Original Prusa i3 MK2.5 MMU2 0.8 nozzle]
|
||||
## inherits = Original Prusa i3 MK2.5 MMU2
|
||||
@ -9707,7 +9708,7 @@ color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
## printer_variant = 0.8
|
||||
## retract_length = 1
|
||||
## default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n
|
||||
|
||||
# XXXXXXXXXXXXXXXXX
|
||||
# XXX--- MK3 ---XXX
|
||||
@ -9737,7 +9738,7 @@ remaining_times = 1
|
||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
|
||||
retract_lift_below = 209
|
||||
max_print_height = 210
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
printer_model = MK3
|
||||
default_print_profile = 0.15mm QUALITY @MK3
|
||||
thumbnails = 160x120
|
||||
@ -9749,7 +9750,7 @@ max_layer_height = 0.15
|
||||
min_layer_height = 0.05
|
||||
printer_variant = 0.25
|
||||
retract_lift = 0.15
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E8 F700 ; intro line\nG1 X100 E12.5 F700 ; intro line\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E8 F700 ; intro line\nG1 X100 E12.5 F700 ; intro line\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif}
|
||||
default_print_profile = 0.10mm DETAIL @0.25 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
|
||||
@ -9760,7 +9761,7 @@ max_layer_height = 0.40
|
||||
min_layer_height = 0.15
|
||||
printer_variant = 0.6
|
||||
deretract_speed = 25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}
|
||||
default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.5 F1500 ; prime after color change
|
||||
|
||||
@ -9774,7 +9775,7 @@ retract_length = 0.7
|
||||
retract_speed = 35
|
||||
deretract_speed = 20
|
||||
retract_lift = 0.25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0\nM221 S95
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n{if filament_settings_id[initial_tool]=~/.*Prusament PA11.*/}\nG1 Z0.3 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E9 F1000 ; intro line\n{else}\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\n{endif}\nG92 E0\nM221 S95
|
||||
default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
default_filament_profile = Prusament PLA @0.8 nozzle
|
||||
color_change_gcode = M600\nG1 E0.6 F1500 ; prime after color change
|
||||
@ -9846,7 +9847,7 @@ default_filament_profile = Prusament PLA @MMU2
|
||||
inherits = *mm2*
|
||||
single_extruder_multi_material = 0
|
||||
default_filament_profile = Prusament PLA
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
[printer:Original Prusa i3 MK3 MMU2 Single 0.6 nozzle]
|
||||
@ -9857,7 +9858,7 @@ max_layer_height = 0.40
|
||||
min_layer_height = 0.15
|
||||
printer_variant = 0.6
|
||||
deretract_speed = 25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.5 F1500 ; prime after color change
|
||||
|
||||
@ -9872,7 +9873,7 @@ retract_length = 0.7
|
||||
retract_speed = 35
|
||||
deretract_speed = 20
|
||||
retract_lift = 0.25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
default_filament_profile = Prusament PLA @0.8 nozzle
|
||||
color_change_gcode = M600\nG1 E0.6 F1500 ; prime after color change
|
||||
@ -9885,7 +9886,7 @@ max_layer_height = 0.15
|
||||
min_layer_height = 0.05
|
||||
printer_variant = 0.25
|
||||
retract_lift = 0.15
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F1000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F1400\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 E8 F1000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F1400\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif}
|
||||
default_print_profile = 0.10mm DETAIL @0.25 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
|
||||
@ -9894,7 +9895,7 @@ inherits = *mm2*
|
||||
machine_max_acceleration_e = 8000,8000
|
||||
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
|
||||
extruder_colour = #FF8000;#DB5182;#3EC0FF;#FF4F4F;#FBEB7D
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E32 F1073\nG1 X5 E32 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E32 F1073\nG1 X5 E32 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\n{if has_wipe_tower}\nG1 E-15 F3000\n{else}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
[printer:Original Prusa i3 MK3S & MK3S+ MMU2S Single]
|
||||
@ -9902,7 +9903,7 @@ inherits = *mm2s*
|
||||
renamed_from = "Original Prusa i3 MK3S MMU2S Single"
|
||||
single_extruder_multi_material = 0
|
||||
default_filament_profile = Prusament PLA
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
[printer:Original Prusa i3 MK3S & MK3S+ MMU2S Single 0.6 nozzle]
|
||||
@ -9914,7 +9915,7 @@ max_layer_height = 0.40
|
||||
min_layer_height = 0.15
|
||||
printer_variant = 0.6
|
||||
deretract_speed = 25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.5 F1500 ; prime after color change
|
||||
|
||||
@ -9929,7 +9930,7 @@ retract_length = 0.7
|
||||
retract_speed = 35
|
||||
deretract_speed = 20
|
||||
retract_lift = 0.25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
default_filament_profile = Prusament PLA @0.8 nozzle
|
||||
color_change_gcode = M600\nG1 E0.6 F1500 ; prime after color change
|
||||
@ -9943,7 +9944,7 @@ max_layer_height = 0.15
|
||||
min_layer_height = 0.05
|
||||
printer_variant = 0.25
|
||||
retract_lift = 0.15
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F1400\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nTc\n; purge line\nG1 X55 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F1400\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif}
|
||||
default_print_profile = 0.10mm DETAIL @0.25 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
|
||||
@ -9953,7 +9954,7 @@ renamed_from = "Original Prusa i3 MK3S MMU2S"
|
||||
machine_max_acceleration_e = 8000,8000
|
||||
nozzle_diameter = 0.4,0.4,0.4,0.4,0.4
|
||||
extruder_colour = #FF8000;#DB5182;#3EC0FF;#FF4F4F;#FBEB7D
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E29 F1073\nG1 X5 E29 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E29 F1073\nG1 X5 E29 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif}
|
||||
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y210 F7200 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\n{if has_wipe_tower}\nG1 E-15 F3000\n{else}\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15 F5800\nG1 E-20 F5500\nG1 E10 F3000\nG1 E-10 F3100\nG1 E10 F3150\nG1 E-10 F3250\nG1 E10 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
|
||||
## 0.6mm nozzle MMU2/S printer profiles
|
||||
@ -9966,7 +9967,7 @@ max_layer_height = 0.40
|
||||
min_layer_height = 0.15
|
||||
printer_variant = 0.6
|
||||
deretract_speed = 25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E29 F1073\nG1 X5 E29 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E29 F1073\nG1 X5 E29 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.5 F1500 ; prime after color change
|
||||
|
||||
@ -9977,7 +9978,7 @@ max_layer_height = 0.40
|
||||
min_layer_height = 0.15
|
||||
printer_variant = 0.6
|
||||
deretract_speed = 25
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E32 F1073\nG1 X5 E32 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55 E32 F1073\nG1 X5 E32 F1800\nG1 X55 E8 F2000\nG1 Z0.3 F1000\nG92 E0\nG1 X240 E25 F2200\nG1 Y-2 F1000\nG1 X55 E25 F1400\nG1 Z0.2 F1000\nG1 X5 E4 F1000\nG92 E0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0
|
||||
default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3
|
||||
color_change_gcode = M600\nG1 E0.5 F1500 ; prime after color change
|
||||
|
||||
@ -10011,7 +10012,7 @@ color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
## max_layer_height = 0.6
|
||||
## min_layer_height = 0.2
|
||||
## printer_variant = 0.8
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000\nG1 Z0.4 F1000\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0
|
||||
## default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
|
||||
## [printer:Original Prusa i3 MK3S & MK3S+ MMU2S 0.8 nozzle]
|
||||
@ -10020,7 +10021,7 @@ color_change_gcode = M600\nG1 E0.3 F1500 ; prime after color change
|
||||
## max_layer_height = 0.6
|
||||
## min_layer_height = 0.2
|
||||
## printer_variant = 0.8
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.11.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0
|
||||
## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.12.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0
|
||||
## default_print_profile = 0.40mm QUALITY @0.8 nozzle
|
||||
|
||||
## MINI
|
||||
|
@ -24,6 +24,9 @@ struct SlopeDetection
|
||||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform bool use_color_clip_plane;
|
||||
uniform vec4 uniform_color_clip_plane_1;
|
||||
uniform vec4 uniform_color_clip_plane_2;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
@ -34,6 +37,7 @@ uniform SlopeDetection slope;
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
// x = diffuse, y = specular;
|
||||
varying vec2 intensity;
|
||||
@ -46,12 +50,18 @@ void main()
|
||||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
discard;
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
|
||||
vec4 color;
|
||||
if (use_color_clip_plane) {
|
||||
color.rgb = (color_clip_plane_dot < 0.0) ? uniform_color_clip_plane_1.rgb : uniform_color_clip_plane_2.rgb;
|
||||
color.a = uniform_color.a;
|
||||
}
|
||||
else
|
||||
color = uniform_color;
|
||||
|
||||
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
|
||||
color = vec3(0.7, 0.7, 1.0);
|
||||
alpha = 1.0;
|
||||
color.rgb = vec3(0.7, 0.7, 1.0);
|
||||
color.a = 1.0;
|
||||
}
|
||||
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
@ -67,13 +77,13 @@ void main()
|
||||
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
|
||||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
}
|
||||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_tex)
|
||||
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
else
|
||||
#endif
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ uniform SlopeDetection slope;
|
||||
uniform vec2 z_range;
|
||||
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||
uniform vec4 clipping_plane;
|
||||
// Color clip plane - general orientation. Used by the cut gizmo.
|
||||
uniform vec4 color_clip_plane;
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
@ -43,6 +45,7 @@ attribute vec3 v_normal;
|
||||
varying vec2 intensity;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
varying vec4 world_pos;
|
||||
varying float world_normal_z;
|
||||
@ -74,4 +77,5 @@ void main()
|
||||
gl_Position = projection_matrix * position;
|
||||
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
|
||||
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
|
||||
color_clip_plane_dot = dot(world_pos, color_clip_plane);
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ struct SlopeDetection
|
||||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform bool use_color_clip_plane;
|
||||
uniform vec4 uniform_color_clip_plane_1;
|
||||
uniform vec4 uniform_color_clip_plane_2;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
@ -34,6 +37,7 @@ uniform SlopeDetection slope;
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
in vec3 clipping_planes_dots;
|
||||
in float color_clip_plane_dot;
|
||||
|
||||
// x = diffuse, y = specular;
|
||||
in vec2 intensity;
|
||||
@ -48,12 +52,18 @@ void main()
|
||||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
discard;
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
|
||||
vec4 color;
|
||||
if (use_color_clip_plane) {
|
||||
color.rgb = (color_clip_plane_dot < 0.0) ? uniform_color_clip_plane_1.rgb : uniform_color_clip_plane_2.rgb;
|
||||
color.a = uniform_color.a;
|
||||
}
|
||||
else
|
||||
color = uniform_color;
|
||||
|
||||
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
|
||||
color = vec3(0.7, 0.7, 1.0);
|
||||
alpha = 1.0;
|
||||
color.rgb = vec3(0.7, 0.7, 1.0);
|
||||
color.a = 1.0;
|
||||
}
|
||||
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
@ -69,13 +79,13 @@ void main()
|
||||
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
|
||||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
}
|
||||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_tex)
|
||||
out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
|
||||
out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
else
|
||||
#endif
|
||||
out_color = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
out_color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ uniform SlopeDetection slope;
|
||||
uniform vec2 z_range;
|
||||
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||
uniform vec4 clipping_plane;
|
||||
// Color clip plane - general orientation. Used by the cut gizmo.
|
||||
uniform vec4 color_clip_plane;
|
||||
|
||||
in vec3 v_position;
|
||||
in vec3 v_normal;
|
||||
@ -43,6 +45,7 @@ in vec3 v_normal;
|
||||
out vec2 intensity;
|
||||
|
||||
out vec3 clipping_planes_dots;
|
||||
out float color_clip_plane_dot;
|
||||
|
||||
out vec4 world_pos;
|
||||
out float world_normal_z;
|
||||
@ -74,4 +77,5 @@ void main()
|
||||
gl_Position = projection_matrix * position;
|
||||
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
|
||||
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
|
||||
color_clip_plane_dot = dot(world_pos, color_clip_plane);
|
||||
}
|
||||
|
@ -26,6 +26,9 @@ struct SlopeDetection
|
||||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform bool use_color_clip_plane;
|
||||
uniform vec4 uniform_color_clip_plane_1;
|
||||
uniform vec4 uniform_color_clip_plane_2;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
@ -36,6 +39,7 @@ uniform SlopeDetection slope;
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
// x = diffuse, y = specular;
|
||||
varying vec2 intensity;
|
||||
@ -48,12 +52,18 @@ void main()
|
||||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
discard;
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
|
||||
vec4 color;
|
||||
if (use_color_clip_plane) {
|
||||
color.rgb = (color_clip_plane_dot < 0.0) ? uniform_color_clip_plane_1.rgb : uniform_color_clip_plane_2.rgb;
|
||||
color.a = uniform_color.a;
|
||||
}
|
||||
else
|
||||
color = uniform_color;
|
||||
|
||||
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
|
||||
color = vec3(0.7, 0.7, 1.0);
|
||||
alpha = 1.0;
|
||||
color.rgb = vec3(0.7, 0.7, 1.0);
|
||||
color.a = 1.0;
|
||||
}
|
||||
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
@ -70,12 +80,12 @@ void main()
|
||||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_tex)
|
||||
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
else
|
||||
#endif
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ uniform SlopeDetection slope;
|
||||
uniform vec2 z_range;
|
||||
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||
uniform vec4 clipping_plane;
|
||||
// Color clip plane - general orientation. Used by the cut gizmo.
|
||||
uniform vec4 color_clip_plane;
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
@ -43,6 +45,7 @@ attribute vec3 v_normal;
|
||||
varying vec2 intensity;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
varying vec4 world_pos;
|
||||
varying float world_normal_z;
|
||||
@ -74,4 +77,5 @@ void main()
|
||||
gl_Position = projection_matrix * position;
|
||||
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
|
||||
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
|
||||
color_clip_plane_dot = dot(world_pos, color_clip_plane);
|
||||
}
|
||||
|
@ -72,6 +72,8 @@ int CLI::run(int argc, char **argv)
|
||||
{
|
||||
// Mark the main thread for the debugger and for runtime checks.
|
||||
set_current_thread_name("slic3r_main");
|
||||
// Save the thread ID of the main thread.
|
||||
save_main_thread_id();
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// On Linux, wxGTK has no support for Wayland, and the app crashes on
|
||||
|
@ -150,6 +150,8 @@ namespace ImGui
|
||||
// const wchar_t CustomSupportsMarker = 0x1D;
|
||||
// const wchar_t CustomSeamMarker = 0x1E;
|
||||
// const wchar_t MmuSegmentationMarker = 0x1F;
|
||||
const wchar_t PlugMarker = 0x1C;
|
||||
const wchar_t DowelMarker = 0x1D;
|
||||
// Do not forget use following letters only in wstring
|
||||
const wchar_t DocumentationButton = 0x2600;
|
||||
const wchar_t DocumentationHoverButton = 0x2601;
|
||||
|
@ -417,12 +417,8 @@ std::string AppConfig::load()
|
||||
|
||||
void AppConfig::save()
|
||||
{
|
||||
{
|
||||
// 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!");
|
||||
}
|
||||
if (! is_main_thread_active())
|
||||
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
||||
|
||||
// The config is first written to a file with a PID suffix and then moved
|
||||
// to avoid race conditions with multiple instances of Slic3r
|
||||
@ -491,6 +487,46 @@ void AppConfig::save()
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
bool AppConfig::erase(const std::string §ion, const std::string &key)
|
||||
{
|
||||
if (auto it_storage = m_storage.find(section); it_storage != m_storage.end()) {
|
||||
auto §ion = it_storage->second;
|
||||
auto it = section.find(key);
|
||||
if (it != section.end()) {
|
||||
section.erase(it);
|
||||
m_dirty = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AppConfig::set_section(const std::string §ion, std::map<std::string, std::string> data)
|
||||
{
|
||||
auto it_section = m_storage.find(section);
|
||||
if (it_section == m_storage.end()) {
|
||||
if (data.empty())
|
||||
return false;
|
||||
it_section = m_storage.insert({ section, {} }).first;
|
||||
}
|
||||
auto &dst = it_section->second;
|
||||
if (dst == data)
|
||||
return false;
|
||||
dst = std::move(data);
|
||||
m_dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppConfig::clear_section(const std::string §ion)
|
||||
{
|
||||
if (auto it_section = m_storage.find(section); it_section != m_storage.end() && ! it_section->second.empty()) {
|
||||
it_section->second.clear();
|
||||
m_dirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
|
||||
{
|
||||
const auto it_v = m_vendors.find(vendor);
|
||||
@ -499,28 +535,47 @@ bool AppConfig::get_variant(const std::string &vendor, const std::string &model,
|
||||
return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end();
|
||||
}
|
||||
|
||||
void AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable)
|
||||
bool AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
if (get_variant(vendor, model, variant)) { return; }
|
||||
if (get_variant(vendor, model, variant))
|
||||
return false;
|
||||
m_vendors[vendor][model].insert(variant);
|
||||
} else {
|
||||
auto it_v = m_vendors.find(vendor);
|
||||
if (it_v == m_vendors.end()) { return; }
|
||||
if (it_v == m_vendors.end())
|
||||
return false;
|
||||
auto it_m = it_v->second.find(model);
|
||||
if (it_m == it_v->second.end()) { return; }
|
||||
if (it_m == it_v->second.end())
|
||||
return false;
|
||||
auto it_var = it_m->second.find(variant);
|
||||
if (it_var == it_m->second.end()) { return; }
|
||||
if (it_var == it_m->second.end())
|
||||
return false;
|
||||
it_m->second.erase(it_var);
|
||||
}
|
||||
// If we got here, there was an update
|
||||
m_dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AppConfig::set_vendors(const AppConfig &from)
|
||||
bool AppConfig::set_vendors(const VendorMap &vendors)
|
||||
{
|
||||
m_vendors = from.m_vendors;
|
||||
m_dirty = true;
|
||||
if (m_vendors != vendors) {
|
||||
m_vendors = vendors;
|
||||
m_dirty = true;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AppConfig::set_vendors(VendorMap &&vendors)
|
||||
{
|
||||
if (m_vendors != vendors) {
|
||||
m_vendors = std::move(vendors);
|
||||
m_dirty = true;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AppConfig::get_last_dir() const
|
||||
@ -555,34 +610,52 @@ std::vector<std::string> AppConfig::get_recent_projects() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AppConfig::set_recent_projects(const std::vector<std::string>& recent_projects)
|
||||
bool AppConfig::set_recent_projects(const std::vector<std::string>& recent_projects)
|
||||
{
|
||||
auto it = m_storage.find("recent_projects");
|
||||
if (it == m_storage.end())
|
||||
it = m_storage.insert(std::map<std::string, std::map<std::string, std::string>>::value_type("recent_projects", std::map<std::string, std::string>())).first;
|
||||
|
||||
it->second.clear();
|
||||
for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i)
|
||||
{
|
||||
it->second[std::to_string(i + 1)] = recent_projects[i];
|
||||
static constexpr const char *section = "recent_projects";
|
||||
auto it_section = m_storage.find(section);
|
||||
if (it_section == m_storage.end()) {
|
||||
if (recent_projects.empty())
|
||||
return false;
|
||||
it_section = m_storage.insert({ std::string(section), {} }).first;
|
||||
}
|
||||
auto &dst = it_section->second;
|
||||
|
||||
std::map<std::string, std::string> src;
|
||||
for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i)
|
||||
src[std::to_string(i + 1)] = recent_projects[i];
|
||||
|
||||
if (src != dst) {
|
||||
dst = std::move(src);
|
||||
m_dirty = true;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
void AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone,
|
||||
bool AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone,
|
||||
float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz)
|
||||
{
|
||||
std::string key = std::string("mouse_device:") + name;
|
||||
auto it = m_storage.find(key);
|
||||
if (it == m_storage.end())
|
||||
it = m_storage.insert(std::map<std::string, std::map<std::string, std::string>>::value_type(key, std::map<std::string, std::string>())).first;
|
||||
const std::string key = std::string("mouse_device:") + name;
|
||||
auto it_section = m_storage.find(key);
|
||||
if (it_section == m_storage.end())
|
||||
it_section = m_storage.insert({ key, {} }).first;
|
||||
auto &dst = it_section->second;
|
||||
|
||||
it->second.clear();
|
||||
it->second["translation_speed"] = float_to_string_decimal_point(translation_speed);
|
||||
it->second["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone);
|
||||
it->second["rotation_speed"] = float_to_string_decimal_point(rotation_speed);
|
||||
it->second["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone);
|
||||
it->second["zoom_speed"] = float_to_string_decimal_point(zoom_speed);
|
||||
it->second["swap_yz"] = swap_yz ? "1" : "0";
|
||||
std::map<std::string, std::string> src;
|
||||
src["translation_speed"] = float_to_string_decimal_point(translation_speed);
|
||||
src["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone);
|
||||
src["rotation_speed"] = float_to_string_decimal_point(rotation_speed);
|
||||
src["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone);
|
||||
src["zoom_speed"] = float_to_string_decimal_point(zoom_speed);
|
||||
src["swap_yz"] = swap_yz ? "1" : "0";
|
||||
|
||||
if (src != dst) {
|
||||
dst = std::move(src);
|
||||
m_dirty = true;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> AppConfig::get_mouse_device_names() const
|
||||
@ -596,16 +669,16 @@ std::vector<std::string> AppConfig::get_mouse_device_names() const
|
||||
return out;
|
||||
}
|
||||
|
||||
void AppConfig::update_config_dir(const std::string &dir)
|
||||
bool AppConfig::update_config_dir(const std::string &dir)
|
||||
{
|
||||
this->set("recent", "config_directory", dir);
|
||||
return this->set("recent", "config_directory", dir);
|
||||
}
|
||||
|
||||
void AppConfig::update_skein_dir(const std::string &dir)
|
||||
bool AppConfig::update_skein_dir(const std::string &dir)
|
||||
{
|
||||
if (is_shapes_dir(dir))
|
||||
return; // do not save "shapes gallery" directory
|
||||
this->set("recent", "skein_directory", dir);
|
||||
return false; // do not save "shapes gallery" directory
|
||||
return this->set("recent", "skein_directory", dir);
|
||||
}
|
||||
/*
|
||||
std::string AppConfig::get_last_output_dir(const std::string &alt) const
|
||||
@ -640,9 +713,9 @@ std::string AppConfig::get_last_output_dir(const std::string& alt, const bool re
|
||||
return is_shapes_dir(alt) ? get_last_dir() : alt;
|
||||
}
|
||||
|
||||
void AppConfig::update_last_output_dir(const std::string& dir, const bool removable)
|
||||
bool AppConfig::update_last_output_dir(const std::string& dir, const bool removable)
|
||||
{
|
||||
this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir);
|
||||
return this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir);
|
||||
}
|
||||
|
||||
|
||||
@ -660,7 +733,7 @@ void AppConfig::reset_selections()
|
||||
}
|
||||
}
|
||||
|
||||
std::string AppConfig::config_path()
|
||||
std::string AppConfig::config_path() const
|
||||
{
|
||||
std::string path = (m_mode == EAppMode::Editor) ?
|
||||
(boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string() :
|
||||
@ -695,7 +768,7 @@ std::string AppConfig::profile_folder_url() const
|
||||
return PROFILE_FOLDER_URL;
|
||||
}
|
||||
|
||||
bool AppConfig::exists()
|
||||
bool AppConfig::exists() const
|
||||
{
|
||||
return boost::filesystem::exists(config_path());
|
||||
}
|
||||
|
@ -58,9 +58,13 @@ public:
|
||||
}
|
||||
std::string get(const std::string §ion, const std::string &key) const
|
||||
{ std::string value; this->get(section, key, value); return value; }
|
||||
bool get_bool(const std::string §ion, const std::string &key) const
|
||||
{ return this->get(section, key) == "1"; }
|
||||
std::string get(const std::string &key) const
|
||||
{ std::string value; this->get("", key, value); return value; }
|
||||
void set(const std::string §ion, const std::string &key, const std::string &value)
|
||||
bool get_bool(const std::string &key) const
|
||||
{ return this->get(key) == "1"; }
|
||||
bool set(const std::string §ion, const std::string &key, const std::string &value)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
@ -74,10 +78,12 @@ public:
|
||||
if (old != value) {
|
||||
old = value;
|
||||
m_dirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void set(const std::string &key, const std::string &value)
|
||||
{ this->set("", key, value); }
|
||||
bool set(const std::string &key, const std::string &value)
|
||||
{ return this->set("", key, value); }
|
||||
bool has(const std::string §ion, const std::string &key) const
|
||||
{
|
||||
auto it = m_storage.find(section);
|
||||
@ -89,40 +95,32 @@ public:
|
||||
bool has(const std::string &key) const
|
||||
{ return this->has("", key); }
|
||||
|
||||
void erase(const std::string §ion, const std::string &key)
|
||||
{
|
||||
auto it = m_storage.find(section);
|
||||
if (it != m_storage.end()) {
|
||||
it->second.erase(key);
|
||||
}
|
||||
}
|
||||
bool erase(const std::string §ion, const std::string &key);
|
||||
|
||||
bool has_section(const std::string §ion) const
|
||||
{ return m_storage.find(section) != m_storage.end(); }
|
||||
const std::map<std::string, std::string>& get_section(const std::string §ion) const
|
||||
{ auto it = m_storage.find(section); assert(it != m_storage.end()); return it->second; }
|
||||
void set_section(const std::string §ion, const std::map<std::string, std::string>& data)
|
||||
{ m_storage[section] = data; }
|
||||
void clear_section(const std::string §ion)
|
||||
{ m_storage[section].clear(); }
|
||||
bool set_section(const std::string §ion, std::map<std::string, std::string> data);
|
||||
bool clear_section(const std::string §ion);
|
||||
|
||||
typedef std::map<std::string, std::map<std::string, std::set<std::string>>> VendorMap;
|
||||
bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const;
|
||||
void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
|
||||
void set_vendors(const AppConfig &from);
|
||||
void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; }
|
||||
void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; }
|
||||
bool set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
|
||||
bool set_vendors(const AppConfig &from) { return this->set_vendors(from.vendors()); }
|
||||
bool set_vendors(const VendorMap &vendors);
|
||||
bool set_vendors(VendorMap &&vendors);
|
||||
const VendorMap& vendors() const { return m_vendors; }
|
||||
|
||||
// return recent/skein_directory or recent/config_directory or empty string.
|
||||
std::string get_last_dir() const;
|
||||
void update_config_dir(const std::string &dir);
|
||||
void update_skein_dir(const std::string &dir);
|
||||
bool update_config_dir(const std::string &dir);
|
||||
bool update_skein_dir(const std::string &dir);
|
||||
|
||||
//std::string get_last_output_dir(const std::string &alt) const;
|
||||
//void update_last_output_dir(const std::string &dir);
|
||||
std::string get_last_output_dir(const std::string& alt, const bool removable = false) const;
|
||||
void update_last_output_dir(const std::string &dir, const bool removable = false);
|
||||
bool update_last_output_dir(const std::string &dir, const bool removable = false);
|
||||
|
||||
// reset the current print / filament / printer selections, so that
|
||||
// the PresetBundle::load_selections(const AppConfig &config) call will select
|
||||
@ -130,7 +128,7 @@ public:
|
||||
void reset_selections();
|
||||
|
||||
// Get the default config path from Slic3r::data_dir().
|
||||
std::string config_path();
|
||||
std::string config_path() const;
|
||||
|
||||
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
|
||||
bool legacy_datadir() const { return m_legacy_datadir; }
|
||||
@ -140,9 +138,9 @@ public:
|
||||
// This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
|
||||
std::string version_check_url() const;
|
||||
// Get the Slic3r url to vendor index archive zip.
|
||||
std::string index_archive_url() const;
|
||||
std::string index_archive_url() const;
|
||||
// Get the Slic3r url to folder with vendor profile files.
|
||||
std::string profile_folder_url() const;
|
||||
std::string profile_folder_url() const;
|
||||
|
||||
|
||||
// Returns the original Slic3r version found in the ini file before it was overwritten
|
||||
@ -150,12 +148,12 @@ public:
|
||||
Semver orig_version() const { return m_orig_version; }
|
||||
|
||||
// Does the config file exist?
|
||||
bool exists();
|
||||
bool exists() const;
|
||||
|
||||
std::vector<std::string> get_recent_projects() const;
|
||||
void set_recent_projects(const std::vector<std::string>& recent_projects);
|
||||
bool set_recent_projects(const std::vector<std::string>& recent_projects);
|
||||
|
||||
void set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz);
|
||||
bool set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz);
|
||||
std::vector<std::string> get_mouse_device_names() const;
|
||||
bool get_mouse_device_translation_speed(const std::string& name, double& speed) const
|
||||
{ return get_3dmouse_device_numeric_value(name, "translation_speed", speed); }
|
||||
|
@ -361,6 +361,8 @@ inline Slic3r::Polygons expand(const Slic3r::Polygon &polygon, const float del
|
||||
{ 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)
|
||||
{ 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)
|
||||
{ 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.
|
||||
|
@ -268,7 +268,7 @@ ConfigOption* ConfigOptionDef::create_empty_option() const
|
||||
// case coPoint3s: return new ConfigOptionPoint3s();
|
||||
case coBool: return new ConfigOptionBool();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -279,7 +279,7 @@ ConfigOption* ConfigOptionDef::create_default_option() const
|
||||
if (this->default_value)
|
||||
return (this->default_value->type() == coEnum) ?
|
||||
// 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();
|
||||
return this->create_empty_option();
|
||||
}
|
||||
@ -303,6 +303,31 @@ ConfigOptionDef* ConfigDef::add_nullable(const t_config_option_key &opt_key, Con
|
||||
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
|
||||
{
|
||||
// prepare a function for wrapping text
|
||||
@ -378,8 +403,8 @@ std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, s
|
||||
descr += " (";
|
||||
if (!def.sidetext.empty()) {
|
||||
descr += def.sidetext + ", ";
|
||||
} else if (!def.enum_values.empty()) {
|
||||
descr += boost::algorithm::join(def.enum_values, ", ") + "; ";
|
||||
} else if (def.enum_def->has_values()) {
|
||||
descr += boost::algorithm::join(def.enum_def->values(), ", ") + "; ";
|
||||
}
|
||||
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 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,
|
||||
// look for it in the next token.
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <float.h>
|
||||
#include "libslic3r.h"
|
||||
@ -226,6 +227,7 @@ enum ForwardCompatibilitySubstitutionRule
|
||||
EnableSilentDisableSystem,
|
||||
};
|
||||
|
||||
class ConfigDef;
|
||||
class ConfigOption;
|
||||
class ConfigOptionDef;
|
||||
// For forward definition of ConfigOption in ConfigOptionUniquePtr, we have to define a custom deleter.
|
||||
@ -1547,7 +1549,7 @@ public:
|
||||
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();
|
||||
// Map from an enum name to an enum integer value.
|
||||
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)); }
|
||||
};
|
||||
|
||||
// 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.
|
||||
class ConfigOptionDef
|
||||
{
|
||||
@ -1629,16 +1802,18 @@ public:
|
||||
i_enum_open,
|
||||
// Open enums, float value could be one of the enumerated values or something else.
|
||||
f_enum_open,
|
||||
// Open enums, string value could be one of the enumerated values or something else.
|
||||
select_open,
|
||||
// Color picker, string value.
|
||||
color,
|
||||
// ???
|
||||
select_open,
|
||||
// Currently unused.
|
||||
slider,
|
||||
// Static text
|
||||
legend,
|
||||
// Vector value, but edited as a single 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.
|
||||
@ -1683,7 +1858,7 @@ public:
|
||||
case coPoint3: { auto opt = new ConfigOptionPoint3(); archive(*opt); return opt; }
|
||||
case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
|
||||
case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
|
||||
case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_keys_map); archive(*opt); return opt; }
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1780,30 +1955,73 @@ public:
|
||||
// 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".
|
||||
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) {
|
||||
enum_values.clear();
|
||||
enum_values.reserve(il.size());
|
||||
enum_labels.clear();
|
||||
enum_labels.reserve(il.size());
|
||||
for (const std::pair<std::string_view, std::string_view> p : il) {
|
||||
enum_values.emplace_back(p.first);
|
||||
enum_labels.emplace_back(p.second);
|
||||
}
|
||||
Slic3r::clonable_ptr<ConfigOptionEnumDef> enum_def;
|
||||
|
||||
void set_enum_values(const std::initializer_list<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::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 {
|
||||
for (const std::string &v : enum_values)
|
||||
if (v == value)
|
||||
return true;
|
||||
return false;
|
||||
return enum_def && enum_def->value_to_index(value).has_value();
|
||||
}
|
||||
|
||||
// 0 is an invalid key.
|
||||
@ -1815,6 +2033,14 @@ public:
|
||||
|
||||
// Assign this key to cli to disable CLI for this option.
|
||||
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() {
|
||||
@ -1860,6 +2086,8 @@ public:
|
||||
protected:
|
||||
ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type);
|
||||
ConfigOptionDef* add_nullable(const t_config_option_key &opt_key, ConfigOptionType type);
|
||||
// Finalize open / close enums, validate everything.
|
||||
void finalize();
|
||||
};
|
||||
|
||||
// A pure interface to resolving ConfigOptions.
|
||||
@ -1969,7 +2197,12 @@ public:
|
||||
{ return dynamic_cast<T*>(this->optptr(opt_key, create)); }
|
||||
template<class T> const T* opt(const t_config_option_key &opt_key) const
|
||||
{ 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.
|
||||
// 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.
|
||||
|
@ -31,6 +31,9 @@ public:
|
||||
virtual void reverse() = 0;
|
||||
virtual const Point& first_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.
|
||||
// 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;
|
||||
@ -81,6 +84,7 @@ public:
|
||||
void reverse() override { this->polyline.reverse(); }
|
||||
const Point& first_point() const override { return this->polyline.points.front(); }
|
||||
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(); }
|
||||
bool empty() const { return this->polyline.empty(); }
|
||||
bool is_closed() const { return ! this->empty() && this->polyline.points.front() == this->polyline.points.back(); }
|
||||
@ -153,6 +157,7 @@ public:
|
||||
void reverse() override;
|
||||
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& 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(); }
|
||||
bool empty() const { return this->paths.empty(); }
|
||||
double length() const override;
|
||||
@ -204,6 +209,7 @@ public:
|
||||
void reverse() override;
|
||||
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& middle_point() const override { auto& path = this->paths[this->paths.size() / 2]; return path.polyline.points[path.polyline.size() / 2]; }
|
||||
Polygon polygon() const;
|
||||
double length() const override;
|
||||
bool split_at_vertex(const Point &point, const double scaled_epsilon = scaled<double>(0.001));
|
||||
@ -288,12 +294,12 @@ inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, const Pol
|
||||
}
|
||||
}
|
||||
|
||||
inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height)
|
||||
inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse = true)
|
||||
{
|
||||
dst.reserve(dst.size() + polylines.size());
|
||||
for (Polyline &polyline : polylines)
|
||||
if (polyline.is_valid()) {
|
||||
ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
|
||||
ExtrusionPath *extrusion_path = can_reverse ? new ExtrusionPath(role, mm3_per_mm, width, height) : new ExtrusionPathOriented(role, mm3_per_mm, width, height);
|
||||
dst.push_back(extrusion_path);
|
||||
extrusion_path->polyline = std::move(polyline);
|
||||
}
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
void reverse() override;
|
||||
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& 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.
|
||||
// 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;
|
||||
|
@ -83,6 +83,11 @@ struct ExtrusionRole : public ExtrusionRoleModifiers
|
||||
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_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
|
||||
|
@ -230,6 +230,8 @@ namespace Slic3r {
|
||||
|
||||
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
|
||||
|
||||
gcode += gcodegen.writer().unlift(); // Make sure there is no z-hop (in most cases, there isn't).
|
||||
|
||||
double current_z = gcodegen.writer().get_position().z();
|
||||
if (z == -1.) // in case no specific z was provided, print at current_z pos
|
||||
z = current_z;
|
||||
@ -1192,7 +1194,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
||||
|
||||
std::vector<unsigned char> is_extruder_used(print.config().nozzle_diameter.size(), 0);
|
||||
for (unsigned int extruder_id : print.extruders())
|
||||
for (unsigned int extruder_id : tool_ordering.all_extruders())
|
||||
is_extruder_used[extruder_id] = true;
|
||||
m_placeholder_parser.set("is_extruder_used", new ConfigOptionBools(is_extruder_used));
|
||||
}
|
||||
@ -1784,9 +1786,7 @@ std::vector<GCode::InstanceToPrint> GCode::sort_print_object_instances(
|
||||
if (ordering == nullptr) {
|
||||
// Sequential print, single object is being printed.
|
||||
assert(object_layers.size() == 1);
|
||||
const Layer *layer = object_layers.front().object_layer;
|
||||
assert(layer != nullptr);
|
||||
out.emplace_back(0, *layer->object(), single_object_instance_idx);
|
||||
out.emplace_back(0, *object_layers.front().object(), single_object_instance_idx);
|
||||
} else {
|
||||
// Create mapping from PrintObject* to ObjectLayerToPrint ID.
|
||||
std::vector<std::pair<const PrintObject*, size_t>> sorted;
|
||||
@ -2248,29 +2248,24 @@ void GCode::process_layer_single_object(
|
||||
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()) {
|
||||
ExtrusionRole role = support_layer.support_fills.role();
|
||||
bool has_support = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterial;
|
||||
bool has_interface = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterialInterface;
|
||||
bool has_support = role.is_mixed() || role.is_support_base();
|
||||
bool has_interface = role.is_mixed() || role.is_support_interface();
|
||||
// Extruder ID of the support base. -1 if "don't care".
|
||||
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?
|
||||
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".
|
||||
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?
|
||||
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) {
|
||||
// Some support will be printed with "don't care" material, preferably non-soluble.
|
||||
// Is the current extruder assigned a soluble filament?
|
||||
unsigned int dontcare_extruder = layer_tools.extruders.front();
|
||||
if (print.config().filament_soluble.get_at(dontcare_extruder)) {
|
||||
// The last extruder printed on the previous layer extrudes soluble filament.
|
||||
// Try to find a non-soluble extruder on the same layer.
|
||||
for (unsigned int extruder_id : layer_tools.extruders)
|
||||
if (! print.config().filament_soluble.get_at(extruder_id)) {
|
||||
dontcare_extruder = extruder_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto it_nonsoluble = std::find_if(layer_tools.extruders.begin(), layer_tools.extruders.end(),
|
||||
[&soluble = std::as_const(print.config().filament_soluble)](unsigned int extruder_id) { return ! soluble.get_at(extruder_id); });
|
||||
// There should be a non-soluble extruder available.
|
||||
assert(it_nonsoluble != layer_tools.extruders.end());
|
||||
unsigned int dontcare_extruder = it_nonsoluble == layer_tools.extruders.end() ? layer_tools.extruders.front() : *it_nonsoluble;
|
||||
if (support_dontcare)
|
||||
support_extruder = dontcare_extruder;
|
||||
if (interface_dontcare)
|
||||
@ -2284,7 +2279,7 @@ void GCode::process_layer_single_object(
|
||||
m_object_layer_over_raft = false;
|
||||
gcode += this->extrude_support(
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2798,8 +2793,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
||||
} else if (m_config.bridge_acceleration.value > 0 && path.role().is_bridge()) {
|
||||
acceleration = m_config.bridge_acceleration.value;
|
||||
} else if (m_config.top_solid_infill_acceleration > 0 && path.role() == ExtrusionRole::TopSolidInfill) {
|
||||
acceleration = m_config.top_solid_infill_acceleration.value;
|
||||
} else if (m_config.solid_infill_acceleration > 0 && path.role().is_solid_infill()) {
|
||||
acceleration = m_config.solid_infill_acceleration.value;
|
||||
} else if (m_config.infill_acceleration.value > 0 && path.role().is_infill()) {
|
||||
acceleration = m_config.infill_acceleration.value;
|
||||
} else if (m_config.external_perimeter_acceleration > 0 && path.role().is_external_perimeter()) {
|
||||
acceleration = m_config.external_perimeter_acceleration.value;
|
||||
} else if (m_config.perimeter_acceleration.value > 0 && path.role().is_perimeter()) {
|
||||
acceleration = m_config.perimeter_acceleration.value;
|
||||
} else {
|
||||
@ -2861,9 +2862,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||
bool variable_speed = false;
|
||||
std::vector<ProcessedPoint> new_points{};
|
||||
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,
|
||||
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; });
|
||||
}
|
||||
|
||||
@ -2948,10 +2952,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||
prev = p;
|
||||
}
|
||||
} else {
|
||||
std::string comment;
|
||||
std::string marked_comment;
|
||||
if (m_config.gcode_comments) {
|
||||
comment = description;
|
||||
comment += description_bridge;
|
||||
marked_comment = description;
|
||||
marked_comment += description_bridge;
|
||||
}
|
||||
double last_set_speed = new_points[0].speed * 60.0;
|
||||
gcode += m_writer.set_speed(last_set_speed, "", comment);
|
||||
@ -2960,7 +2964,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||
const ProcessedPoint& processed_point = new_points[i];
|
||||
Vec2d p = this->point_to_gcode_quantized(processed_point.p);
|
||||
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;
|
||||
double new_speed = processed_point.speed * 60.0;
|
||||
if (last_set_speed != new_speed) {
|
||||
|
@ -461,23 +461,24 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
}
|
||||
active_speed_modifier = size_t(-1);
|
||||
} else if (boost::starts_with(sline, m_toolchange_prefix)) {
|
||||
unsigned int new_extruder;
|
||||
unsigned int new_extruder = 0;
|
||||
auto res = std::from_chars(sline.data() + m_toolchange_prefix.size(), sline.data() + sline.size(), new_extruder);
|
||||
// Only change extruder in case the number is meaningful. User could provide an out-of-range index through custom gcodes - those shall be ignored.
|
||||
if (new_extruder < map_extruder_to_per_extruder_adjustment.size()) {
|
||||
if (new_extruder != current_extruder) {
|
||||
// Switch the tool.
|
||||
line.type = CoolingLine::TYPE_SET_TOOL;
|
||||
current_extruder = new_extruder;
|
||||
adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
|
||||
if (res.ec != std::errc::invalid_argument) {
|
||||
// Only change extruder in case the number is meaningful. User could provide an out-of-range index through custom gcodes - those shall be ignored.
|
||||
if (new_extruder < map_extruder_to_per_extruder_adjustment.size()) {
|
||||
if (new_extruder != current_extruder) {
|
||||
// Switch the tool.
|
||||
line.type = CoolingLine::TYPE_SET_TOOL;
|
||||
current_extruder = new_extruder;
|
||||
adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Only log the error in case of MM printer. Single extruder printers likely ignore any T anyway.
|
||||
if (map_extruder_to_per_extruder_adjustment.size() > 1)
|
||||
BOOST_LOG_TRIVIAL(error) << "CoolingBuffer encountered an invalid toolchange, maybe from a custom gcode: " << sline;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Only log the error in case of MM printer. Single extruder printers likely ignore any T anyway.
|
||||
if (map_extruder_to_per_extruder_adjustment.size() > 1)
|
||||
BOOST_LOG_TRIVIAL(error) << "CoolingBuffer encountered an invalid toolchange, maybe from a custom gcode: " << sline;
|
||||
}
|
||||
|
||||
} else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
|
||||
line.type = CoolingLine::TYPE_BRIDGE_FAN_START;
|
||||
} else if (boost::starts_with(sline, ";_BRIDGE_FAN_END")) {
|
||||
@ -785,9 +786,9 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
||||
if (line_start > pos)
|
||||
new_gcode.append(pos, line_start - pos);
|
||||
if (line->type & CoolingLine::TYPE_SET_TOOL) {
|
||||
unsigned int new_extruder;
|
||||
unsigned int new_extruder = 0;
|
||||
auto res = std::from_chars(line_start + m_toolchange_prefix.size(), line_end, new_extruder);
|
||||
if (new_extruder != m_current_extruder) {
|
||||
if (res.ec != std::errc::invalid_argument && new_extruder != m_current_extruder) {
|
||||
m_current_extruder = new_extruder;
|
||||
change_extruder_set_fan();
|
||||
}
|
||||
|
@ -264,10 +264,11 @@ public:
|
||||
float original_speed)
|
||||
{
|
||||
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;
|
||||
for (size_t i = 0; i < speed_sections_count; i++) {
|
||||
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});
|
||||
}
|
||||
std::sort(speed_sections.begin(), speed_sections.end(),
|
||||
|
@ -593,9 +593,11 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||
m_time_processor.filament_unload_times[i] = static_cast<float>(config.filament_unload_time.values[i]);
|
||||
}
|
||||
|
||||
m_single_extruder_multi_material = config.single_extruder_multi_material;
|
||||
|
||||
// With MM setups like Prusa MMU2, the filaments may be expected to be parked at the beginning.
|
||||
// Remember the parking position so the initial load is not included in filament estimate.
|
||||
if (config.single_extruder_multi_material && extruders_count > 1 && config.wipe_tower) {
|
||||
if (m_single_extruder_multi_material && extruders_count > 1 && config.wipe_tower) {
|
||||
m_parking_position = float(config.parking_pos_retraction.value);
|
||||
m_extra_loading_move = float(config.extra_loading_move);
|
||||
}
|
||||
@ -772,8 +774,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||
const ConfigOptionFloat* parking_pos_retraction = config.option<ConfigOptionFloat>("parking_pos_retraction");
|
||||
const ConfigOptionFloat* extra_loading_move = config.option<ConfigOptionFloat>("extra_loading_move");
|
||||
|
||||
if (single_extruder_multi_material != nullptr && wipe_tower != nullptr && parking_pos_retraction != nullptr && extra_loading_move != nullptr) {
|
||||
if (single_extruder_multi_material->value && m_result.extruders_count > 1 && wipe_tower->value) {
|
||||
m_single_extruder_multi_material = single_extruder_multi_material != nullptr && single_extruder_multi_material->value;
|
||||
|
||||
if (m_single_extruder_multi_material && wipe_tower != nullptr && parking_pos_retraction != nullptr && extra_loading_move != nullptr) {
|
||||
if (m_single_extruder_multi_material && m_result.extruders_count > 1 && wipe_tower->value) {
|
||||
m_parking_position = float(parking_pos_retraction->value);
|
||||
m_extra_loading_move = float(extra_loading_move->value);
|
||||
}
|
||||
@ -977,6 +981,8 @@ void GCodeProcessor::reset()
|
||||
m_spiral_vase_active = false;
|
||||
m_kissslicer_toolchange_time_correction = 0.0f;
|
||||
|
||||
m_single_extruder_multi_material = false;
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
m_mm3_per_mm_compare.reset();
|
||||
m_height_compare.reset();
|
||||
@ -3372,6 +3378,11 @@ void GCodeProcessor::process_T(const std::string_view command)
|
||||
extra_time += m_kissslicer_toolchange_time_correction;
|
||||
simulate_st_synchronize(extra_time);
|
||||
|
||||
// specific to single extruder multi material, set the extruder temperature
|
||||
// if not done yet
|
||||
if (m_single_extruder_multi_material && m_extruder_temps[m_extruder_id] == 0.0f)
|
||||
m_extruder_temps[m_extruder_id] = m_extruder_temps[old_extruder_id];
|
||||
|
||||
m_result.extruders_count = std::max<size_t>(m_result.extruders_count, m_extruder_id + 1);
|
||||
}
|
||||
|
||||
|
@ -559,6 +559,7 @@ namespace Slic3r {
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_start_time;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
bool m_single_extruder_multi_material;
|
||||
|
||||
enum class EProducer
|
||||
{
|
||||
|
@ -720,28 +720,26 @@ void Transformation::reset()
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Transformation::reset_rotation()
|
||||
{
|
||||
const Geometry::TransformationSVD svd(*this);
|
||||
m_matrix = get_offset_matrix() * Transform3d(svd.v * svd.s * svd.v.transpose()) * svd.mirror_matrix();
|
||||
}
|
||||
|
||||
void Transformation::reset_scaling_factor()
|
||||
{
|
||||
const Geometry::TransformationSVD svd(*this);
|
||||
m_matrix = get_offset_matrix() * Transform3d(svd.u) * Transform3d(svd.v.transpose()) * svd.mirror_matrix();
|
||||
}
|
||||
|
||||
void Transformation::reset_skew()
|
||||
{
|
||||
Matrix3d rotation;
|
||||
Matrix3d scale;
|
||||
m_matrix.computeRotationScaling(&rotation, &scale);
|
||||
auto new_scale_factor = [](const Matrix3d& s) {
|
||||
return pow(s(0, 0) * s(1, 1) * s(2, 2), 1. / 3.); // scale average
|
||||
};
|
||||
|
||||
const double average_scale = std::cbrt(scale(0, 0) * scale(1, 1) * scale(2, 2));
|
||||
|
||||
scale(0, 0) = is_left_handed() ? -average_scale : average_scale;
|
||||
scale(1, 1) = average_scale;
|
||||
scale(2, 2) = average_scale;
|
||||
|
||||
scale(0, 1) = 0.0;
|
||||
scale(0, 2) = 0.0;
|
||||
scale(1, 0) = 0.0;
|
||||
scale(1, 2) = 0.0;
|
||||
scale(2, 0) = 0.0;
|
||||
scale(2, 1) = 0.0;
|
||||
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation * scale;
|
||||
m_matrix.translation() = offset;
|
||||
const Geometry::TransformationSVD svd(*this);
|
||||
m_matrix = get_offset_matrix() * Transform3d(svd.u) * scale_transform(new_scale_factor(svd.s)) * Transform3d(svd.v.transpose()) * svd.mirror_matrix();
|
||||
}
|
||||
|
||||
Transform3d Transformation::get_matrix_no_offset() const
|
||||
@ -838,6 +836,43 @@ Transformation Transformation::volume_to_bed_transformation(const Transformation
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationSVD::TransformationSVD(const Transform3d& trafo)
|
||||
{
|
||||
const auto &m0 = trafo.matrix().block<3, 3>(0, 0);
|
||||
mirror = m0.determinant() < 0.0;
|
||||
|
||||
Matrix3d m;
|
||||
if (mirror)
|
||||
m = m0 * Eigen::DiagonalMatrix<double, 3, 3>(-1.0, 1.0, 1.0);
|
||||
else
|
||||
m = m0;
|
||||
const Eigen::JacobiSVD<Matrix3d> svd(m, Eigen::ComputeFullU | Eigen::ComputeFullV);
|
||||
u = svd.matrixU();
|
||||
v = svd.matrixV();
|
||||
s = svd.singularValues().asDiagonal();
|
||||
|
||||
scale = !s.isApprox(Matrix3d::Identity());
|
||||
anisotropic_scale = ! is_approx(s(0, 0), s(1, 1)) || ! is_approx(s(1, 1), s(2, 2));
|
||||
rotation = !v.isApprox(u);
|
||||
|
||||
if (anisotropic_scale) {
|
||||
rotation_90_degrees = true;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const Vec3d row = v.row(i).cwiseAbs();
|
||||
size_t num_zeros = is_approx(row[0], 0.) + is_approx(row[1], 0.) + is_approx(row[2], 0.);
|
||||
size_t num_ones = is_approx(row[0], 1.) + is_approx(row[1], 1.) + is_approx(row[2], 1.);
|
||||
if (num_zeros != 2 || num_ones != 1) {
|
||||
rotation_90_degrees = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
skew = ! rotation_90_degrees;
|
||||
} else
|
||||
skew = false;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// For parsing a transformation matrix from 3MF / AMF.
|
||||
Transform3d transform3d_from_string(const std::string& transform_str)
|
||||
{
|
||||
|
@ -492,8 +492,8 @@ public:
|
||||
void reset();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void reset_offset() { set_offset(Vec3d::Zero()); }
|
||||
void reset_rotation() { set_rotation(Vec3d::Zero()); }
|
||||
void reset_scaling_factor() { set_scaling_factor(Vec3d::Ones()); }
|
||||
void reset_rotation();
|
||||
void reset_scaling_factor();
|
||||
void reset_mirror() { set_mirror(Vec3d::Ones()); }
|
||||
void reset_skew();
|
||||
|
||||
@ -538,6 +538,27 @@ private:
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
struct TransformationSVD
|
||||
{
|
||||
Matrix3d u = Matrix3d::Identity();
|
||||
Matrix3d s = Matrix3d::Identity();
|
||||
Matrix3d v = Matrix3d::Identity();
|
||||
|
||||
bool mirror{ false };
|
||||
bool scale{ false };
|
||||
bool anisotropic_scale{ false };
|
||||
bool rotation{ false };
|
||||
bool rotation_90_degrees{ false };
|
||||
bool skew{ false };
|
||||
|
||||
explicit TransformationSVD(const Transformation& trafo) : TransformationSVD(trafo.get_matrix()) {}
|
||||
explicit TransformationSVD(const Transform3d& trafo);
|
||||
|
||||
Eigen::DiagonalMatrix<double, 3, 3> mirror_matrix() const { return Eigen::DiagonalMatrix<double, 3, 3>(this->mirror ? -1. : 1., 1., 1.); }
|
||||
};
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// For parsing a transformation matrix from 3MF / AMF.
|
||||
extern Transform3d transform3d_from_string(const std::string& transform_str);
|
||||
|
||||
|
@ -398,7 +398,7 @@ bool inside_convex_polygon(const std::pair<std::vector<Vec2d>, std::vector<Vec2d
|
||||
// At min x.
|
||||
assert(pt.x() == it_bottom->x());
|
||||
assert(pt.x() == it_top->x());
|
||||
assert(it_bottom->y() <= pt.y() <= it_top->y());
|
||||
assert(it_bottom->y() <= pt.y() && pt.y() <= it_top->y());
|
||||
return pt.y() >= it_bottom->y() && pt.y() <= it_top->y();
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ static void connect_layer_slices(
|
||||
const coord_t offset_below,
|
||||
const coord_t offset_above
|
||||
#ifndef NDEBUG
|
||||
, const coord_t offset_end
|
||||
, const coord_t offset_end
|
||||
#endif // NDEBUG
|
||||
)
|
||||
{
|
||||
@ -127,9 +127,7 @@ static void connect_layer_slices(
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
auto assert_intersection_valid = [this](int i, int j) {
|
||||
assert(i != j);
|
||||
if (i > j)
|
||||
std::swap(i, j);
|
||||
assert(i < j);
|
||||
assert(i >= m_offset_below);
|
||||
assert(i < m_offset_above);
|
||||
assert(j >= m_offset_above);
|
||||
@ -140,35 +138,47 @@ static void connect_layer_slices(
|
||||
if (polynode.Contour.size() >= 3) {
|
||||
// If there is an intersection point, it should indicate which contours (one from layer below, the other from layer above) intersect.
|
||||
// Otherwise the contour is fully inside another contour.
|
||||
int32_t i = 0, j = 0;
|
||||
int32_t i = -1, j = -1;
|
||||
for (int icontour = 0; icontour <= polynode.ChildCount(); ++ icontour) {
|
||||
const bool first = icontour == 0;
|
||||
const ClipperLib_Z::Path &contour = first ? polynode.Contour : polynode.Childs[icontour - 1]->Contour;
|
||||
const ClipperLib_Z::Path &contour = icontour == 0 ? polynode.Contour : polynode.Childs[icontour - 1]->Contour;
|
||||
if (contour.size() >= 3) {
|
||||
if (first) {
|
||||
i = contour.front().z();
|
||||
j = i;
|
||||
if (i < 0) {
|
||||
std::tie(i, j) = m_intersections[-i - 1];
|
||||
assert(assert_intersection_valid(i, j));
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
for (const ClipperLib_Z::IntPoint& pt : contour) {
|
||||
for (const ClipperLib_Z::IntPoint &pt : contour) {
|
||||
j = pt.z();
|
||||
if (j < 0) {
|
||||
std::tie(i, j) = m_intersections[-j - 1];
|
||||
const auto &intersection = m_intersections[-j - 1];
|
||||
assert(intersection.first <= intersection.second);
|
||||
if (intersection.second < m_offset_above) {
|
||||
// Ignore intersection of polygons on the 1st layer.
|
||||
assert(intersection.first >= m_offset_below);
|
||||
j = i;
|
||||
} else if (intersection.first >= m_offset_above) {
|
||||
// Ignore intersection of polygons on the 2nd layer
|
||||
assert(intersection.second < m_offset_end);
|
||||
j = i;
|
||||
} else {
|
||||
std::tie(i, j) = m_intersections[-j - 1];
|
||||
assert(assert_intersection_valid(i, j));
|
||||
goto end;
|
||||
}
|
||||
} else if (i == -1) {
|
||||
// First source contour of this expolygon was found.
|
||||
i = j;
|
||||
} else if (i != j) {
|
||||
// Second source contour of this expolygon was found.
|
||||
if (i > j)
|
||||
std::swap(i, j);
|
||||
assert(assert_intersection_valid(i, j));
|
||||
goto end;
|
||||
}
|
||||
else if (i != j)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
bool found = false;
|
||||
if (i == j) {
|
||||
if (i == -1) {
|
||||
// This should not happen. It may only happen if the source contours had just self intersections or intersections with contours at the same layer.
|
||||
assert(false);
|
||||
} else if (i == j) {
|
||||
// The contour is completely inside another contour.
|
||||
Point pt(polynode.Contour.front().x(), polynode.Contour.front().y());
|
||||
if (i < m_offset_above) {
|
||||
@ -202,8 +212,6 @@ static void connect_layer_slices(
|
||||
}
|
||||
} else {
|
||||
assert(assert_intersection_valid(i, j));
|
||||
if (i > j)
|
||||
std::swap(i, j);
|
||||
i -= m_offset_below;
|
||||
j -= m_offset_above;
|
||||
assert(i >= 0 && i < m_below.lslices_ex.size());
|
||||
@ -578,7 +586,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.
|
||||
for (uint32_t iexpoly : fill_expolygons_ranges[islice])
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@ -589,12 +597,12 @@ void Layer::sort_perimeters_into_islands(
|
||||
if (ee.is_collection()) {
|
||||
for (const ExtrusionEntity *ee2 : dynamic_cast<const ExtrusionEntityCollection&>(ee).entities)
|
||||
if (! ee2->role().is_external()) {
|
||||
sample = ee2->first_point();
|
||||
sample = ee2->middle_point();
|
||||
sample_set = true;
|
||||
goto loop_end;
|
||||
}
|
||||
} else if (! ee.role().is_external()) {
|
||||
sample = ee.first_point();
|
||||
sample = ee.middle_point();
|
||||
sample_set = true;
|
||||
break;
|
||||
}
|
||||
@ -603,12 +611,12 @@ void Layer::sort_perimeters_into_islands(
|
||||
if (! sample_set) {
|
||||
if (! extrusions.second.empty()) {
|
||||
// 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;
|
||||
}
|
||||
if (! sample_set && ! extrusions.first.empty()) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@ -835,6 +843,15 @@ void Layer::sort_perimeters_into_islands(
|
||||
d2min = d2;
|
||||
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);
|
||||
insert_into_island(lslice_idx_min, it_source_slice->first);
|
||||
}
|
||||
|
@ -1305,7 +1305,9 @@ void ModelObject::synchronize_model_after_cut()
|
||||
void ModelObject::apply_cut_attributes(ModelObjectCutAttributes attributes)
|
||||
{
|
||||
// we don't save cut information, if result will not contains all parts of initial object
|
||||
if (!attributes.has(ModelObjectCutAttribute::KeepUpper) || !attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
if (!attributes.has(ModelObjectCutAttribute::KeepUpper) ||
|
||||
!attributes.has(ModelObjectCutAttribute::KeepLower) ||
|
||||
attributes.has(ModelObjectCutAttribute::InvalidateCutInfo))
|
||||
return;
|
||||
|
||||
if (cut_id.id().invalid())
|
||||
@ -1352,11 +1354,11 @@ void ModelVolume::apply_tolerance()
|
||||
vol->set_offset(pos);
|
||||
*/
|
||||
// make a "hole" wider
|
||||
sf[X] *= 1. + double(cut_info.radius_tolerance);
|
||||
sf[Y] *= 1. + double(cut_info.radius_tolerance);
|
||||
sf[X] += double(cut_info.radius_tolerance);
|
||||
sf[Y] += double(cut_info.radius_tolerance);
|
||||
|
||||
// make a "hole" dipper
|
||||
sf[Z] *= 1. + double(cut_info.height_tolerance);
|
||||
sf[Z] += double(cut_info.height_tolerance);
|
||||
|
||||
set_scaling_factor(sf);
|
||||
}
|
||||
@ -1425,7 +1427,7 @@ void ModelObject::process_modifier_cut(ModelVolume* volume, const Transform3d& i
|
||||
lower->add_volume(*volume);
|
||||
}
|
||||
|
||||
static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix)
|
||||
static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {})
|
||||
{
|
||||
if (mesh.empty())
|
||||
return;
|
||||
@ -1433,7 +1435,7 @@ static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelV
|
||||
mesh.transform(cut_matrix);
|
||||
ModelVolume* vol = object->add_volume(mesh);
|
||||
|
||||
vol->name = src_volume->name;
|
||||
vol->name = src_volume->name + suffix;
|
||||
// Don't copy the config's ID.
|
||||
vol->config.assign_config(src_volume->config);
|
||||
assert(vol->config.id().valid());
|
||||
@ -1477,6 +1479,12 @@ void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d&
|
||||
|
||||
// Add required cut parts to the objects
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepAsParts)) {
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix, "_A");
|
||||
add_cut_volume(lower_mesh, upper, volume, cut_matrix, "_B");
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper))
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix);
|
||||
|
||||
@ -1560,7 +1568,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
||||
clone_for_cut(&upper);
|
||||
|
||||
ModelObject* lower{ nullptr };
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !attributes.has(ModelObjectCutAttribute::KeepAsParts))
|
||||
clone_for_cut(&lower);
|
||||
|
||||
std::vector<ModelObject*> dowels;
|
||||
@ -1608,34 +1616,40 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
||||
|
||||
ModelObjectPtrs res;
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && !upper->volumes.empty()) {
|
||||
invalidate_translations(upper, instances[instance]);
|
||||
|
||||
reset_instance_transformation(upper, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper),
|
||||
attributes.has(ModelObjectCutAttribute::FlipUpper),
|
||||
local_displace);
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepAsParts) && !upper->volumes.empty()) {
|
||||
reset_instance_transformation(upper, instance, cut_matrix);
|
||||
res.push_back(upper);
|
||||
}
|
||||
else {
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && !upper->volumes.empty()) {
|
||||
invalidate_translations(upper, instances[instance]);
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !lower->volumes.empty()) {
|
||||
invalidate_translations(lower, instances[instance]);
|
||||
reset_instance_transformation(upper, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper),
|
||||
attributes.has(ModelObjectCutAttribute::FlipUpper),
|
||||
local_displace);
|
||||
res.push_back(upper);
|
||||
}
|
||||
|
||||
reset_instance_transformation(lower, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower),
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower) ? true : attributes.has(ModelObjectCutAttribute::FlipLower));
|
||||
res.push_back(lower);
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !lower->volumes.empty()) {
|
||||
invalidate_translations(lower, instances[instance]);
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels) && !dowels.empty()) {
|
||||
for (auto dowel : dowels) {
|
||||
invalidate_translations(dowel, instances[instance]);
|
||||
reset_instance_transformation(lower, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower),
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower) ? true : attributes.has(ModelObjectCutAttribute::FlipLower));
|
||||
res.push_back(lower);
|
||||
}
|
||||
|
||||
reset_instance_transformation(dowel, instance, Transform3d::Identity(), false, false, local_dowels_displace);
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels) && !dowels.empty()) {
|
||||
for (auto dowel : dowels) {
|
||||
invalidate_translations(dowel, instances[instance]);
|
||||
|
||||
local_dowels_displace += dowel->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(-1.5, -1.5, 0.0));
|
||||
dowel->name += "-Dowel-" + dowel->volumes[0]->name;
|
||||
res.push_back(dowel);
|
||||
reset_instance_transformation(dowel, instance, Transform3d::Identity(), false, false, local_dowels_displace);
|
||||
|
||||
local_dowels_displace += dowel->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(-1.5, -1.5, 0.0));
|
||||
dowel->name += "-Dowel-" + dowel->volumes[0]->name;
|
||||
res.push_back(dowel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ enum class ModelVolumeType : int {
|
||||
SUPPORT_ENFORCER,
|
||||
};
|
||||
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels };
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, KeepAsParts, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels, InvalidateCutInfo };
|
||||
using ModelObjectCutAttributes = enum_bitmask<ModelObjectCutAttribute>;
|
||||
ENABLE_ENUM_BITMASK_OPERATORS(ModelObjectCutAttribute);
|
||||
|
||||
@ -385,7 +385,11 @@ public:
|
||||
bool is_mm_painted() const;
|
||||
// Checks if object contains just one volume and it's a text
|
||||
bool is_text() const;
|
||||
|
||||
// This object may have a varying layer height by painting or by a table.
|
||||
// Even if true is returned, the layer height profile may be "flat" with no difference to default layering.
|
||||
bool has_custom_layering() const
|
||||
{ return ! this->layer_config_ranges.empty() || ! this->layer_height_profile.empty(); }
|
||||
|
||||
ModelInstance* add_instance();
|
||||
ModelInstance* add_instance(const ModelInstance &instance);
|
||||
ModelInstance* add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation, const Vec3d &mirror);
|
||||
|
@ -728,6 +728,7 @@ ExtrusionPaths sort_and_connect_extra_perimeters(const std::vector<ExtrusionPath
|
||||
std::vector<ExtrusionPaths> connected_shells;
|
||||
connected_shells.reserve(extra_perims.size());
|
||||
for (const ExtrusionPaths &ps : extra_perims) {
|
||||
// this will also filter away empty paths
|
||||
connected_shells.push_back(reconnect_extrusion_paths(ps, 1.0 * extrusion_spacing));
|
||||
}
|
||||
|
||||
@ -753,7 +754,7 @@ ExtrusionPaths sort_and_connect_extra_perimeters(const std::vector<ExtrusionPath
|
||||
std::unordered_set<Pidx, PidxHash> current_dependencies{};
|
||||
if (shell > 0) {
|
||||
for (const auto &prev_path : dependencies[shell - 1]) {
|
||||
if (paths_touch(get_path(current_path), get_path(prev_path.first), extrusion_spacing * 2.0)) {
|
||||
if (paths_touch(get_path(current_path), get_path(prev_path.first), extrusion_spacing * 1.5f)) {
|
||||
current_dependencies.insert(prev_path.first);
|
||||
};
|
||||
}
|
||||
@ -845,7 +846,18 @@ first_point_found:
|
||||
}
|
||||
}
|
||||
|
||||
ExtrusionPaths reconnected = reconnect_extrusion_paths(sorted_paths, extrusion_spacing * 2.0);
|
||||
ExtrusionPaths reconnected;
|
||||
reconnected.reserve(sorted_paths.size());
|
||||
for (const ExtrusionPath &path : sorted_paths) {
|
||||
if (!reconnected.empty() && (reconnected.back().last_point() - path.first_point()).cast<double>().squaredNorm() <
|
||||
extrusion_spacing * extrusion_spacing * 4.0) {
|
||||
reconnected.back().polyline.points.insert(reconnected.back().polyline.points.end(), path.polyline.points.begin(),
|
||||
path.polyline.points.end());
|
||||
} else {
|
||||
reconnected.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
ExtrusionPaths filtered;
|
||||
filtered.reserve(reconnected.size());
|
||||
for (ExtrusionPath &p : reconnected) {
|
||||
@ -1030,12 +1042,6 @@ std::tuple<std::vector<ExtrusionPaths>, Polygons> generate_extra_perimeters_over
|
||||
break;
|
||||
}
|
||||
}
|
||||
Polylines perimeter = intersection_pl(to_polylines(perimeter_polygon), shrinked_overhang_to_cover);
|
||||
if (!perimeter.empty()) {
|
||||
overhang_region.emplace_back();
|
||||
extrusion_paths_append(overhang_region.back(), perimeter, ExtrusionRole::OverhangPerimeter, overhang_flow.mm3_per_mm(),
|
||||
overhang_flow.width(), overhang_flow.height());
|
||||
}
|
||||
|
||||
perimeter_polygon = expand(perimeter_polygon, 0.5 * overhang_flow.scaled_spacing());
|
||||
perimeter_polygon = union_(perimeter_polygon, anchoring);
|
||||
|
@ -443,6 +443,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"enable_dynamic_overhang_speeds", "dynamic_overhang_speeds", "overhang_overlap_levels",
|
||||
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
|
||||
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",
|
||||
"external_perimeter_acceleration", "top_solid_infill_acceleration", "solid_infill_acceleration",
|
||||
"bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||
"min_skirt_length", "brim_width", "brim_separation", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||
@ -457,7 +458,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
||||
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
|
@ -74,6 +74,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
"duplicate_distance",
|
||||
"end_gcode",
|
||||
"end_filament_gcode",
|
||||
"external_perimeter_acceleration",
|
||||
"extrusion_axis",
|
||||
"extruder_clearance_height",
|
||||
"extruder_clearance_radius",
|
||||
@ -125,10 +126,12 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
"retract_speed",
|
||||
"single_extruder_multi_material_priming",
|
||||
"slowdown_below_layer_time",
|
||||
"solid_infill_acceleration",
|
||||
"standby_temperature_delta",
|
||||
"start_gcode",
|
||||
"start_filament_gcode",
|
||||
"toolchange_gcode",
|
||||
"top_solid_infill_acceleration",
|
||||
"thumbnails",
|
||||
"thumbnails_format",
|
||||
"use_firmware_retraction",
|
||||
@ -474,6 +477,10 @@ std::string Print::validate(std::string* warning) const
|
||||
return L("Some objects are too tall and cannot be printed without extruder collisions.");
|
||||
}
|
||||
|
||||
if (m_config.avoid_crossing_perimeters && m_config.avoid_crossing_curled_overhangs) {
|
||||
return L("Avoid crossing perimeters option and avoid crossing curled overhangs option cannot be both enabled together.");
|
||||
}
|
||||
|
||||
if (m_config.spiral_vase) {
|
||||
size_t total_copies_count = 0;
|
||||
for (const PrintObject *object : m_objects)
|
||||
@ -487,6 +494,47 @@ std::string Print::validate(std::string* warning) const
|
||||
return L("The Spiral Vase option can only be used when printing single material objects.");
|
||||
}
|
||||
|
||||
// Cache of layer height profiles for checking:
|
||||
// 1) Whether all layers are synchronized if printing with wipe tower and / or unsynchronized supports.
|
||||
// 2) Whether layer height is constant for Organic supports.
|
||||
// 3) Whether build volume Z is not violated.
|
||||
std::vector<std::vector<coordf_t>> layer_height_profiles;
|
||||
auto layer_height_profile = [this, &layer_height_profiles](const size_t print_object_idx) -> const std::vector<coordf_t>& {
|
||||
const PrintObject &print_object = *m_objects[print_object_idx];
|
||||
if (layer_height_profiles.empty())
|
||||
layer_height_profiles.assign(m_objects.size(), std::vector<coordf_t>());
|
||||
std::vector<coordf_t> &profile = layer_height_profiles[print_object_idx];
|
||||
if (profile.empty())
|
||||
PrintObject::update_layer_height_profile(*print_object.model_object(), print_object.slicing_parameters(), profile);
|
||||
return profile;
|
||||
};
|
||||
|
||||
// Checks that the print does not exceed the max print height
|
||||
for (size_t print_object_idx = 0; print_object_idx < m_objects.size(); ++ print_object_idx) {
|
||||
const PrintObject &print_object = *m_objects[print_object_idx];
|
||||
//FIXME It is quite expensive to generate object layers just to get the print height!
|
||||
if (auto layers = generate_object_layers(print_object.slicing_parameters(), layer_height_profile(print_object_idx));
|
||||
! layers.empty() && layers.back() > this->config().max_print_height) {
|
||||
return L("The print is taller than the maximum allowed height. You might want to reduce the size of your model"
|
||||
" or change current print settings and retry.");
|
||||
}
|
||||
}
|
||||
|
||||
// Some of the objects has variable layer height applied by painting or by a table.
|
||||
bool has_custom_layering = std::find_if(m_objects.begin(), m_objects.end(),
|
||||
[](const PrintObject *object) { return object->model_object()->has_custom_layering(); })
|
||||
!= m_objects.end();
|
||||
|
||||
// Custom layering is not allowed for tree supports as of now.
|
||||
for (size_t print_object_idx = 0; print_object_idx < m_objects.size(); ++ print_object_idx)
|
||||
if (const PrintObject &print_object = *m_objects[print_object_idx];
|
||||
print_object.has_support_material() && print_object.config().support_material_style.value == smsOrganic &&
|
||||
print_object.model_object()->has_custom_layering()) {
|
||||
if (const std::vector<coordf_t> &layers = layer_height_profile(print_object_idx); ! layers.empty())
|
||||
if (! check_object_layers_fixed(print_object.slicing_parameters(), layers))
|
||||
return L("Variable layer height is not supported with Organic supports.");
|
||||
}
|
||||
|
||||
if (this->has_wipe_tower() && ! m_objects.empty()) {
|
||||
// Make sure all extruders use same diameter filament and have the same nozzle diameter
|
||||
// EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments
|
||||
@ -514,19 +562,8 @@ std::string Print::validate(std::string* warning) const
|
||||
return L("The Wipe Tower is currently not supported for multimaterial sequential prints.");
|
||||
|
||||
if (m_objects.size() > 1) {
|
||||
bool has_custom_layering = false;
|
||||
std::vector<std::vector<coordf_t>> layer_height_profiles;
|
||||
for (const PrintObject *object : m_objects) {
|
||||
has_custom_layering = ! object->model_object()->layer_config_ranges.empty() || ! object->model_object()->layer_height_profile.empty();
|
||||
if (has_custom_layering) {
|
||||
layer_height_profiles.assign(m_objects.size(), std::vector<coordf_t>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
const SlicingParameters &slicing_params0 = m_objects.front()->slicing_parameters();
|
||||
size_t tallest_object_idx = 0;
|
||||
if (has_custom_layering)
|
||||
PrintObject::update_layer_height_profile(*m_objects.front()->model_object(), slicing_params0, layer_height_profiles.front());
|
||||
const SlicingParameters &slicing_params0 = m_objects.front()->slicing_parameters();
|
||||
size_t tallest_object_idx = 0;
|
||||
for (size_t i = 1; i < m_objects.size(); ++ i) {
|
||||
const PrintObject *object = m_objects[i];
|
||||
const SlicingParameters &slicing_params = object->slicing_parameters();
|
||||
@ -541,8 +578,9 @@ std::string Print::validate(std::string* warning) const
|
||||
if (! equal_layering(slicing_params, slicing_params0))
|
||||
return L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
|
||||
if (has_custom_layering) {
|
||||
PrintObject::update_layer_height_profile(*object->model_object(), slicing_params, layer_height_profiles[i]);
|
||||
if (*(layer_height_profiles[i].end()-2) > *(layer_height_profiles[tallest_object_idx].end()-2))
|
||||
auto &lh = layer_height_profile(i);
|
||||
auto &lh_tallest = layer_height_profile(tallest_object_idx);
|
||||
if (*(lh.end()-2) > *(lh_tallest.end()-2))
|
||||
tallest_object_idx = i;
|
||||
}
|
||||
}
|
||||
@ -618,10 +656,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), "
|
||||
"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) {
|
||||
// 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.");
|
||||
} else {
|
||||
// Non-soluble interface
|
||||
@ -1169,7 +1207,7 @@ void Print::alert_when_supports_needed()
|
||||
for (const auto &obj : objects_isssues) {
|
||||
for (const auto &issue : obj.second) {
|
||||
po_by_support_issues[issue].push_back(obj.first);
|
||||
if (issue.first == SupportSpotsGenerator::SupportPointCause::SeparationFromBed){
|
||||
if (issue.first == SupportSpotsGenerator::SupportPointCause::SeparationFromBed && !obj.first->has_brim()){
|
||||
recommend_brim = true;
|
||||
}
|
||||
}
|
||||
@ -1200,7 +1238,9 @@ void Print::alert_when_supports_needed()
|
||||
}
|
||||
}
|
||||
|
||||
message += "\n" + L("Consider enabling supports") + (recommend_brim ? (" " + L("and/or brim")) : "") + ".";
|
||||
bool brim_or_supp = recommend_brim && po_by_support_issues.size() < 2;
|
||||
auto brim_part = " " + (brim_or_supp ? L("or") : L("and")) + " " + L("brim");
|
||||
message += "\n" + L("Consider enabling supports") + (recommend_brim ? brim_part : "") + ".";
|
||||
|
||||
if (objects_isssues.size() > 0) {
|
||||
this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, message);
|
||||
|
@ -243,6 +243,7 @@ PrintConfigDef::PrintConfigDef()
|
||||
assign_printer_technology_to_unknown(this->options, ptFFF);
|
||||
this->init_sla_params();
|
||||
assign_printer_technology_to_unknown(this->options, ptSLA);
|
||||
this->finalize();
|
||||
}
|
||||
|
||||
void PrintConfigDef::init_common_params()
|
||||
@ -252,9 +253,7 @@ void PrintConfigDef::init_common_params()
|
||||
def = this->add("printer_technology", coEnum);
|
||||
def->label = L("Printer technology");
|
||||
def->tooltip = L("Printer technology");
|
||||
def->enum_keys_map = &ConfigOptionEnum<PrinterTechnology>::get_enum_values();
|
||||
def->enum_values.push_back("FFF");
|
||||
def->enum_values.push_back("SLA");
|
||||
def->set_enum<PrinterTechnology>({ "FFF", "SLA" });
|
||||
def->set_default_value(new ConfigOptionEnum<PrinterTechnology>(ptFFF));
|
||||
|
||||
def = this->add("bed_shape", coPoints);
|
||||
@ -293,10 +292,7 @@ void PrintConfigDef::init_common_params()
|
||||
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->mode = comExpert;
|
||||
def->enum_keys_map = &ConfigOptionEnum<GCodeThumbnailsFormat>::get_enum_values();
|
||||
def->enum_values.push_back("PNG");
|
||||
def->enum_values.push_back("JPG");
|
||||
def->enum_values.push_back("QOI");
|
||||
def->set_enum<GCodeThumbnailsFormat>({ "PNG", "JPG", "QOI" });
|
||||
def->set_default_value(new ConfigOptionEnum<GCodeThumbnailsFormat>(GCodeThumbnailsFormat::PNG));
|
||||
|
||||
def = this->add("layer_height", coFloat);
|
||||
@ -338,7 +334,7 @@ void PrintConfigDef::init_common_params()
|
||||
def = this->add("printhost_port", coString);
|
||||
def->label = L("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->cli = ConfigOptionDef::nocli;
|
||||
def->set_default_value(new ConfigOptionString(""));
|
||||
@ -385,11 +381,10 @@ void PrintConfigDef::init_common_params()
|
||||
def = this->add("printhost_authorization_type", coEnum);
|
||||
def->label = L("Authorization Type");
|
||||
// def->tooltip = L("");
|
||||
def->enum_keys_map = &ConfigOptionEnum<AuthorizationType>::get_enum_values();
|
||||
def->enum_values.push_back("key");
|
||||
def->enum_values.push_back("user");
|
||||
def->enum_labels.push_back(L("API key"));
|
||||
def->enum_labels.push_back(L("HTTP digest"));
|
||||
def->set_enum<AuthorizationType>({
|
||||
{ "key", L("API key") },
|
||||
{ "user", L("HTTP digest") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->cli = ConfigOptionDef::nocli;
|
||||
def->set_default_value(new ConfigOptionEnum<AuthorizationType>(atKeyPassword));
|
||||
@ -585,15 +580,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Brim type");
|
||||
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->enum_keys_map = &ConfigOptionEnum<BrimType>::get_enum_values();
|
||||
def->enum_values.emplace_back("no_brim");
|
||||
def->enum_values.emplace_back("outer_only");
|
||||
def->enum_values.emplace_back("inner_only");
|
||||
def->enum_values.emplace_back("outer_and_inner");
|
||||
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->set_enum<BrimType>({
|
||||
{ "no_brim", L("No brim") },
|
||||
{ "outer_only", L("Outer brim only") },
|
||||
{ "inner_only", L("Inner brim only") },
|
||||
{ "outer_and_inner", L("Outer and inner brim") }
|
||||
});
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<BrimType>(btOuterOnly));
|
||||
|
||||
@ -606,14 +598,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0.f));
|
||||
|
||||
def = this->add("clip_multipart_objects", coBool);
|
||||
def->label = L("Clip multi-part objects");
|
||||
def->tooltip = L("When printing multi-material objects, this settings will make Slic3r "
|
||||
"to clip the overlapping object parts one by the other "
|
||||
"(2nd part will be clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc).");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
def = this->add("colorprint_heights", coFloats);
|
||||
def->label = L("Colorprint height");
|
||||
def->tooltip = L("Heights at which a filament change is to occur.");
|
||||
@ -774,8 +758,7 @@ void PrintConfigDef::init_fff_params()
|
||||
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->cli = "top-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
def->set_enum_values({
|
||||
def->set_enum<InfillPattern>({
|
||||
{ "rectilinear", L("Rectilinear") },
|
||||
{ "monotonic", L("Monotonic") },
|
||||
{ "monotoniclines", L("Monotonic Lines") },
|
||||
@ -795,9 +778,7 @@ void PrintConfigDef::init_fff_params()
|
||||
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->cli = "bottom-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
def->enum_values = def_top_fill_pattern->enum_values;
|
||||
def->enum_labels = def_top_fill_pattern->enum_labels;
|
||||
def->enum_def = Slic3r::clonable_ptr<Slic3r::ConfigOptionEnumDef>(def_top_fill_pattern->enum_def->clone());
|
||||
def->aliases = def_top_fill_pattern->aliases;
|
||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipMonotonic));
|
||||
|
||||
@ -851,18 +832,13 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("extruder", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Extruder");
|
||||
def->category = L("Extruders");
|
||||
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.");
|
||||
def->min = 0; // 0 = inherit defaults
|
||||
def->enum_labels.push_back(L("default")); // override label for item 0
|
||||
def->enum_labels.push_back("1");
|
||||
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->set_enum_labels(ConfigOptionDef::GUIType::i_enum_open,
|
||||
{ L("default"), "1", "2", "3", "4", "5" }); // override label for item 0
|
||||
|
||||
def = this->add("extruder_clearance_height", coFloat);
|
||||
def->label = L("Height");
|
||||
@ -1096,29 +1072,29 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("filament_type", coStrings);
|
||||
def->label = L("Filament type");
|
||||
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->enum_values.push_back("PLA");
|
||||
def->enum_values.push_back("PET");
|
||||
def->enum_values.push_back("ABS");
|
||||
def->enum_values.push_back("ASA");
|
||||
def->enum_values.push_back("FLEX");
|
||||
def->enum_values.push_back("HIPS");
|
||||
def->enum_values.push_back("EDGE");
|
||||
def->enum_values.push_back("NGEN");
|
||||
def->enum_values.push_back("PA");
|
||||
def->enum_values.push_back("NYLON");
|
||||
def->enum_values.push_back("PVA");
|
||||
def->enum_values.push_back("PC");
|
||||
def->enum_values.push_back("PP");
|
||||
def->enum_values.push_back("PEI");
|
||||
def->enum_values.push_back("PEEK");
|
||||
def->enum_values.push_back("PEKK");
|
||||
def->enum_values.push_back("POM");
|
||||
def->enum_values.push_back("PSU");
|
||||
def->enum_values.push_back("PVDF");
|
||||
def->enum_values.push_back("SCAFF");
|
||||
|
||||
def->set_enum_values(ConfigOptionDef::GUIType::select_open, {
|
||||
"PLA",
|
||||
"PET",
|
||||
"ABS",
|
||||
"ASA",
|
||||
"FLEX",
|
||||
"HIPS",
|
||||
"EDGE",
|
||||
"NGEN",
|
||||
"PA",
|
||||
"NYLON",
|
||||
"PVA",
|
||||
"PC",
|
||||
"PP",
|
||||
"PEI",
|
||||
"PEEK",
|
||||
"PEKK",
|
||||
"POM",
|
||||
"PSU",
|
||||
"PVDF",
|
||||
"SCAFF"
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionStrings { "PLA" });
|
||||
|
||||
@ -1166,7 +1142,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionFloat(45));
|
||||
|
||||
def = this->add("fill_density", coPercent);
|
||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
||||
def->gui_flags = "show_value";
|
||||
def->label = L("Fill density");
|
||||
def->category = L("Infill");
|
||||
@ -1174,75 +1149,47 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("%");
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
def->enum_values.push_back("0");
|
||||
def->enum_values.push_back("5");
|
||||
def->enum_values.push_back("10");
|
||||
def->enum_values.push_back("15");
|
||||
def->enum_values.push_back("20");
|
||||
def->enum_values.push_back("25");
|
||||
def->enum_values.push_back("30");
|
||||
def->enum_values.push_back("40");
|
||||
def->enum_values.push_back("50");
|
||||
def->enum_values.push_back("60");
|
||||
def->enum_values.push_back("70");
|
||||
def->enum_values.push_back("80");
|
||||
def->enum_values.push_back("90");
|
||||
def->enum_values.push_back("100");
|
||||
def->enum_labels.push_back("0%");
|
||||
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_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||
{ "0", "0%" },
|
||||
{ "5", "5%" },
|
||||
{ "10", "10%" },
|
||||
{ "15", "15%" },
|
||||
{ "20", "20%" },
|
||||
{ "25", "25%" },
|
||||
{ "30", "30%" },
|
||||
{ "40", "40%" },
|
||||
{ "50", "50%" },
|
||||
{ "60", "60%" },
|
||||
{ "70", "70%" },
|
||||
{ "80", "80%" },
|
||||
{ "90", "90%" },
|
||||
{ "100", "100%" }
|
||||
});
|
||||
def->set_default_value(new ConfigOptionPercent(20));
|
||||
|
||||
def = this->add("fill_pattern", coEnum);
|
||||
def->label = L("Fill pattern");
|
||||
def->category = L("Infill");
|
||||
def->tooltip = L("Fill pattern for general low-density infill.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
def->enum_values.push_back("rectilinear");
|
||||
def->enum_values.push_back("alignedrectilinear");
|
||||
def->enum_values.push_back("grid");
|
||||
def->enum_values.push_back("triangles");
|
||||
def->enum_values.push_back("stars");
|
||||
def->enum_values.push_back("cubic");
|
||||
def->enum_values.push_back("line");
|
||||
def->enum_values.push_back("concentric");
|
||||
def->enum_values.push_back("honeycomb");
|
||||
def->enum_values.push_back("3dhoneycomb");
|
||||
def->enum_values.push_back("gyroid");
|
||||
def->enum_values.push_back("hilbertcurve");
|
||||
def->enum_values.push_back("archimedeanchords");
|
||||
def->enum_values.push_back("octagramspiral");
|
||||
def->enum_values.push_back("adaptivecubic");
|
||||
def->enum_values.push_back("supportcubic");
|
||||
def->enum_values.push_back("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_enum<InfillPattern>({
|
||||
{ "rectilinear", L("Rectilinear") },
|
||||
{ "alignedrectilinear", L("Aligned Rectilinear") },
|
||||
{ "grid", L("Grid") },
|
||||
{ "triangles", L("Triangles")},
|
||||
{ "stars", L("Stars")},
|
||||
{ "cubic", L("Cubic")},
|
||||
{ "line", L("Line")},
|
||||
{ "concentric", L("Concentric")},
|
||||
{ "honeycomb", L("Honeycomb")},
|
||||
{ "3dhoneycomb", L("3D Honeycomb")},
|
||||
{ "gyroid", L("Gyroid")},
|
||||
{ "hilbertcurve", L("Hilbert Curve")},
|
||||
{ "archimedeanchords", L("Archimedean Chords")},
|
||||
{ "octagramspiral", L("Octagram Spiral")},
|
||||
{ "adaptivecubic", L("Adaptive Cubic")},
|
||||
{ "supportcubic", L("Support Cubic")},
|
||||
{ "lightning", L("Lightning")}
|
||||
});
|
||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipStars));
|
||||
|
||||
def = this->add("first_layer_acceleration", coFloat);
|
||||
@ -1343,14 +1290,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Fuzzy Skin");
|
||||
def->category = L("Fuzzy Skin");
|
||||
def->tooltip = L("Fuzzy skin type.");
|
||||
|
||||
def->enum_keys_map = &ConfigOptionEnum<FuzzySkinType>::get_enum_values();
|
||||
def->enum_values.push_back("none");
|
||||
def->enum_values.push_back("external");
|
||||
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->set_enum<FuzzySkinType>({
|
||||
{ "none", L("None") },
|
||||
{ "external", L("Outside walls") },
|
||||
{ "all", L("All walls") }
|
||||
});
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<FuzzySkinType>(FuzzySkinType::None));
|
||||
|
||||
@ -1404,31 +1348,20 @@ void PrintConfigDef::init_fff_params()
|
||||
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. "
|
||||
"The \"No extrusion\" flavor prevents PrusaSlicer from exporting any extrusion value at all.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<GCodeFlavor>::get_enum_values();
|
||||
def->enum_values.push_back("reprap");
|
||||
def->enum_values.push_back("reprapfirmware");
|
||||
def->enum_values.push_back("repetier");
|
||||
def->enum_values.push_back("teacup");
|
||||
def->enum_values.push_back("makerware");
|
||||
def->enum_values.push_back("marlin");
|
||||
def->enum_values.push_back("marlin2");
|
||||
def->enum_values.push_back("sailfish");
|
||||
def->enum_values.push_back("mach3");
|
||||
def->enum_values.push_back("machinekit");
|
||||
def->enum_values.push_back("smoothie");
|
||||
def->enum_values.push_back("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->set_enum<GCodeFlavor>({
|
||||
{ "reprap", "RepRap/Sprinter" },
|
||||
{ "reprapfirmware", "RepRapFirmware" },
|
||||
{ "repetier", "Repetier" },
|
||||
{ "teacup", "Teacup" },
|
||||
{ "makerware", "MakerWare (MakerBot)" },
|
||||
{ "marlin", "Marlin (legacy)" },
|
||||
{ "marlin2", "Marlin 2" },
|
||||
{ "sailfish", "Sailfish (MakerBot)" },
|
||||
{ "mach3", "Mach3/LinuxCNC" },
|
||||
{ "machinekit", "Machinekit" },
|
||||
{ "smoothie", "Smoothie" },
|
||||
{ "no-extrusion", L("No extrusion") }
|
||||
});
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRapSprinter));
|
||||
|
||||
@ -1457,12 +1390,31 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("infill_acceleration", coFloat);
|
||||
def->label = L("Infill");
|
||||
def->tooltip = L("This is the acceleration your printer will use for infill. Set zero to disable "
|
||||
"acceleration control for infill.");
|
||||
"acceleration control for infill.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("solid_infill_acceleration", coFloat);
|
||||
def->label = L("Solid infill");
|
||||
def->tooltip = L("This is the acceleration your printer will use for solid infill. Set zero to use "
|
||||
"the value for infill.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("top_solid_infill_acceleration", coFloat);
|
||||
def->label = L("Top solid infill");
|
||||
def->tooltip = L("This is the acceleration your printer will use for top solid infill. Set zero to use "
|
||||
"the value for solid infill.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
|
||||
def = this->add("infill_every_layers", coInt);
|
||||
def->label = L("Combine infill every");
|
||||
def->category = L("Infill");
|
||||
@ -1486,19 +1438,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "infill_extrusion_width";
|
||||
def->max_literal = 1000;
|
||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
||||
def->enum_values.push_back("0");
|
||||
def->enum_values.push_back("1");
|
||||
def->enum_values.push_back("2");
|
||||
def->enum_values.push_back("5");
|
||||
def->enum_values.push_back("10");
|
||||
def->enum_values.push_back("1000");
|
||||
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->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||
{ "0", L("0 (no open anchors)") },
|
||||
{ "1", L("1 mm") },
|
||||
{ "2", L("2 mm") },
|
||||
{ "5", L("5 mm") },
|
||||
{ "10", L("10 mm") },
|
||||
{ "1000", L("1000 (unlimited)") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(600, true));
|
||||
|
||||
@ -1514,14 +1461,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = def_infill_anchor_min->sidetext;
|
||||
def->ratio_over = def_infill_anchor_min->ratio_over;
|
||||
def->max_literal = def_infill_anchor_min->max_literal;
|
||||
def->gui_type = def_infill_anchor_min->gui_type;
|
||||
def->enum_values = def_infill_anchor_min->enum_values;
|
||||
def->enum_labels.push_back(L("0 (not anchored)"));
|
||||
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->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||
{ "0", L("0 (not anchored)") },
|
||||
{ "1", L("1 mm") },
|
||||
{ "2", L("2 mm") },
|
||||
{ "5", L("5 mm") },
|
||||
{ "10", L("10 mm") },
|
||||
{ "1000", L("1000 (unlimited)") }
|
||||
});
|
||||
def->mode = def_infill_anchor_min->mode;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(50, false));
|
||||
|
||||
@ -1625,13 +1572,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Ironing Type");
|
||||
def->category = L("Ironing");
|
||||
def->tooltip = L("Ironing Type");
|
||||
def->enum_keys_map = &ConfigOptionEnum<IroningType>::get_enum_values();
|
||||
def->enum_values.push_back("top");
|
||||
def->enum_values.push_back("topmost");
|
||||
def->enum_values.push_back("solid");
|
||||
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->set_enum<IroningType>({
|
||||
{ "top", L("All top surfaces") },
|
||||
{ "topmost", L("Topmost surface only") },
|
||||
{ "solid", L("All solid surfaces") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<IroningType>(IroningType::TopSurfaces));
|
||||
|
||||
@ -1695,13 +1640,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_label = L("Purpose of Machine Limits");
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = L("How to apply the Machine Limits");
|
||||
def->enum_keys_map = &ConfigOptionEnum<MachineLimitsUsage>::get_enum_values();
|
||||
def->enum_values.push_back("emit_to_gcode");
|
||||
def->enum_values.push_back("time_estimate_only");
|
||||
def->enum_values.push_back("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->set_enum<MachineLimitsUsage>({
|
||||
{ "emit_to_gcode", L("Emit to G-code") },
|
||||
{ "time_estimate_only", L("Use for time estimate") },
|
||||
{ "ignore", L("Ignore") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<MachineLimitsUsage>(MachineLimitsUsage::TimeEstimateOnly));
|
||||
|
||||
@ -1947,23 +1890,16 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Host Type");
|
||||
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain "
|
||||
"the kind of the host.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<PrintHostType>::get_enum_values();
|
||||
def->enum_values.push_back("prusalink");
|
||||
def->enum_values.push_back("prusaconnect");
|
||||
def->enum_values.push_back("octoprint");
|
||||
def->enum_values.push_back("duet");
|
||||
def->enum_values.push_back("flashair");
|
||||
def->enum_values.push_back("astrobox");
|
||||
def->enum_values.push_back("repetier");
|
||||
def->enum_values.push_back("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->set_enum<PrintHostType>({
|
||||
{ "prusalink", "PrusaLink" },
|
||||
{ "prusaconnect", "PrusaConnect" },
|
||||
{ "octoprint", "OctoPrint" },
|
||||
{ "duet", "Duet" },
|
||||
{ "flashair", "FlashAir" },
|
||||
{ "astrobox", "AstroBox" },
|
||||
{ "repetier", "Repetier" },
|
||||
{ "mks", "MKS" }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->cli = ConfigOptionDef::nocli;
|
||||
def->set_default_value(new ConfigOptionEnum<PrintHostType>(htPrusaLink));
|
||||
@ -2025,6 +1961,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("external_perimeter_acceleration", coFloat);
|
||||
def->label = L("External perimeters");
|
||||
def->tooltip = L("This is the acceleration your printer will use for external perimeters. "
|
||||
"Set zero to use the value for perimeters.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("perimeter_extruder", coInt);
|
||||
def->label = L("Perimeter extruder");
|
||||
def->category = L("Extruders");
|
||||
@ -2296,15 +2240,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Seam position");
|
||||
def->category = L("Layers and Perimeters");
|
||||
def->tooltip = L("Position of perimeters starting points.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SeamPosition>::get_enum_values();
|
||||
def->enum_values.push_back("random");
|
||||
def->enum_values.push_back("nearest");
|
||||
def->enum_values.push_back("aligned");
|
||||
def->enum_values.push_back("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->set_enum<SeamPosition>({
|
||||
{ "random", L("Random") },
|
||||
{ "nearest", L("Nearest") },
|
||||
{ "aligned", L("Aligned") },
|
||||
{ "rear", L("Rear") }
|
||||
});
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spAligned));
|
||||
|
||||
@ -2356,13 +2297,11 @@ void PrintConfigDef::init_fff_params()
|
||||
"Enabled = skirt is as tall as the highest printed object.\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.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<DraftShield>::get_enum_values();
|
||||
def->enum_values.push_back("disabled");
|
||||
def->enum_values.push_back("limited");
|
||||
def->enum_values.push_back("enabled");
|
||||
def->enum_labels.push_back(L("Disabled"));
|
||||
def->enum_labels.push_back(L("Limited"));
|
||||
def->enum_labels.push_back(L("Enabled"));
|
||||
def->set_enum<DraftShield>({
|
||||
{ "disabled", L("Disabled") },
|
||||
{ "limited", L("Limited") },
|
||||
{ "enabled", L("Enabled") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<DraftShield>(dsDisabled));
|
||||
|
||||
@ -2579,13 +2518,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Slicing Mode");
|
||||
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->enum_keys_map = &ConfigOptionEnum<SlicingMode>::get_enum_values();
|
||||
def->enum_values.push_back("regular");
|
||||
def->enum_values.push_back("even_odd");
|
||||
def->enum_values.push_back("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->set_enum<SlicingMode>({
|
||||
{ "regular", L("Regular") },
|
||||
{ "even_odd", L("Even-odd") },
|
||||
{ "close_holes", L("Close holes") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
|
||||
|
||||
@ -2634,7 +2571,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("support_material_contact_distance", coFloat);
|
||||
def->gui_type = ConfigOptionDef::GUIType::f_enum_open;
|
||||
def->label = L("Top contact Z distance");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("The vertical distance between object and support material interface. "
|
||||
@ -2642,30 +2578,27 @@ void PrintConfigDef::init_fff_params()
|
||||
"for the first object layer.");
|
||||
def->sidetext = L("mm");
|
||||
// def->min = 0;
|
||||
def->enum_values.push_back("0");
|
||||
def->enum_values.push_back("0.1");
|
||||
def->enum_values.push_back("0.2");
|
||||
def->enum_labels.push_back(L("0 (soluble)"));
|
||||
def->enum_labels.push_back(L("0.1 (detachable)"));
|
||||
def->enum_labels.push_back(L("0.2 (detachable)"));
|
||||
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||
{ "0", L("0 (soluble)") },
|
||||
{ "0.1", L("0.1 (detachable)") },
|
||||
{ "0.2", L("0.2 (detachable)") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0.2));
|
||||
|
||||
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->category = L("Support material");
|
||||
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.");
|
||||
def->sidetext = L("mm");
|
||||
// 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
|
||||
def->enum_labels.push_back(L("Same as top"));
|
||||
def->enum_labels.push_back("0.1");
|
||||
def->enum_labels.push_back("0.2");
|
||||
def->set_enum_values(ConfigOptionDef::GUIType::f_enum_open, {
|
||||
{ "0", L("Same as top") },
|
||||
{ "0.1", "0.1" },
|
||||
{ "0.2", "0.2" }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
@ -2720,36 +2653,35 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionInt(1));
|
||||
|
||||
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->category = L("Support material");
|
||||
def->tooltip = L("Number of interface layers to insert between the object(s) and support material.");
|
||||
def->sidetext = L("layers");
|
||||
def->min = 0;
|
||||
def->enum_values.push_back("0");
|
||||
def->enum_values.push_back("1");
|
||||
def->enum_values.push_back("2");
|
||||
def->enum_values.push_back("3");
|
||||
def->enum_labels.push_back(L("0 (off)"));
|
||||
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->set_enum_values(ConfigOptionDef::GUIType::i_enum_open, {
|
||||
{ "0", L("0 (off)") },
|
||||
{ "1", L("1 (light)") },
|
||||
{ "2", L("2 (default)") },
|
||||
{ "3", L("3 (heavy)") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(3));
|
||||
|
||||
def = this->add("support_material_bottom_interface_layers", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Bottom interface layers");
|
||||
def->category = L("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");
|
||||
def->sidetext = L("layers");
|
||||
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
|
||||
def->enum_labels.push_back(L("Same as top"));
|
||||
append(def->enum_labels, support_material_interface_layers->enum_labels);
|
||||
def->set_enum_values(ConfigOptionDef::GUIType::i_enum_open, {
|
||||
{ "-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->set_default_value(new ConfigOptionInt(-1));
|
||||
|
||||
@ -2787,13 +2719,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Pattern");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Pattern used to generate support material.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialPattern>::get_enum_values();
|
||||
def->enum_values.push_back("rectilinear");
|
||||
def->enum_values.push_back("rectilinear-grid");
|
||||
def->enum_values.push_back("honeycomb");
|
||||
def->enum_labels.push_back(L("Rectilinear"));
|
||||
def->enum_labels.push_back(L("Rectilinear grid"));
|
||||
def->enum_labels.push_back(L("Honeycomb"));
|
||||
def->set_enum<SupportMaterialPattern>({
|
||||
{ "rectilinear", L("Rectilinear") },
|
||||
{ "rectilinear-grid", L("Rectilinear grid") },
|
||||
{ "honeycomb", L("Honeycomb") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear));
|
||||
|
||||
@ -2803,13 +2733,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("Pattern used to generate support material interface. "
|
||||
"Default pattern for non-soluble support interface is Rectilinear, "
|
||||
"while default pattern for soluble support interface is Concentric.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values();
|
||||
def->enum_values.push_back("auto");
|
||||
def->enum_values.push_back("rectilinear");
|
||||
def->enum_values.push_back("concentric");
|
||||
def->enum_labels.push_back(L("Default"));
|
||||
def->enum_labels.push_back(L("Rectilinear"));
|
||||
def->enum_labels.push_back(L("Concentric"));
|
||||
def->set_enum<SupportMaterialInterfacePattern>({
|
||||
{ "auto", L("Default") },
|
||||
{ "rectilinear", L("Rectilinear") },
|
||||
{ "concentric", L("Concentric") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<SupportMaterialInterfacePattern>(smipRectilinear));
|
||||
|
||||
@ -2837,8 +2765,7 @@ void PrintConfigDef::init_fff_params()
|
||||
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 "
|
||||
"object scarring.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialStyle>::get_enum_values();
|
||||
def->set_enum_values({
|
||||
def->set_enum<SupportMaterialStyle>({
|
||||
{ "grid", L("Grid") },
|
||||
{ "snug", L("Snug") },
|
||||
{ "organic", L("Organic") }
|
||||
@ -2878,7 +2805,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
def = this->add("support_tree_angle", coFloat);
|
||||
def->label = L("Tree Support Maximum Branch Angle");
|
||||
def->label = L("Maximum Branch Angle");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("The maximum angle of the branches, when the branches have to avoid the model. "
|
||||
"Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach.");
|
||||
@ -2889,7 +2816,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionFloat(40));
|
||||
|
||||
def = this->add("support_tree_angle_slow", coFloat);
|
||||
def->label = L("Tree Support Preferred Branch Angle");
|
||||
def->label = L("Preferred Branch Angle");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("The preferred angle of the branches, when they do not have to avoid the model. "
|
||||
"Use a lower angle to make them more vertical and more stable. Use a higher angle for branches to merge faster.");
|
||||
@ -2900,18 +2827,18 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionFloat(25));
|
||||
|
||||
def = this->add("support_tree_tip_diameter", coFloat);
|
||||
def->label = L("Tree Support Tip Diameter");
|
||||
def->label = L("Tip Diameter");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("The diameter of the top of the tip of the branches of tree support.");
|
||||
def->tooltip = L("The diameter of the top of the tip of the branches of organic support.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0.8));
|
||||
|
||||
def = this->add("support_tree_branch_diameter", coFloat);
|
||||
def->label = L("Tree Support Branch Diameter");
|
||||
def->label = L("Branch Diameter");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. "
|
||||
def->tooltip = L("The diameter of the thinnest branches of organic support. Thicker branches are more sturdy. "
|
||||
"Branches towards the base will be thicker than this.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
@ -2919,11 +2846,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionFloat(2));
|
||||
|
||||
def = this->add("support_tree_branch_diameter_angle", coFloat);
|
||||
def->label = L("Tree Support Branch Diameter Angle");
|
||||
def->label = L("Branch Diameter Angle");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("The angle of the branches' diameter as they gradually become thicker towards the bottom. "
|
||||
"An angle of 0 will cause the branches to have uniform thickness over their length. "
|
||||
"A bit of an angle can increase stability of the tree support.");
|
||||
"A bit of an angle can increase stability of the organic support.");
|
||||
def->sidetext = L("°");
|
||||
def->min = 0;
|
||||
def->max = 15;
|
||||
@ -2931,7 +2858,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionFloat(5));
|
||||
|
||||
def = this->add("support_tree_top_rate", coPercent);
|
||||
def->label = L("Tree Support Branch Density");
|
||||
def->label = L("Branch Density");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Adjusts the density of the support structure used to generate the tips of the branches. "
|
||||
"A higher value results in better overhangs, but the supports are harder to remove. "
|
||||
@ -3207,11 +3134,10 @@ void PrintConfigDef::init_fff_params()
|
||||
"very thin areas is used gap-fill. "
|
||||
"Arachne engine produces perimeters with variable extrusion width. "
|
||||
"This setting also affects the Concentric infill.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<PerimeterGeneratorType>::get_enum_values();
|
||||
def->enum_values.push_back("classic");
|
||||
def->enum_values.push_back("arachne");
|
||||
def->enum_labels.push_back(L("Classic"));
|
||||
def->enum_labels.push_back(L("Arachne"));
|
||||
def->set_enum<PerimeterGeneratorType>({
|
||||
{ "classic", L("Classic") },
|
||||
{ "arachne", L("Arachne") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Arachne));
|
||||
|
||||
@ -3434,13 +3360,9 @@ void PrintConfigDef::init_sla_support_params(const std::string &prefix)
|
||||
" Can be zig-zag, cross (double zig-zag) or dynamic which"
|
||||
" will automatically switch between the first two depending"
|
||||
" on the distance of the two pillars.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_values();
|
||||
def->enum_keys_map = &ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_values();
|
||||
def->enum_values = ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_names();
|
||||
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->set_enum<SLAPillarConnectionMode>(
|
||||
ConfigOptionEnum<SLAPillarConnectionMode>::get_enum_names(),
|
||||
{ L("Zig-Zag"), L("Cross"), L("Dynamic") });
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum(SLAPillarConnectionMode::dynamic));
|
||||
|
||||
@ -3602,11 +3524,10 @@ void PrintConfigDef::init_sla_params()
|
||||
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"
|
||||
" and the output images will be rotated by 90 degrees.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SLADisplayOrientation>::get_enum_values();
|
||||
def->enum_values.push_back("landscape");
|
||||
def->enum_values.push_back("portrait");
|
||||
def->enum_labels.push_back(L("Landscape"));
|
||||
def->enum_labels.push_back(L("Portrait"));
|
||||
def->set_enum<SLADisplayOrientation>({
|
||||
{ "landscape", L("Landscape") },
|
||||
{ "portrait", L("Portrait") }
|
||||
});
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait));
|
||||
|
||||
@ -3718,13 +3639,9 @@ void PrintConfigDef::init_sla_params()
|
||||
def = this->add("material_type", coString);
|
||||
def->label = 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->enum_values.push_back("Tough");
|
||||
def->enum_values.push_back("Flexible");
|
||||
def->enum_values.push_back("Casting");
|
||||
def->enum_values.push_back("Dental");
|
||||
def->enum_values.push_back("Heat-resistant");
|
||||
def->set_enum_values(ConfigOptionDef::GUIType::select_open,
|
||||
{ "Tough", "Flexible", "Casting", "Dental", "Heat-resistant" });
|
||||
def->set_default_value(new ConfigOptionString("Tough"));
|
||||
|
||||
def = this->add("initial_layer_height", coFloat);
|
||||
@ -3898,12 +3815,10 @@ void PrintConfigDef::init_sla_params()
|
||||
def = this->add("support_tree_type", coEnum);
|
||||
def->label = L("Support tree type");
|
||||
def->tooltip = L("Support tree building strategy");
|
||||
def->enum_keys_map = &ConfigOptionEnum<sla::SupportTreeType>::get_enum_values();
|
||||
def->enum_values = ConfigOptionEnum<sla::SupportTreeType>::get_enum_names();
|
||||
def->enum_labels = ConfigOptionEnum<sla::SupportTreeType>::get_enum_names();
|
||||
def->enum_labels[0] = L("Default");
|
||||
def->enum_labels[1] = L("Branching (experimental)");
|
||||
// TODO: def->enum_labels[2] = L("Organic");
|
||||
def->set_enum<sla::SupportTreeType>(
|
||||
ConfigOptionEnum<sla::SupportTreeType>::get_enum_names(),
|
||||
{ L("Default"), L("Branching (experimental)") });
|
||||
// TODO: def->enum_def->labels[2] = L("Organic");
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum(sla::SupportTreeType::Default));
|
||||
|
||||
@ -4107,13 +4022,11 @@ void PrintConfigDef::init_sla_params()
|
||||
def->tooltip = L(
|
||||
"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.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SLAMaterialSpeed>::get_enum_values();
|
||||
def->enum_values.push_back("slow");
|
||||
def->enum_values.push_back("fast");
|
||||
def->enum_values.push_back("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->set_enum<SLAMaterialSpeed>({
|
||||
{ "slow", L("Slow") },
|
||||
{ "fast", L("Fast") },
|
||||
{ "high_viscosity", L("High viscosity") }
|
||||
});
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<SLAMaterialSpeed>(slamsFast));
|
||||
|
||||
@ -4126,11 +4039,27 @@ void PrintConfigDef::init_sla_params()
|
||||
def->label = L("SLA output precision");
|
||||
def->tooltip = L("Minimum resolution in nanometers");
|
||||
def->sidetext = L("mm");
|
||||
def->min = SCALING_FACTOR;
|
||||
def->min = float(SCALING_FACTOR);
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0.001));
|
||||
}
|
||||
|
||||
// Ignore the following obsolete configuration keys:
|
||||
static std::set<std::string> PrintConfigDef_ignore = {
|
||||
"clip_multipart_objects",
|
||||
"duplicate_x", "duplicate_y", "gcode_arcs", "multiply_x", "multiply_y",
|
||||
"support_material_tool", "acceleration", "adjust_overhang_flow",
|
||||
"standby_temperature", "scale", "rotate", "duplicate", "duplicate_grid",
|
||||
"start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start",
|
||||
"seal_position", "vibration_limit", "bed_size",
|
||||
"print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe",
|
||||
"serial_port", "serial_speed",
|
||||
// Introduced in some PrusaSlicer 2.3.1 alpha, later renamed or removed.
|
||||
"fuzzy_skin_perimeter_mode", "fuzzy_skin_shape",
|
||||
// Introduced in PrusaSlicer 2.3.0-alpha2, later replaced by automatic calculation based on extrusion width.
|
||||
"wall_add_middle_threshold", "wall_split_middle_threshold",
|
||||
};
|
||||
|
||||
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)
|
||||
{
|
||||
// handle legacy options
|
||||
@ -4204,32 +4133,17 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
||||
}
|
||||
}*/
|
||||
|
||||
// Ignore the following obsolete configuration keys:
|
||||
static std::set<std::string> ignore = {
|
||||
"duplicate_x", "duplicate_y", "gcode_arcs", "multiply_x", "multiply_y",
|
||||
"support_material_tool", "acceleration", "adjust_overhang_flow",
|
||||
"standby_temperature", "scale", "rotate", "duplicate", "duplicate_grid",
|
||||
"start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start",
|
||||
"seal_position", "vibration_limit", "bed_size",
|
||||
"print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe",
|
||||
"serial_port", "serial_speed",
|
||||
// Introduced in some PrusaSlicer 2.3.1 alpha, later renamed or removed.
|
||||
"fuzzy_skin_perimeter_mode", "fuzzy_skin_shape",
|
||||
// Introduced in PrusaSlicer 2.3.0-alpha2, later replaced by automatic calculation based on extrusion width.
|
||||
"wall_add_middle_threshold", "wall_split_middle_threshold",
|
||||
};
|
||||
|
||||
// In PrusaSlicer 2.3.0-alpha0 the "monotonous" infill was introduced, which was later renamed to "monotonic".
|
||||
if (value == "monotonous" && (opt_key == "top_fill_pattern" || opt_key == "bottom_fill_pattern" || opt_key == "fill_pattern"))
|
||||
value = "monotonic";
|
||||
|
||||
if (ignore.find(opt_key) != ignore.end()) {
|
||||
opt_key = "";
|
||||
if (PrintConfigDef_ignore.find(opt_key) != PrintConfigDef_ignore.end()) {
|
||||
opt_key = {};
|
||||
return;
|
||||
}
|
||||
|
||||
if (! print_config_def.has(opt_key)) {
|
||||
opt_key = "";
|
||||
opt_key = {};
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4794,13 +4708,11 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||
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 "
|
||||
"bail out or to substitute an unknown value with a default silently or verbosely.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>::get_enum_values();
|
||||
def->enum_values.push_back("disable");
|
||||
def->enum_values.push_back("enable");
|
||||
def->enum_values.push_back("enable_silent");
|
||||
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_enum<ForwardCompatibilitySubstitutionRule>({
|
||||
{ "disable", L("Bail out on unknown configuration values") },
|
||||
{ "enable", L("Enable reading unknown configuration values by verbosely substituting them with defaults.") },
|
||||
{ "enable_silent", L("Enable reading unknown configuration values by silently substituting them with defaults.") }
|
||||
});
|
||||
def->set_default_value(new ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>(ForwardCompatibilitySubstitutionRule::Enable));
|
||||
|
||||
def = this->add("load", coStrings);
|
||||
@ -4818,12 +4730,6 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||
"or an existing PrusaSlicer window is activated. "
|
||||
"Overrides the \"single_instance\" configuration value from application preferences.");
|
||||
|
||||
/*
|
||||
def = this->add("autosave", coString);
|
||||
def->label = L("Autosave");
|
||||
def->tooltip = L("Automatically export current configuration to the specified file.");
|
||||
*/
|
||||
|
||||
def = this->add("datadir", coString);
|
||||
def->label = L("Data directory");
|
||||
def->tooltip = L("Load and store settings at the given directory. This is useful for maintaining different profiles or including configurations from a network storage.");
|
||||
|
@ -487,7 +487,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, brim_separation))
|
||||
((ConfigOptionEnum<BrimType>, brim_type))
|
||||
((ConfigOptionFloat, brim_width))
|
||||
((ConfigOptionBool, clip_multipart_objects))
|
||||
((ConfigOptionBool, dont_support_bridges))
|
||||
((ConfigOptionFloat, elefant_foot_compensation))
|
||||
((ConfigOptionFloatOrPercent, extrusion_width))
|
||||
@ -755,6 +754,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionInts, disable_fan_first_layers))
|
||||
((ConfigOptionEnum<DraftShield>, draft_shield))
|
||||
((ConfigOptionFloat, duplicate_distance))
|
||||
((ConfigOptionFloat, external_perimeter_acceleration))
|
||||
((ConfigOptionFloat, extruder_clearance_height))
|
||||
((ConfigOptionFloat, extruder_clearance_radius))
|
||||
((ConfigOptionStrings, extruder_colour))
|
||||
@ -797,12 +797,14 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionInt, skirt_height))
|
||||
((ConfigOptionInt, skirts))
|
||||
((ConfigOptionInts, slowdown_below_layer_time))
|
||||
((ConfigOptionFloat, solid_infill_acceleration))
|
||||
((ConfigOptionBool, spiral_vase))
|
||||
((ConfigOptionInt, standby_temperature_delta))
|
||||
((ConfigOptionInts, temperature))
|
||||
((ConfigOptionInt, threads))
|
||||
((ConfigOptionPoints, thumbnails))
|
||||
((ConfigOptionEnum<GCodeThumbnailsFormat>, thumbnails_format))
|
||||
((ConfigOptionFloat, top_solid_infill_acceleration))
|
||||
((ConfigOptionBools, wipe))
|
||||
((ConfigOptionBool, wipe_tower))
|
||||
((ConfigOptionFloat, wipe_tower_x))
|
||||
|
@ -620,8 +620,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "slicing_mode") {
|
||||
steps.emplace_back(posSlice);
|
||||
} else if (
|
||||
opt_key == "clip_multipart_objects"
|
||||
|| opt_key == "elefant_foot_compensation"
|
||||
opt_key == "elefant_foot_compensation"
|
||||
|| opt_key == "support_material_contact_distance"
|
||||
|| opt_key == "xy_size_compensation") {
|
||||
steps.emplace_back(posSlice);
|
||||
@ -1792,6 +1791,8 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c
|
||||
// use the constructor because the assignement is crashing on ASAN OsX
|
||||
layer_height_profile = std::vector<coordf_t>(model_object.layer_height_profile.get());
|
||||
// layer_height_profile = model_object.layer_height_profile;
|
||||
// The layer height returned is sampled with high density for the UI layer height painting
|
||||
// and smoothing tool to work.
|
||||
updated = true;
|
||||
}
|
||||
|
||||
@ -1806,6 +1807,7 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c
|
||||
if (layer_height_profile.empty()) {
|
||||
//layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes);
|
||||
layer_height_profile = layer_height_profile_from_ranges(slicing_parameters, model_object.layer_config_ranges);
|
||||
// The layer height profile is already compressed.
|
||||
updated = true;
|
||||
}
|
||||
return updated;
|
||||
|
@ -237,9 +237,6 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
|
||||
const PrintObjectRegions &print_object_regions,
|
||||
const std::vector<float> &zs,
|
||||
std::vector<VolumeSlices> &&volume_slices,
|
||||
// If clipping is disabled, then ExPolygons produced by different volumes will never be merged, thus they will be allowed to overlap.
|
||||
// It is up to the model designer to handle these overlaps.
|
||||
const bool clip_multipart_objects,
|
||||
const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
model_volumes_sort_by_id(model_volumes);
|
||||
@ -308,7 +305,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
|
||||
}
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, zs_complex.size()),
|
||||
[&slices_by_region, &print_object_regions, &zs_complex, &layer_ranges_regions_to_slices, clip_multipart_objects, &throw_on_cancel_callback]
|
||||
[&slices_by_region, &print_object_regions, &zs_complex, &layer_ranges_regions_to_slices, &throw_on_cancel_callback]
|
||||
(const tbb::blocked_range<size_t> &range) {
|
||||
float z = zs_complex[range.begin()].second;
|
||||
auto it_layer_range = layer_range_first(print_object_regions.layer_ranges, z);
|
||||
@ -359,7 +356,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
|
||||
if (next_region_same_modifier)
|
||||
// To be used in the following iteration.
|
||||
temp_slices[idx_region + 1].expolygons = std::move(source);
|
||||
} else if ((region.model_volume->is_model_part() && clip_multipart_objects) || region.model_volume->is_negative_volume()) {
|
||||
} else if (region.model_volume->is_model_part() || region.model_volume->is_negative_volume()) {
|
||||
// Clip every non-zero region preceding it.
|
||||
for (int idx_region2 = 0; idx_region2 < idx_region; ++ idx_region2)
|
||||
if (! temp_slices[idx_region2].expolygons.empty()) {
|
||||
@ -388,10 +385,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
// Don't unite the regions if ! clip_multipart_objects. In that case it is user's responsibility
|
||||
// to handle region overlaps. Indeed, one may intentionally let the regions overlap to produce crossing perimeters
|
||||
// for example.
|
||||
if (merged && clip_multipart_objects)
|
||||
if (merged)
|
||||
expolygons = closing_ex(expolygons, float(scale_(EPSILON)));
|
||||
slices_by_region[temp_slices[i].region_id][z_idx] = std::move(expolygons);
|
||||
i = j;
|
||||
@ -696,7 +690,6 @@ void PrintObject::slice_volumes()
|
||||
slice_volumes_inner(
|
||||
print->config(), this->config(), this->trafo_centered(),
|
||||
this->model_object()->volumes, m_shared_regions->layer_ranges, slice_zs, throw_on_cancel_callback),
|
||||
m_config.clip_multipart_objects,
|
||||
throw_on_cancel_callback);
|
||||
|
||||
for (size_t region_id = 0; region_id < region_slices.size(); ++ region_id) {
|
||||
|
@ -183,32 +183,47 @@ std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||
// 2) Convert the trimmed ranges to a height profile, fill in the undefined intervals between z=0 and z=slicing_params.object_print_z_max()
|
||||
// with slicing_params.layer_height
|
||||
std::vector<coordf_t> layer_height_profile;
|
||||
for (std::vector<std::pair<t_layer_height_range,coordf_t>>::const_iterator it_range = ranges_non_overlapping.begin(); it_range != ranges_non_overlapping.end(); ++ it_range) {
|
||||
coordf_t lo = it_range->first.first;
|
||||
coordf_t hi = it_range->first.second;
|
||||
coordf_t height = it_range->second;
|
||||
coordf_t last_z = layer_height_profile.empty() ? 0. : layer_height_profile[layer_height_profile.size() - 2];
|
||||
if (lo > last_z + EPSILON) {
|
||||
auto last_z = [&layer_height_profile]() {
|
||||
return layer_height_profile.empty() ? 0. : *(layer_height_profile.end() - 2);
|
||||
};
|
||||
auto lh_append = [&layer_height_profile, last_z](coordf_t z, coordf_t layer_height) {
|
||||
if (! layer_height_profile.empty()) {
|
||||
bool last_z_matches = is_approx(*(layer_height_profile.end() - 2), z);
|
||||
bool last_h_matches = is_approx(layer_height_profile.back(), layer_height);
|
||||
if (last_h_matches) {
|
||||
if (last_z_matches) {
|
||||
// Drop a duplicate.
|
||||
return;
|
||||
}
|
||||
if (layer_height_profile.size() >= 4 && is_approx(*(layer_height_profile.end() - 3), layer_height)) {
|
||||
// Third repetition of the same layer_height. Update z of the last entry.
|
||||
*(layer_height_profile.end() - 2) = z;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
layer_height_profile.push_back(z);
|
||||
layer_height_profile.push_back(layer_height);
|
||||
};
|
||||
|
||||
for (const std::pair<t_layer_height_range,coordf_t> &non_overlapping_range : ranges_non_overlapping) {
|
||||
coordf_t lo = non_overlapping_range.first.first;
|
||||
coordf_t hi = non_overlapping_range.first.second;
|
||||
coordf_t height = non_overlapping_range.second;
|
||||
if (coordf_t z = last_z(); lo > z + EPSILON) {
|
||||
// Insert a step of normal layer height.
|
||||
layer_height_profile.push_back(last_z);
|
||||
layer_height_profile.push_back(slicing_params.layer_height);
|
||||
layer_height_profile.push_back(lo);
|
||||
layer_height_profile.push_back(slicing_params.layer_height);
|
||||
lh_append(z, slicing_params.layer_height);
|
||||
lh_append(lo, slicing_params.layer_height);
|
||||
}
|
||||
// Insert a step of the overriden layer height.
|
||||
layer_height_profile.push_back(lo);
|
||||
layer_height_profile.push_back(height);
|
||||
layer_height_profile.push_back(hi);
|
||||
layer_height_profile.push_back(height);
|
||||
lh_append(lo, height);
|
||||
lh_append(hi, height);
|
||||
}
|
||||
|
||||
coordf_t last_z = layer_height_profile.empty() ? 0. : layer_height_profile[layer_height_profile.size() - 2];
|
||||
if (last_z < slicing_params.object_print_z_height()) {
|
||||
if (coordf_t z = last_z(); z < slicing_params.object_print_z_height()) {
|
||||
// Insert a step of normal layer height up to the object top.
|
||||
layer_height_profile.push_back(last_z);
|
||||
layer_height_profile.push_back(slicing_params.layer_height);
|
||||
layer_height_profile.push_back(slicing_params.object_print_z_height());
|
||||
layer_height_profile.push_back(slicing_params.layer_height);
|
||||
lh_append(z, slicing_params.layer_height);
|
||||
lh_append(slicing_params.object_print_z_height(), slicing_params.layer_height);
|
||||
}
|
||||
|
||||
return layer_height_profile;
|
||||
@ -294,7 +309,7 @@ std::vector<double> layer_height_profile_adaptive(const SlicingParameters& slici
|
||||
print_z += height;
|
||||
}
|
||||
|
||||
double z_gap = slicing_params.object_print_z_height() - layer_height_profile[layer_height_profile.size() - 2];
|
||||
double z_gap = slicing_params.object_print_z_height() - *(layer_height_profile.end() - 2);
|
||||
if (z_gap > 0.0)
|
||||
{
|
||||
layer_height_profile.push_back(slicing_params.object_print_z_height());
|
||||
@ -632,6 +647,40 @@ std::vector<coordf_t> generate_object_layers(
|
||||
return out;
|
||||
}
|
||||
|
||||
// Check whether the layer height profile describes a fixed layer height profile.
|
||||
bool check_object_layers_fixed(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layer_height_profile)
|
||||
{
|
||||
assert(layer_height_profile.size() >= 4);
|
||||
assert(layer_height_profile.size() % 2 == 0);
|
||||
assert(layer_height_profile[0] == 0);
|
||||
|
||||
if (layer_height_profile.size() != 4 && layer_height_profile.size() != 8)
|
||||
return false;
|
||||
|
||||
bool fixed_step1 = is_approx(layer_height_profile[1], layer_height_profile[3]);
|
||||
bool fixed_step2 = layer_height_profile.size() == 4 ||
|
||||
(layer_height_profile[2] == layer_height_profile[4] && is_approx(layer_height_profile[5], layer_height_profile[7]));
|
||||
|
||||
if (! fixed_step1 || ! fixed_step2)
|
||||
return false;
|
||||
|
||||
if (layer_height_profile[2] < 0.5 * slicing_params.first_object_layer_height + EPSILON ||
|
||||
! is_approx(layer_height_profile[3], slicing_params.first_object_layer_height))
|
||||
return false;
|
||||
|
||||
double z_max = layer_height_profile[layer_height_profile.size() - 2];
|
||||
double z_2nd = slicing_params.first_object_layer_height + 0.5 * slicing_params.layer_height;
|
||||
if (z_2nd > z_max)
|
||||
return true;
|
||||
if (z_2nd < *(layer_height_profile.end() - 4) + EPSILON ||
|
||||
! is_approx(layer_height_profile.back(), slicing_params.layer_height))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int generate_layer_height_texture(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layers,
|
||||
|
@ -129,11 +129,11 @@ inline bool equal_layering(const SlicingParameters &sp1, const SlicingParameters
|
||||
typedef std::pair<coordf_t,coordf_t> t_layer_height_range;
|
||||
typedef std::map<t_layer_height_range, ModelConfig> t_layer_config_ranges;
|
||||
|
||||
extern std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||
std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||
const SlicingParameters &slicing_params,
|
||||
const t_layer_config_ranges &layer_config_ranges);
|
||||
|
||||
extern std::vector<double> layer_height_profile_adaptive(
|
||||
std::vector<double> layer_height_profile_adaptive(
|
||||
const SlicingParameters& slicing_params,
|
||||
const ModelObject& object, float quality_factor);
|
||||
|
||||
@ -146,7 +146,7 @@ struct HeightProfileSmoothingParams
|
||||
HeightProfileSmoothingParams(unsigned int radius, bool keep_min) : radius(radius), keep_min(keep_min) {}
|
||||
};
|
||||
|
||||
extern std::vector<double> smooth_height_profile(
|
||||
std::vector<double> smooth_height_profile(
|
||||
const std::vector<double>& profile, const SlicingParameters& slicing_params,
|
||||
const HeightProfileSmoothingParams& smoothing_params);
|
||||
|
||||
@ -157,7 +157,7 @@ enum LayerHeightEditActionType : unsigned int {
|
||||
LAYER_HEIGHT_EDIT_ACTION_SMOOTH = 3
|
||||
};
|
||||
|
||||
extern void adjust_layer_height_profile(
|
||||
void adjust_layer_height_profile(
|
||||
const SlicingParameters &slicing_params,
|
||||
std::vector<coordf_t> &layer_height_profile,
|
||||
coordf_t z,
|
||||
@ -167,14 +167,19 @@ extern void adjust_layer_height_profile(
|
||||
|
||||
// Produce object layers as pairs of low / high layer boundaries, stored into a linear vector.
|
||||
// The object layers are based at z=0, ignoring the raft layers.
|
||||
extern std::vector<coordf_t> generate_object_layers(
|
||||
std::vector<coordf_t> generate_object_layers(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layer_height_profile);
|
||||
|
||||
// Check whether the layer height profile describes a fixed layer height profile.
|
||||
bool check_object_layers_fixed(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layer_height_profile);
|
||||
|
||||
// Produce a 1D texture packed into a 2D texture describing in the RGBA format
|
||||
// the planned object layers.
|
||||
// Returns number of cells used by the texture of the 0th LOD level.
|
||||
extern int generate_layer_height_texture(
|
||||
int generate_layer_height_texture(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layers,
|
||||
void *data, int rows, int cols, bool level_of_detail_2nd_level);
|
||||
|
@ -1260,87 +1260,86 @@ namespace SupportMaterialInternal {
|
||||
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_bridges_from_contacts(
|
||||
const PrintConfig &print_config,
|
||||
const Layer &lower_layer,
|
||||
const Polygons &lower_layer_polygons,
|
||||
const LayerRegion &layerm,
|
||||
float fw,
|
||||
Polygons &contact_polygons)
|
||||
void remove_bridges_from_contacts(
|
||||
const PrintConfig &print_config,
|
||||
const Layer &lower_layer,
|
||||
const LayerRegion &layerm,
|
||||
float fw,
|
||||
Polygons &contact_polygons)
|
||||
{
|
||||
// compute the area of bridging perimeters
|
||||
Polygons bridges;
|
||||
{
|
||||
// compute the area of bridging perimeters
|
||||
Polygons bridges;
|
||||
{
|
||||
// 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,
|
||||
//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))),
|
||||
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
// Collect perimeters of this layer.
|
||||
//FIXME split_at_first_point() could split a bridge mid-way
|
||||
#if 0
|
||||
Polylines overhang_perimeters = layerm.perimeters.as_polylines();
|
||||
// workaround for Clipper bug, see Slic3r::Polygon::clip_as_polyline()
|
||||
for (Polyline &polyline : overhang_perimeters)
|
||||
polyline.points[0].x += 1;
|
||||
// Trim the perimeters of this layer by the lower layer to get the unsupported pieces of perimeters.
|
||||
overhang_perimeters = diff_pl(overhang_perimeters, lower_grown_slices);
|
||||
#else
|
||||
Polylines overhang_perimeters = diff_pl(layerm.perimeters().as_polylines(), lower_grown_slices);
|
||||
#endif
|
||||
|
||||
// only consider straight overhangs
|
||||
// only consider overhangs having endpoints inside layer's slices
|
||||
// convert bridging polylines into polygons by inflating them with their thickness
|
||||
// since we're dealing with bridges, we can't assume width is larger than spacing,
|
||||
// so we take the largest value and also apply safety offset to be ensure no gaps
|
||||
// are left in between
|
||||
Flow perimeter_bridge_flow = layerm.bridging_flow(frPerimeter);
|
||||
//FIXME one may want to use a maximum of bridging flow width and normal flow width, as the perimeters are calculated using the normal flow
|
||||
// and then turned to bridging flow, thus their centerlines are derived from non-bridging flow and expanding them by a bridging flow
|
||||
// may not expand them to the edge of their respective islands.
|
||||
const float w = float(0.5 * std::max(perimeter_bridge_flow.scaled_width(), perimeter_bridge_flow.scaled_spacing())) + scaled<float>(0.001);
|
||||
for (Polyline &polyline : overhang_perimeters)
|
||||
if (polyline.is_straight()) {
|
||||
// This is a bridge
|
||||
polyline.extend_start(fw);
|
||||
polyline.extend_end(fw);
|
||||
// Is the straight perimeter segment supported at both sides?
|
||||
Point pts[2] = { polyline.first_point(), polyline.last_point() };
|
||||
bool supported[2] = { false, false };
|
||||
for (size_t i = 0; i < lower_layer.lslices.size() && ! (supported[0] && supported[1]); ++ i)
|
||||
for (int j = 0; j < 2; ++ j)
|
||||
if (! supported[j] && lower_layer.lslices_ex[i].bbox.contains(pts[j]) && lower_layer.lslices[i].contains(pts[j]))
|
||||
supported[j] = true;
|
||||
if (supported[0] && supported[1])
|
||||
// Offset a polyline into a thick line.
|
||||
polygons_append(bridges, offset(polyline, w));
|
||||
}
|
||||
bridges = union_(bridges);
|
||||
}
|
||||
// remove the entire bridges and only support the unsupported edges
|
||||
//FIXME the brided regions are already collected as layerm.bridged. Use it?
|
||||
for (const Surface &surface : layerm.fill_surfaces())
|
||||
if (surface.surface_type == stBottomBridge && surface.bridge_angle >= 0.0)
|
||||
polygons_append(bridges, surface.expolygon);
|
||||
//FIXME add the gap filled areas. Extrude the gaps with a bridge flow?
|
||||
// Remove the unsupported ends of the bridges from the bridged areas.
|
||||
//FIXME add supports at regular intervals to support long bridges!
|
||||
bridges = diff(bridges,
|
||||
// Offset unsupported edges into polygons.
|
||||
offset(layerm.unsupported_bridge_edges(), scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||
// Remove bridged areas from the supported areas.
|
||||
contact_polygons = diff(contact_polygons, bridges, ApplySafetyOffset::Yes);
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
static int iRun = 0;
|
||||
SVG::export_expolygons(debug_out_path("support-top-contacts-remove-bridges-run%d.svg", iRun ++),
|
||||
{ { { union_ex(offset(layerm.unsupported_bridge_edges(), scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS)) }, { "unsupported_bridge_edges", "orange", 0.5f } },
|
||||
{ { union_ex(contact_polygons) }, { "contact_polygons", "blue", 0.5f } },
|
||||
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
||||
#endif /* SLIC3R_DEBUG */
|
||||
// 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.lslices,
|
||||
//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))),
|
||||
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
// Collect perimeters of this layer.
|
||||
//FIXME split_at_first_point() could split a bridge mid-way
|
||||
#if 0
|
||||
Polylines overhang_perimeters = layerm.perimeters.as_polylines();
|
||||
// workaround for Clipper bug, see Slic3r::Polygon::clip_as_polyline()
|
||||
for (Polyline &polyline : overhang_perimeters)
|
||||
polyline.points[0].x += 1;
|
||||
// Trim the perimeters of this layer by the lower layer to get the unsupported pieces of perimeters.
|
||||
overhang_perimeters = diff_pl(overhang_perimeters, lower_grown_slices);
|
||||
#else
|
||||
Polylines overhang_perimeters = diff_pl(layerm.perimeters().as_polylines(), lower_grown_slices);
|
||||
#endif
|
||||
|
||||
// only consider straight overhangs
|
||||
// only consider overhangs having endpoints inside layer's slices
|
||||
// convert bridging polylines into polygons by inflating them with their thickness
|
||||
// since we're dealing with bridges, we can't assume width is larger than spacing,
|
||||
// so we take the largest value and also apply safety offset to be ensure no gaps
|
||||
// are left in between
|
||||
Flow perimeter_bridge_flow = layerm.bridging_flow(frPerimeter);
|
||||
//FIXME one may want to use a maximum of bridging flow width and normal flow width, as the perimeters are calculated using the normal flow
|
||||
// and then turned to bridging flow, thus their centerlines are derived from non-bridging flow and expanding them by a bridging flow
|
||||
// may not expand them to the edge of their respective islands.
|
||||
const float w = float(0.5 * std::max(perimeter_bridge_flow.scaled_width(), perimeter_bridge_flow.scaled_spacing())) + scaled<float>(0.001);
|
||||
for (Polyline &polyline : overhang_perimeters)
|
||||
if (polyline.is_straight()) {
|
||||
// This is a bridge
|
||||
polyline.extend_start(fw);
|
||||
polyline.extend_end(fw);
|
||||
// Is the straight perimeter segment supported at both sides?
|
||||
Point pts[2] = { polyline.first_point(), polyline.last_point() };
|
||||
bool supported[2] = { false, false };
|
||||
for (size_t i = 0; i < lower_layer.lslices.size() && ! (supported[0] && supported[1]); ++ i)
|
||||
for (int j = 0; j < 2; ++ j)
|
||||
if (! supported[j] && lower_layer.lslices_ex[i].bbox.contains(pts[j]) && lower_layer.lslices[i].contains(pts[j]))
|
||||
supported[j] = true;
|
||||
if (supported[0] && supported[1])
|
||||
// Offset a polyline into a thick line.
|
||||
polygons_append(bridges, offset(polyline, w));
|
||||
}
|
||||
bridges = union_(bridges);
|
||||
}
|
||||
// remove the entire bridges and only support the unsupported edges
|
||||
//FIXME the brided regions are already collected as layerm.bridged. Use it?
|
||||
for (const Surface &surface : layerm.fill_surfaces())
|
||||
if (surface.surface_type == stBottomBridge && surface.bridge_angle >= 0.0)
|
||||
polygons_append(bridges, surface.expolygon);
|
||||
//FIXME add the gap filled areas. Extrude the gaps with a bridge flow?
|
||||
// Remove the unsupported ends of the bridges from the bridged areas.
|
||||
//FIXME add supports at regular intervals to support long bridges!
|
||||
bridges = diff(bridges,
|
||||
// Offset unsupported edges into polygons.
|
||||
offset(layerm.unsupported_bridge_edges(), scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||
// Remove bridged areas from the supported areas.
|
||||
contact_polygons = diff(contact_polygons, bridges, ApplySafetyOffset::Yes);
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
static int iRun = 0;
|
||||
SVG::export_expolygons(debug_out_path("support-top-contacts-remove-bridges-run%d.svg", iRun ++),
|
||||
{ { { union_ex(offset(layerm.unsupported_bridge_edges(), scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS)) }, { "unsupported_bridge_edges", "orange", 0.5f } },
|
||||
{ { union_ex(contact_polygons) }, { "contact_polygons", "blue", 0.5f } },
|
||||
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
||||
#endif /* SLIC3R_DEBUG */
|
||||
}
|
||||
|
||||
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)
|
||||
//FIXME Expensive, potentially not precise enough. Misses gap fill extrusions, which bridge.
|
||||
SupportMaterialInternal::remove_bridges_from_contacts(
|
||||
print_config, lower_layer, lower_layer_polygons, *layerm, fw, diff_polygons);
|
||||
remove_bridges_from_contacts(print_config, lower_layer, *layerm, fw, diff_polygons);
|
||||
|
||||
if (diff_polygons.empty())
|
||||
continue;
|
||||
@ -3246,6 +3244,10 @@ static Polylines draw_perimeters(const ExPolygon &expoly, double clip_length)
|
||||
for (size_t i = 0; i <= expoly.holes.size(); ++ i) {
|
||||
Polyline pl(i == 0 ? expoly.contour.points : expoly.holes[i - 1].points);
|
||||
pl.points.emplace_back(pl.points.front());
|
||||
if (i > 0)
|
||||
// It is a hole, reverse it.
|
||||
pl.reverse();
|
||||
// so that all contours are CCW oriented.
|
||||
pl.clip_end(clip_length);
|
||||
polylines.emplace_back(std::move(pl));
|
||||
}
|
||||
@ -3351,13 +3353,17 @@ static inline void tree_supports_generate_paths(
|
||||
const double anchor_length = spacing * 6.;
|
||||
ClipperLib_Z::Paths anchor_candidates;
|
||||
for (ExPolygon& expoly : closing_ex(polygons, float(SCALED_EPSILON), float(SCALED_EPSILON + 0.5 * flow.scaled_width()))) {
|
||||
std::unique_ptr<ExtrusionEntityCollection> eec;
|
||||
double area = expoly.area();
|
||||
if (area > sqr(scaled<double>(5.))) {
|
||||
eec = std::make_unique<ExtrusionEntityCollection>();
|
||||
// Don't reoder internal / external loops of the same island, always start with the internal loop.
|
||||
eec->no_sort = true;
|
||||
// Make the tree branch stable by adding another perimeter.
|
||||
ExPolygons level2 = offset2_ex({ expoly }, -1.5 * flow.scaled_width(), 0.5 * flow.scaled_width());
|
||||
if (level2.size() == 1) {
|
||||
Polylines polylines;
|
||||
extrusion_entities_append_paths(dst, draw_perimeters(expoly, clip_length), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
||||
extrusion_entities_append_paths(eec->entities, draw_perimeters(expoly, clip_length), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
||||
// Disable reversal of the path, always start with the anchor, always print CCW.
|
||||
false);
|
||||
expoly = level2.front();
|
||||
@ -3369,20 +3375,21 @@ static inline void tree_supports_generate_paths(
|
||||
// The anchor candidate points are annotated with an index of the source contour or with -1 if on intersection.
|
||||
anchor_candidates.clear();
|
||||
shrink_expolygon_with_contour_idx(expoly, flow.scaled_width(), DefaultJoinType, 1.2, anchor_candidates);
|
||||
// Orient all contours CCW.
|
||||
// Orient all contours CW.
|
||||
for (auto &path : anchor_candidates)
|
||||
if (ClipperLib_Z::Area(path) < 0)
|
||||
if (ClipperLib_Z::Area(path) > 0)
|
||||
std::reverse(path.begin(), path.end());
|
||||
|
||||
// Draw the perimeters.
|
||||
Polylines polylines;
|
||||
polylines.reserve(expoly.holes.size() + 1);
|
||||
for (size_t idx_loop = 0; idx_loop <= expoly.holes.size(); ++ idx_loop) {
|
||||
for (size_t idx_loop = 0; idx_loop < expoly.num_contours(); ++ idx_loop) {
|
||||
// Open the loop with a seam.
|
||||
const Polygon &loop = idx_loop == 0 ? expoly.contour : expoly.holes[idx_loop - 1];
|
||||
const Polygon &loop = expoly.contour_or_hole(idx_loop);
|
||||
Polyline pl(loop.points);
|
||||
// Orient all contours CCW.
|
||||
if (loop.area() < 0)
|
||||
// Orient all contours CW, because the anchor will be added to the end of polyline while we want to start a loop with the anchor.
|
||||
if (idx_loop == 0)
|
||||
// It is an outer contour.
|
||||
pl.reverse();
|
||||
pl.points.emplace_back(pl.points.front());
|
||||
pl.clip_end(clip_length);
|
||||
@ -3421,7 +3428,7 @@ static inline void tree_supports_generate_paths(
|
||||
}
|
||||
if (d2min < sqr(flow.scaled_width() * 3.)) {
|
||||
// Try to cut an anchor from the closest_contour.
|
||||
// Both closest_contour and pl are CCW oriented.
|
||||
// Both closest_contour and pl are CW oriented.
|
||||
pl.points.emplace_back(closest_point.cast<coord_t>());
|
||||
const ClipperLib_Z::Path &path = *closest_contour;
|
||||
double remaining_length = anchor_length - (seam_pt - closest_point).norm();
|
||||
@ -3460,9 +3467,15 @@ static inline void tree_supports_generate_paths(
|
||||
pl.reverse();
|
||||
polylines.emplace_back(std::move(pl));
|
||||
}
|
||||
extrusion_entities_append_paths(dst, polylines, ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
||||
|
||||
ExtrusionEntitiesPtr &out = eec ? eec->entities : dst;
|
||||
extrusion_entities_append_paths(out, std::move(polylines), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
||||
// Disable reversal of the path, always start with the anchor, always print CCW.
|
||||
false);
|
||||
if (eec) {
|
||||
std::reverse(eec->entities.begin(), eec->entities.end());
|
||||
dst.emplace_back(eec.release());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,15 @@ struct SupportParameters {
|
||||
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
|
||||
// in case there is no raft layer to improve support adhesion.
|
||||
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;
|
||||
|
||||
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) {
|
||||
unchecked_dist += line.len;
|
||||
} else {
|
||||
@ -1077,14 +1077,14 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width,
|
||||
}
|
||||
|
||||
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)});
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
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);
|
||||
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) {
|
||||
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)});
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
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);
|
||||
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 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 support_points_interface_radius = 1.5f; // mm
|
||||
|
@ -191,6 +191,26 @@ std::optional<std::string> get_current_thread_name()
|
||||
|
||||
#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.
|
||||
// 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()
|
||||
@ -249,7 +269,8 @@ void set_current_thread_qos()
|
||||
#ifdef __APPLE__
|
||||
// OSX specific: Set Quality of Service to "user initiated", so that the threads will be scheduled to high performance
|
||||
// cores if available.
|
||||
pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0);
|
||||
// With QOS_CLASS_USER_INITIATED the worker threads drop priority once slicer loses user focus.
|
||||
pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
|
||||
#endif // __APPLE__
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
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
|
||||
// cores if available.
|
||||
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();
|
||||
|
||||
// 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);
|
||||
|
||||
// Calculate maximum external perimeter width over all printing regions, taking into account the default layer height.
|
||||
@ -505,7 +505,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
// 1) Calculate offsets of collision areas in parallel.
|
||||
std::vector<Polygons> collision_areas_offsetted(max_required_layer + 1 - min_layer_bottom);
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_bottom, max_required_layer + 1),
|
||||
[&outlines, &machine_border = m_machine_border, offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel]
|
||||
[&outlines, &machine_border = std::as_const(m_machine_border), offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel]
|
||||
(const tbb::blocked_range<LayerIndex> &range) {
|
||||
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) {
|
||||
Polygons collision_areas = machine_border;
|
||||
@ -520,14 +520,54 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
// 2) Sum over top / bottom ranges.
|
||||
const bool last = outline_idx == layer_outline_indices.size();
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_last + 1, max_layer_idx + 1),
|
||||
[&collision_areas_offsetted, &anti_overhang = m_anti_overhang, min_layer_bottom, radius, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel]
|
||||
[&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, min_layer_bottom, radius,
|
||||
xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel]
|
||||
(const tbb::blocked_range<LayerIndex>& range) {
|
||||
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) {
|
||||
Polygons collisions;
|
||||
for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) {
|
||||
int j = layer_idx + i - min_layer_bottom;
|
||||
if (j >= 0 && j < int(collision_areas_offsetted.size()))
|
||||
if (j >= 0 && j < int(collision_areas_offsetted.size()) && i <= 0)
|
||||
append(collisions, collision_areas_offsetted[j]);
|
||||
else if (j >= 0 && layer_idx + i < int(outlines.size()) && i > 0) {
|
||||
Polygons collision_areas_original = machine_border;
|
||||
append(collision_areas_original, outlines[layer_idx + i]);
|
||||
|
||||
// If just the collision (including the xy distance) of the layers above is accumulated, it leads to the
|
||||
// following issue:
|
||||
// Example: assuming the z distance is 2 layer
|
||||
// + = xy_distance
|
||||
// - = model
|
||||
// o = overhang of the area two layers above that should result in tips on this layer
|
||||
//
|
||||
// +-----+
|
||||
// +-----+
|
||||
// +-----+
|
||||
// o +-----+
|
||||
// If just the collision above is accumulated the overhang will get overwritten by the xy_distance of the
|
||||
// layer below the overhang...
|
||||
//
|
||||
// This only causes issues if the overhang area is thinner than xy_distance
|
||||
// Just accumulating areas of the model above without the xy distance is also problematic, as then support
|
||||
// may get closer to the model (on the diagonal downwards) than the user intended. Example (s = support):
|
||||
// +-----+
|
||||
// +-----+
|
||||
// +-----+
|
||||
// s+-----+
|
||||
|
||||
// technically the calculation below is off by one layer, as the actual distance between plastic one layer
|
||||
// down is 0 not layer height, as this layer is filled with said plastic. But otherwise a part of the
|
||||
// overhang that is expected to be supported is overwritten by the remaining part of the xy distance of the
|
||||
// layer below the to be supported area.
|
||||
coord_t required_range_x =
|
||||
(xy_distance - ((i - (z_distance_top_layers == 1 ? 0.5 : 0)) * xy_distance / z_distance_top_layers));
|
||||
// the conditional -0.5 ensures that plastic can never touch on the diagonal
|
||||
// downward when the z_distance_top_layers = 1. It is assumed to be better to
|
||||
// not support an overhang<90 degree than to risk fusing to it.
|
||||
|
||||
collision_areas_original = offset(union_ex(collision_areas_original), radius + required_range_x, ClipperLib::jtMiter, 1.2);
|
||||
append(collisions, collision_areas_original);
|
||||
}
|
||||
}
|
||||
collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions);
|
||||
auto &dst = data[layer_idx - (min_layer_last + 1)];
|
||||
@ -644,7 +684,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector<RadiusLayerPair> &ke
|
||||
BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?";
|
||||
continue;
|
||||
}
|
||||
if (! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta)
|
||||
if ((task.to_model ? to_model : to_build_plate) &&
|
||||
(! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta))
|
||||
avoidance_tasks.emplace_back(task);
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
||||
const PrintObjectConfig &object_config = print_object.config();
|
||||
#endif // NDEBUG
|
||||
// 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);
|
||||
|
||||
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{});
|
||||
|
||||
const PrintConfig &print_config = print_object.print()->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;
|
||||
std::vector<Polygons> enforcers_layers{ print_object.slice_support_enforcers() };
|
||||
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!
|
||||
auto enforcer_overhang_offset = scaled<double>(config.support_tree_tip_diameter.value);
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(1, out.size()),
|
||||
[&print_object, &enforcers_layers, &blockers_layers, support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, &throw_on_cancel, &out]
|
||||
size_t num_overhang_layers = support_auto ? out.size() : std::max(size_t(support_enforce_layers), enforcers_layers.size());
|
||||
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) {
|
||||
for (LayerIndex layer_id = range.begin(); layer_id < range.end(); ++ 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()))
|
||||
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");
|
||||
if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) {
|
||||
@ -488,15 +496,15 @@ static std::optional<std::pair<Point, size_t>> polyline_sample_next_point_at_dis
|
||||
Vec2d xf = p0f - foot_pt;
|
||||
// Squared distance of "start_pt" from the ray (p0, p1).
|
||||
double l2_from_line = xf.squaredNorm();
|
||||
double det = dist2 - l2_from_line;
|
||||
|
||||
if (det > - SCALED_EPSILON) {
|
||||
// Squared distance of an intersection point of a circle with center at the foot point.
|
||||
if (double l2_intersection = dist2 - l2_from_line;
|
||||
l2_intersection > - SCALED_EPSILON) {
|
||||
// The ray (p0, p1) touches or intersects a circle centered at "start_pt" with radius "dist".
|
||||
// Distance of the circle intersection point from the foot point.
|
||||
double dist_circle_intersection = std::sqrt(std::max(0., det));
|
||||
if ((v - foot_pt).cast<double>().norm() > dist_circle_intersection) {
|
||||
l2_intersection = std::max(l2_intersection, 0.);
|
||||
if ((v - foot_pt).cast<double>().squaredNorm() >= l2_intersection) {
|
||||
// Intersection of the circle with the segment (p0, p1) is on the right side (close to p1) from the foot point.
|
||||
Point p = p0 + (foot_pt + v * (dist_circle_intersection / sqrt(l2v))).cast<coord_t>();
|
||||
Point p = p0 + (foot_pt + v * sqrt(l2_intersection / l2v)).cast<coord_t>();
|
||||
validate_range(p);
|
||||
return std::pair<Point, size_t>{ p, i - 1 };
|
||||
}
|
||||
@ -908,7 +916,7 @@ static void generate_initial_areas(
|
||||
//FIXME Vojtech: This is not sufficient for support enforcers to work.
|
||||
//FIXME There is no account for the support overhang angle.
|
||||
//FIXME There is no account for the width of the collision regions.
|
||||
const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0)
|
||||
const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width / 2) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0)
|
||||
//FIXME this is a heuristic value for support enforcers to work.
|
||||
// + 10 * mesh_config.support_line_width;
|
||||
;
|
||||
@ -923,7 +931,9 @@ static void generate_initial_areas(
|
||||
// does not turn valid in double the amount of layers a slope of support angle would take to travel xy_distance, nothing reasonable will come from it.
|
||||
// The 2*z_distance_delta is only a catch for when the support angle is very high.
|
||||
// Used only if not min_xy_dist.
|
||||
const coord_t max_overhang_insert_lag = std::max<coord_t>(round_up_divide(mesh_config.xy_distance, max_overhang_speed / 2), 2 * mesh_config.z_distance_top_layers);
|
||||
const coord_t max_overhang_insert_lag = mesh_config.z_distance_top_layers > 0 ?
|
||||
std::max<coord_t>(round_up_divide(mesh_config.xy_distance, max_overhang_speed / 2), 2 * mesh_config.z_distance_top_layers) :
|
||||
0;
|
||||
|
||||
//FIXME
|
||||
size_t num_support_layers = print_object.layer_count();
|
||||
@ -1069,9 +1079,8 @@ static void generate_initial_areas(
|
||||
Polygons overhang_regular;
|
||||
{
|
||||
const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta];
|
||||
overhang_regular = mesh_group_settings.support_offset == 0 ?
|
||||
overhang_raw :
|
||||
safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1);
|
||||
// When support_offset = 0 safe_offset_inc will only be the difference between overhang_raw and relevant_forbidden, that has to be calculated anyway.
|
||||
overhang_regular = safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1);
|
||||
//check_self_intersections(overhang_regular, "overhang_regular1");
|
||||
|
||||
// offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang
|
||||
@ -2498,8 +2507,10 @@ static void create_nodes_from_area(
|
||||
// Point is chosen based on an inaccurate estimate where the branches will split into two, but every point inside the influence area would produce a valid result.
|
||||
{
|
||||
SupportElements *layer_above = move_bounds.size() > 1 ? &move_bounds[1] : nullptr;
|
||||
for (SupportElement &elem : *layer_above)
|
||||
elem.state.marked = false;
|
||||
if (layer_above) {
|
||||
for (SupportElement &elem : *layer_above)
|
||||
elem.state.marked = false;
|
||||
}
|
||||
for (SupportElement &init : move_bounds.front()) {
|
||||
init.state.result_on_layer = move_inside_if_outside(init.influence_area, init.state.next_position);
|
||||
// Also set the parent nodes, as these will be required for the first iteration of the loop below and mark the parent nodes.
|
||||
@ -2932,7 +2943,11 @@ static void finalize_interface_and_support_areas(
|
||||
|
||||
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
|
||||
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;
|
||||
@ -2943,29 +2958,41 @@ static void finalize_interface_and_support_areas(
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, support_layer_storage.size()),
|
||||
[&](const tbb::blocked_range<size_t> &range) {
|
||||
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
|
||||
SupportGeneratorLayer*& support_roof = top_contacts[layer_idx];
|
||||
if (! support_roof_storage[layer_idx].empty() || support_roof != nullptr) {
|
||||
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]);
|
||||
SupportGeneratorLayer *support_roof = top_contacts[layer_idx];
|
||||
Polygons support_roof_polygons;
|
||||
|
||||
if (! support_roof->polygons.empty() &&
|
||||
area(intersection(support_layer_storage[layer_idx], support_roof->polygons)) > tiny_area_threshold) {
|
||||
if (Polygons &src = support_roof_storage[layer_idx]; ! src.empty()) {
|
||||
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) {
|
||||
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;
|
||||
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;
|
||||
//FIXME
|
||||
#if 1
|
||||
@ -2980,14 +3007,14 @@ static void finalize_interface_and_support_areas(
|
||||
Polygons interface_lines = offset(to_polylines(
|
||||
generate_support_infill_lines(support_roof->polygons, true, layer_idx, config.support_roof_line_distance)),
|
||||
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;
|
||||
}
|
||||
case InterfacePreference::SupportLinesOverwriteInterface:
|
||||
{
|
||||
// Hatch the support roof interfaces, offset them by their line width and subtract them from support base.
|
||||
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));
|
||||
// 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);
|
||||
@ -3001,10 +3028,10 @@ static void finalize_interface_and_support_areas(
|
||||
}
|
||||
|
||||
// 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];
|
||||
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));
|
||||
Polygons floor_layer;
|
||||
size_t layers_below = 0;
|
||||
@ -3022,15 +3049,18 @@ static void finalize_interface_and_support_areas(
|
||||
if (support_bottom == nullptr)
|
||||
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_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()) {
|
||||
SupportGeneratorLayer *&l = intermediate_layers[layer_idx];
|
||||
if (l == nullptr)
|
||||
l = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::Base, print_object.slicing_parameters(), layer_idx);
|
||||
append(l->polygons, union_(support_layer_storage[layer_idx]));
|
||||
if (! support_roof_polygons.empty()) {
|
||||
if (support_roof == nullptr)
|
||||
support_roof = top_contacts[layer_idx] = &layer_allocate(layer_storage, layer_storage_mutex, SupporLayerType::TopContact, print_object.slicing_parameters(), layer_idx);
|
||||
support_roof->polygons = union_(support_roof_polygons);
|
||||
}
|
||||
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
|
||||
@ -3907,25 +3937,15 @@ static void slice_branches(
|
||||
params.closing_radius = float(print_object.config().slice_closing_radius.value);
|
||||
params.mode = MeshSlicingParams::SlicingMode::Positive;
|
||||
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.
|
||||
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) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx)
|
||||
if (SupportGeneratorLayer *layer = intermediate_layers[layer_idx]; layer) {
|
||||
Polygons &poly = intermediate_layers[layer_idx]->polygons;
|
||||
poly = diff_clipped(poly, volumes.getCollision(0, layer_idx, true));
|
||||
}
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx)
|
||||
if (ExPolygons &src = slices[layer_idx]; ! src.empty())
|
||||
support_layer_storage[layer_idx] = diff_clipped(to_polygons(std::move(src)), volumes.getCollision(0, layer_idx, true));
|
||||
});
|
||||
|
||||
std::vector<Polygons> support_layer_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,
|
||||
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"));
|
||||
//FIXME this was the default
|
||||
// interface_preference = InterfacePreference::SupportLinesOverwriteInterface;
|
||||
interface_preference = InterfacePreference::SupportAreaOverwritesInterface;
|
||||
//interface_preference = InterfacePreference::SupportAreaOverwritesInterface;
|
||||
interface_preference = InterfacePreference::InterfaceAreaOverwritesSupport;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -385,8 +385,10 @@ void GLVolume::render()
|
||||
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
const bool is_left_handed = this->is_left_handed();
|
||||
|
||||
if (this->is_left_handed())
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CW));
|
||||
glsafe(::glCullFace(GL_BACK));
|
||||
|
||||
@ -395,7 +397,7 @@ void GLVolume::render()
|
||||
else
|
||||
model.render(this->tverts_range);
|
||||
|
||||
if (this->is_left_handed())
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CCW));
|
||||
}
|
||||
|
||||
@ -793,6 +795,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
const Transform3d& world_matrix = volume.first->world_matrix();
|
||||
volume.first->set_render_color(true);
|
||||
|
||||
// render sinking contours of non-hovered volumes
|
||||
@ -811,17 +814,21 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||
|
||||
shader->set_uniform("z_range", m_z_range);
|
||||
shader->set_uniform("clipping_plane", m_clipping_plane);
|
||||
shader->set_uniform("use_color_clip_plane", m_use_color_clip_plane);
|
||||
shader->set_uniform("color_clip_plane", m_color_clip_plane);
|
||||
shader->set_uniform("uniform_color_clip_plane_1", m_color_clip_plane_colors[0]);
|
||||
shader->set_uniform("uniform_color_clip_plane_2", m_color_clip_plane_colors[1]);
|
||||
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.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.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);
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();
|
||||
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1";
|
||||
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get_bool("use_environment_map");
|
||||
shader->set_uniform("use_environment_tex", use_environment_texture);
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id));
|
||||
@ -829,7 +836,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||
glcheck();
|
||||
|
||||
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("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();
|
||||
@ -866,7 +873,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||
shader->stop_using();
|
||||
if (edges_shader != nullptr) {
|
||||
edges_shader->start_using();
|
||||
if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get("non_manifold_edges") == "1") {
|
||||
if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get_bool("non_manifold_edges")) {
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
volume.first->render_non_manifold_edges();
|
||||
}
|
||||
|
@ -387,6 +387,12 @@ private:
|
||||
// plane coeffs for clipping in shaders
|
||||
std::array<double, 4> m_clipping_plane;
|
||||
|
||||
// plane coeffs for render volumes with different colors in shaders
|
||||
// used by cut gizmo
|
||||
std::array<double, 4> m_color_clip_plane;
|
||||
bool m_use_color_clip_plane{ false };
|
||||
std::array<ColorRGBA, 2> m_color_clip_plane_colors{ ColorRGBA::RED(), ColorRGBA::BLUE() };
|
||||
|
||||
struct Slope
|
||||
{
|
||||
// toggle for slope rendering
|
||||
@ -445,6 +451,14 @@ public:
|
||||
const std::array<float, 2>& get_z_range() const { return m_z_range; }
|
||||
const std::array<double, 4>& get_clipping_plane() const { return m_clipping_plane; }
|
||||
|
||||
void set_use_color_clip_plane(bool use) { m_use_color_clip_plane = use; }
|
||||
void set_color_clip_plane(const Vec3d& cp_normal, double offset) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
m_color_clip_plane[i] = -cp_normal[i];
|
||||
m_color_clip_plane[3] = offset;
|
||||
}
|
||||
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2>& colors) { m_color_clip_plane_colors = colors; }
|
||||
|
||||
bool is_slope_active() const { return m_slope.active; }
|
||||
void set_slope_active(bool active) { m_slope.active = active; }
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "libslic3r/Format/SL1.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/BuildVolume.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
@ -145,20 +144,6 @@ std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::f
|
||||
void BackgroundSlicingProcess::process_fff()
|
||||
{
|
||||
assert(m_print == m_fff_print);
|
||||
|
||||
// Checks that the print does not exceed the max print height
|
||||
const BuildVolume& build_volume = GUI::wxGetApp().mainframe->m_plater->build_volume();
|
||||
auto objects = m_fff_print->objects();
|
||||
for (auto obj : objects) {
|
||||
std::vector<coordf_t> layer_height_profile;
|
||||
PrintObject::update_layer_height_profile(*obj->model_object(), obj->slicing_parameters(), layer_height_profile);
|
||||
auto layers = generate_object_layers(obj->slicing_parameters(), layer_height_profile);
|
||||
if (!layers.empty() && layers.back() > build_volume.max_print_height()) {
|
||||
throw Slic3r::SlicingError("The print is taller than the maximum allowed height. You might want to reduce the size of your model"
|
||||
" or change current print settings and retry.");
|
||||
}
|
||||
}
|
||||
|
||||
m_print->process();
|
||||
wxCommandEvent evt(m_event_slicing_completed_id);
|
||||
// Post the Slicing Finished message for the G-code viewer to update.
|
||||
|
@ -36,10 +36,8 @@ void Camera::set_type(EType type)
|
||||
{
|
||||
if (m_type != type && (type == EType::Ortho || type == EType::Perspective)) {
|
||||
m_type = type;
|
||||
if (m_update_config_on_type_change_enabled) {
|
||||
if (m_update_config_on_type_change_enabled)
|
||||
wxGetApp().app_config->set("use_perspective_camera", (m_type == EType::Perspective) ? "1" : "0");
|
||||
wxGetApp().app_config->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,7 +283,7 @@ void Camera::debug_render() const
|
||||
imgui.begin(std::string("Camera statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
std::string type = get_type_as_string();
|
||||
if (wxGetApp().plater()->get_mouse3d_controller().connected() || (wxGetApp().app_config->get("use_free_camera") == "1"))
|
||||
if (wxGetApp().plater()->get_mouse3d_controller().connected() || (wxGetApp().app_config->get_bool("use_free_camera")))
|
||||
type += "/free";
|
||||
else
|
||||
type += "/constrained";
|
||||
|
@ -116,44 +116,48 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
}
|
||||
}
|
||||
|
||||
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
||||
config->opt_float("support_material_contact_distance") > 0. &&
|
||||
(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"
|
||||
"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)."));
|
||||
if (is_global_config)
|
||||
msg_text += "\n\n" + _(L("Shall I adjust those settings 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_extruder", new ConfigOptionInt(0));
|
||||
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
||||
}
|
||||
else
|
||||
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
auto style = config->opt_enum<SupportMaterialStyle>("support_material_style");
|
||||
|
||||
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));
|
||||
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
|
||||
// Organic supports are always synchronized with object layers as of now.
|
||||
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"
|
||||
"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)."));
|
||||
if (is_global_config)
|
||||
msg_text += "\n\n" + _(L("Shall I adjust those settings 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_extruder", new ConfigOptionInt(0));
|
||||
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
||||
}
|
||||
else
|
||||
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -183,18 +187,14 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
}
|
||||
|
||||
if (config->option<ConfigOptionPercent>("fill_density")->value == 100) {
|
||||
std::string fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->serialize();
|
||||
const auto &top_fill_pattern_values = config->def()->get("top_fill_pattern")->enum_values;
|
||||
bool correct_100p_fill = std::find(top_fill_pattern_values.begin(), top_fill_pattern_values.end(), fill_pattern) != top_fill_pattern_values.end();
|
||||
if (!correct_100p_fill) {
|
||||
const int fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->value;
|
||||
if (bool correct_100p_fill = config->option_def("top_fill_pattern")->enum_def->enum_to_index(fill_pattern).has_value();
|
||||
! correct_100p_fill) {
|
||||
// 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);
|
||||
auto it_pattern = std::find(fill_pattern_def->enum_values.begin(), fill_pattern_def->enum_values.end(), fill_pattern);
|
||||
assert(it_pattern != fill_pattern_def->enum_values.end());
|
||||
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 (auto label = fill_pattern_def->enum_def->enum_to_label(fill_pattern); label.has_value()) {
|
||||
wxString msg_text = GUI::format_wxstr(_L("The %1% infill pattern is not supposed to work at 100%% density."), _(*label));
|
||||
if (is_global_config)
|
||||
msg_text += "\n\n" + _L("Shall I switch to rectilinear fill pattern?");
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, _L("Infill"),
|
||||
@ -261,7 +261,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
toggle_field(el, has_top_solid_infill || (has_spiral_vase && has_bottom_solid_infill));
|
||||
|
||||
bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
|
||||
for (auto el : { "perimeter_acceleration", "infill_acceleration",
|
||||
for (auto el : { "perimeter_acceleration", "infill_acceleration", "top_solid_infill_acceleration",
|
||||
"solid_infill_acceleration", "external_perimeter_acceleration"
|
||||
"bridge_acceleration", "first_layer_acceleration" })
|
||||
toggle_field(el, have_default_acceleration);
|
||||
|
||||
@ -292,6 +293,13 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
toggle_field("support_material_bottom_contact_distance", have_support_material && ! have_support_soluble);
|
||||
toggle_field("support_material_closing_radius", have_support_material && support_material_style == smsSnug);
|
||||
|
||||
const bool has_organic_supports = support_material_style == smsOrganic &&
|
||||
(config->opt_bool("support_material") ||
|
||||
config->opt_int("support_material_enforce_layers") > 0);
|
||||
for (const std::string& key : { "support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter",
|
||||
"support_tree_branch_diameter_angle", "support_tree_tip_diameter", "support_tree_top_rate" })
|
||||
toggle_field(key, has_organic_supports);
|
||||
|
||||
for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder",
|
||||
"support_material_interface_speed", "support_material_interface_contact_loops" })
|
||||
toggle_field(el, have_support_material && have_support_interface);
|
||||
|
@ -1129,16 +1129,15 @@ void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool mat
|
||||
else
|
||||
other_profiles.push_back(data);
|
||||
}
|
||||
if(material_type_ordering) {
|
||||
if (material_type_ordering) {
|
||||
|
||||
const ConfigOptionDef* def = print_config_def.get("filament_type");
|
||||
std::vector<std::string>enum_values = def->enum_values;
|
||||
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++)
|
||||
{
|
||||
// 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
|
||||
if(profs != end_of_sorted) {
|
||||
std::reference_wrapper<const std::string> aux = other_profiles[end_of_sorted];
|
||||
@ -1299,7 +1298,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
|
||||
append_spacer(VERTICAL_SPACING);
|
||||
|
||||
auto *box_presets = new wxCheckBox(this, wxID_ANY, _L("Update built-in Presets automatically"));
|
||||
box_presets->SetValue(app_config->get("preset_update") == "1");
|
||||
box_presets->SetValue(app_config->get_bool("preset_update"));
|
||||
append(box_presets);
|
||||
append_text(wxString::Format(_L(
|
||||
"If enabled, %s downloads updates of built-in system presets in the background."
|
||||
@ -1316,10 +1315,12 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
|
||||
box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace DownloaderUtils
|
||||
{
|
||||
namespace {
|
||||
#ifdef _WIN32
|
||||
|
||||
wxString get_downloads_path()
|
||||
{
|
||||
wxString ret;
|
||||
@ -1331,7 +1332,6 @@ namespace DownloaderUtils
|
||||
CoTaskMemFree(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif __APPLE__
|
||||
wxString get_downloads_path()
|
||||
{
|
||||
@ -1349,9 +1349,8 @@ namespace DownloaderUtils
|
||||
}
|
||||
return wxString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
Worker::Worker(wxWindow* parent)
|
||||
: wxBoxSizer(wxHORIZONTAL)
|
||||
, m_parent(parent)
|
||||
@ -1417,7 +1416,7 @@ PageDownloader::PageDownloader(ConfigWizard* parent)
|
||||
|
||||
auto* box_allow_downloads = new wxCheckBox(this, wxID_ANY, _L("Allow build-in downloader"));
|
||||
// TODO: Do we want it like this? The downloader is allowed for very first time the wizard is run.
|
||||
bool box_allow_value = (app_config->has("downloader_url_registered") ? app_config->get("downloader_url_registered") == "1" : true);
|
||||
bool box_allow_value = (app_config->has("downloader_url_registered") ? app_config->get_bool("downloader_url_registered") : true);
|
||||
box_allow_downloads->SetValue(box_allow_value);
|
||||
append(box_allow_downloads);
|
||||
|
||||
@ -1433,21 +1432,23 @@ PageDownloader::PageDownloader(ConfigWizard* parent)
|
||||
)));
|
||||
#endif
|
||||
|
||||
box_allow_downloads->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->downloader->allow(event.IsChecked()); });
|
||||
box_allow_downloads->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->m_downloader->allow(event.IsChecked()); });
|
||||
|
||||
downloader = new DownloaderUtils::Worker(this);
|
||||
append(downloader);
|
||||
downloader->allow(box_allow_value);
|
||||
m_downloader = new DownloaderUtils::Worker(this);
|
||||
append(m_downloader);
|
||||
m_downloader->allow(box_allow_value);
|
||||
}
|
||||
|
||||
bool PageDownloader::on_finish_downloader() const
|
||||
{
|
||||
return downloader->on_finish();
|
||||
return m_downloader->on_finish();
|
||||
}
|
||||
|
||||
bool DownloaderUtils::Worker::perform_register()
|
||||
bool DownloaderUtils::Worker::perform_register(const std::string& path_override/* = {}*/)
|
||||
{
|
||||
boost::filesystem::path aux_dest (GUI::into_u8(path_name()));
|
||||
if (!path_override.empty())
|
||||
aux_dest = boost::filesystem::path(path_override);
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::path chosen_dest = boost::filesystem::absolute(aux_dest, ec);
|
||||
if(ec)
|
||||
@ -1516,7 +1517,7 @@ void DownloaderUtils::Worker::deregister()
|
||||
|
||||
bool DownloaderUtils::Worker::on_finish() {
|
||||
AppConfig* app_config = wxGetApp().app_config;
|
||||
bool ac_value = app_config->get("downloader_url_registered") == "1";
|
||||
bool ac_value = app_config->get_bool("downloader_url_registered");
|
||||
BOOST_LOG_TRIVIAL(debug) << "PageDownloader::on_finish_downloader ac_value " << ac_value << " downloader_checked " << downloader_checked;
|
||||
if (ac_value && downloader_checked) {
|
||||
// already registered but we need to do it again
|
||||
@ -1545,7 +1546,7 @@ PageReloadFromDisk::PageReloadFromDisk(ConfigWizard* parent)
|
||||
, full_pathnames(false)
|
||||
{
|
||||
auto* box_pathnames = new wxCheckBox(this, wxID_ANY, _L("Export full pathnames of models and parts sources into 3mf and amf files"));
|
||||
box_pathnames->SetValue(wxGetApp().app_config->get("export_sources_full_pathnames") == "1");
|
||||
box_pathnames->SetValue(wxGetApp().app_config->get_bool("export_sources_full_pathnames"));
|
||||
append(box_pathnames);
|
||||
append_text(_L(
|
||||
"If enabled, allows the Reload from disk command to automatically find and load the files when invoked.\n"
|
||||
@ -1594,7 +1595,7 @@ PageMode::PageMode(ConfigWizard *parent)
|
||||
|
||||
append_text("\n" + _L("The size of the object can be specified in inches"));
|
||||
check_inch = new wxCheckBox(this, wxID_ANY, _L("Use inches"));
|
||||
check_inch->SetValue(wxGetApp().app_config->get("use_inches") == "1");
|
||||
check_inch->SetValue(wxGetApp().app_config->get_bool("use_inches"));
|
||||
append(check_inch);
|
||||
|
||||
on_activate();
|
||||
@ -1658,14 +1659,14 @@ PageFirmware::PageFirmware(ConfigWizard *parent)
|
||||
append_text(_(gcode_opt.tooltip));
|
||||
|
||||
wxArrayString choices;
|
||||
choices.Alloc(gcode_opt.enum_labels.size());
|
||||
for (const auto &label : gcode_opt.enum_labels) {
|
||||
choices.Alloc(gcode_opt.enum_def->labels().size());
|
||||
for (const auto &label : gcode_opt.enum_def->labels()) {
|
||||
choices.Add(label);
|
||||
}
|
||||
|
||||
gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
||||
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();
|
||||
if (gcode_opt.default_value) {
|
||||
needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
|
||||
@ -1682,7 +1683,7 @@ PageFirmware::PageFirmware(ConfigWizard *parent)
|
||||
void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
|
||||
{
|
||||
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));
|
||||
config.set_key_value("gcode_flavor", opt);
|
||||
}
|
||||
@ -3034,9 +3035,11 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
||||
|
||||
#ifdef __linux__
|
||||
// Desktop integration on Linux
|
||||
BOOST_LOG_TRIVIAL(debug) << "ConfigWizard::priv::apply_config integrate_desktop" << page_welcome->integrate_desktop() << " perform_registration_linux " << page_downloader->downloader->get_perform_registration_linux();
|
||||
if (page_welcome->integrate_desktop() || page_downloader->downloader->get_perform_registration_linux())
|
||||
DesktopIntegrationDialog::perform_desktop_integration(page_downloader->downloader->get_perform_registration_linux());
|
||||
BOOST_LOG_TRIVIAL(debug) << "ConfigWizard::priv::apply_config integrate_desktop" << page_welcome->integrate_desktop() << " perform_registration_linux " << page_downloader->m_downloader->get_perform_registration_linux();
|
||||
if (page_welcome->integrate_desktop())
|
||||
DesktopIntegrationDialog::perform_desktop_integration();
|
||||
if (page_downloader->m_downloader->get_perform_registration_linux())
|
||||
DesktopIntegrationDialog::perform_downloader_desktop_integration();
|
||||
#endif
|
||||
|
||||
// Decide whether to create snapshot based on run_reason and the reset profile checkbox
|
||||
@ -3174,7 +3177,8 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
||||
|
||||
// apply materials in app_config
|
||||
for (const std::string& section_name : {AppConfig::SECTION_FILAMENTS, AppConfig::SECTION_MATERIALS})
|
||||
app_config->set_section(section_name, appconfig_new.get_section(section_name));
|
||||
if (appconfig_new.has_section(section_name))
|
||||
app_config->set_section(section_name, appconfig_new.get_section(section_name));
|
||||
|
||||
app_config->set_vendors(appconfig_new);
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <memory>
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
|
||||
@ -14,6 +16,36 @@ class PresetUpdater;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
namespace DownloaderUtils {
|
||||
class Worker : public wxBoxSizer
|
||||
{
|
||||
wxWindow* m_parent{ nullptr };
|
||||
wxTextCtrl* m_input_path{ nullptr };
|
||||
bool downloader_checked{ false };
|
||||
#ifdef __linux__
|
||||
bool perform_registration_linux{ false };
|
||||
#endif // __linux__
|
||||
|
||||
void deregister();
|
||||
|
||||
public:
|
||||
Worker(wxWindow* parent);
|
||||
~Worker() {}
|
||||
|
||||
void allow(bool allow_) { downloader_checked = allow_; }
|
||||
bool is_checked() const { return downloader_checked; }
|
||||
wxString path_name() const { return m_input_path ? m_input_path->GetValue() : wxString(); }
|
||||
|
||||
void set_path_name(wxString name);
|
||||
void set_path_name(const std::string& name);
|
||||
|
||||
bool on_finish();
|
||||
bool perform_register(const std::string& path_override = {});
|
||||
#ifdef __linux__
|
||||
bool get_perform_registration_linux() { return perform_registration_linux; }
|
||||
#endif // __linux__
|
||||
};
|
||||
}
|
||||
|
||||
class ConfigWizard: public DPIDialog
|
||||
{
|
||||
|
@ -10,12 +10,10 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/checklst.h>
|
||||
#include <wx/radiobut.h>
|
||||
@ -418,45 +416,10 @@ struct PageUpdate: ConfigWizardPage
|
||||
PageUpdate(ConfigWizard *parent);
|
||||
};
|
||||
|
||||
namespace DownloaderUtils {
|
||||
wxString get_downloads_path();
|
||||
|
||||
class Worker : public wxBoxSizer
|
||||
{
|
||||
wxWindow* m_parent {nullptr};
|
||||
wxTextCtrl* m_input_path {nullptr};
|
||||
bool downloader_checked {false};
|
||||
#ifdef __linux__
|
||||
bool perform_registration_linux { false };
|
||||
#endif // __linux__
|
||||
|
||||
bool perform_register();
|
||||
void deregister();
|
||||
|
||||
public:
|
||||
Worker(wxWindow* parent);
|
||||
~Worker(){}
|
||||
|
||||
void allow(bool allow_) { downloader_checked = allow_; }
|
||||
bool is_checked() const { return downloader_checked; }
|
||||
wxString path_name() const { return m_input_path ? m_input_path->GetValue() : wxString(); }
|
||||
|
||||
void set_path_name(wxString name);
|
||||
void set_path_name(const std::string& name);
|
||||
|
||||
bool on_finish();
|
||||
|
||||
#ifdef __linux__
|
||||
bool get_perform_registration_linux() { return perform_registration_linux; }
|
||||
#endif // __linux__
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct PageDownloader : ConfigWizardPage
|
||||
{
|
||||
DownloaderUtils::Worker* downloader{ nullptr };
|
||||
DownloaderUtils::Worker* m_downloader { nullptr };
|
||||
|
||||
PageDownloader(ConfigWizard* parent);
|
||||
|
||||
|
@ -218,9 +218,9 @@ bool DesktopIntegrationDialog::integration_possible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void DesktopIntegrationDialog::perform_desktop_integration(bool perform_downloader)
|
||||
void DesktopIntegrationDialog::perform_desktop_integration()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "performing desktop integration. With downloader integration: " << perform_downloader;
|
||||
BOOST_LOG_TRIVIAL(debug) << "performing desktop integration.";
|
||||
// Path to appimage
|
||||
const char *appimage_env = std::getenv("APPIMAGE");
|
||||
std::string excutable_path;
|
||||
@ -338,42 +338,47 @@ void DesktopIntegrationDialog::perform_desktop_integration(bool perform_download
|
||||
"StartupNotify=false\n"
|
||||
"StartupWMClass=prusa-slicer\n", name_suffix, version_suffix, excutable_path);
|
||||
|
||||
bool candidate_found = false;
|
||||
for (size_t i = 0; i < target_candidates.size(); ++i) {
|
||||
if (contains_path_dir(target_candidates[i], "applications")) {
|
||||
target_dir_desktop = target_candidates[i];
|
||||
// Write slicer desktop file
|
||||
std::string path = GUI::format("%1%/applications/PrusaSlicer%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (create_desktop_file(path, desktop_file)){
|
||||
if (create_desktop_file(path, desktop_file)) {
|
||||
candidate_found = true;
|
||||
BOOST_LOG_TRIVIAL(debug) << "PrusaSlicer.desktop file installation success.";
|
||||
break;
|
||||
} else {
|
||||
// write failed - try another path
|
||||
BOOST_LOG_TRIVIAL(debug) << "Attempt to PrusaSlicer.desktop file installation failed. failed path: " << target_candidates[i];
|
||||
target_dir_desktop.clear();
|
||||
}
|
||||
}
|
||||
// if all failed - try creating default home folder
|
||||
if (i == target_candidates.size() - 1) {
|
||||
// create $HOME/.local/share
|
||||
create_path(boost::nowide::narrow(wxFileName::GetHomeDir()), ".local/share/applications");
|
||||
// create desktop file
|
||||
target_dir_desktop = GUI::format("%1%/.local/share",wxFileName::GetHomeDir());
|
||||
std::string path = GUI::format("%1%/applications/PrusaSlicer%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (contains_path_dir(target_dir_desktop, "applications")) {
|
||||
if (!create_desktop_file(path, desktop_file)) {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed - could not create desktop file";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed because the application directory was not found.";
|
||||
return;
|
||||
else {
|
||||
// write failed - try another path
|
||||
BOOST_LOG_TRIVIAL(debug) << "Attempt to PrusaSlicer.desktop file installation failed. failed path: " << target_candidates[i];
|
||||
target_dir_desktop.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(target_dir_desktop.empty()) {
|
||||
// Desktop file not written - end desktop integration
|
||||
// if all failed - try creating default home folder
|
||||
if (!candidate_found) {
|
||||
// create $HOME/.local/share
|
||||
create_path(boost::nowide::narrow(wxFileName::GetHomeDir()), ".local/share/applications");
|
||||
// create desktop file
|
||||
target_dir_desktop = GUI::format("%1%/.local/share", wxFileName::GetHomeDir());
|
||||
std::string path = GUI::format("%1%/applications/PrusaSlicer%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (contains_path_dir(target_dir_desktop, "applications")) {
|
||||
if (!create_desktop_file(path, desktop_file)) {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed - could not create desktop file";
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed because the application directory was not found.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(!target_dir_desktop.empty());
|
||||
if (target_dir_desktop.empty()) {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed because the application directory was not found.";
|
||||
show_error(nullptr, _L("Performing desktop integration failed because the application directory was not found."));
|
||||
return;
|
||||
@ -418,38 +423,6 @@ void DesktopIntegrationDialog::perform_desktop_integration(bool perform_download
|
||||
show_error(nullptr, _L("Performing desktop integration failed - could not create Gcodeviewer desktop file. PrusaSlicer desktop file was probably created successfully."));
|
||||
}
|
||||
}
|
||||
|
||||
if (perform_downloader)
|
||||
{
|
||||
std::string desktop_file_downloader = GUI::format(
|
||||
"[Desktop Entry]\n"
|
||||
"Name=PrusaSlicer URL Protocol%1%\n"
|
||||
"Exec=\"%3%\" --single-instance %%u\n"
|
||||
"Icon=PrusaSlicer%4%\n"
|
||||
"Terminal=false\n"
|
||||
"Type=Application\n"
|
||||
"MimeType=x-scheme-handler/prusaslicer;\n"
|
||||
"StartupNotify=false\n"
|
||||
, name_suffix, version_suffix, excutable_path, version_suffix);
|
||||
|
||||
// desktop file for downloader as part of main app
|
||||
std::string desktop_path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (create_desktop_file(desktop_path, desktop_file_downloader)) {
|
||||
// save path to desktop file
|
||||
app_config->set("desktop_integration_URL_path", desktop_path);
|
||||
// finish registration on mime type
|
||||
std::string command = GUI::format("xdg-mime default PrusaSlicerURLProtocol%1%.desktop x-scheme-handler/prusaslicer", version_suffix);
|
||||
BOOST_LOG_TRIVIAL(debug) << "system command: " << command;
|
||||
int r = system(command.c_str());
|
||||
BOOST_LOG_TRIVIAL(debug) << "system result: " << r;
|
||||
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing desktop integration failed - could not create URL Protocol desktop file";
|
||||
show_error(nullptr, _L("Performing desktop integration failed - could not create URL Protocol desktop file."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::DesktopIntegrationSuccess);
|
||||
}
|
||||
void DesktopIntegrationDialog::undo_desktop_intgration()
|
||||
@ -482,15 +455,162 @@ void DesktopIntegrationDialog::undo_desktop_intgration()
|
||||
std::remove(path.c_str());
|
||||
}
|
||||
}
|
||||
// URL Protocol
|
||||
path = std::string(app_config->get("desktop_integration_URL_path"));
|
||||
if (!path.empty()) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "removing " << path;
|
||||
std::remove(path.c_str());
|
||||
}
|
||||
wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::UndoDesktopIntegrationSuccess);
|
||||
}
|
||||
void DesktopIntegrationDialog::perform_downloader_desktop_integration()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "performing downloader desktop integration.";
|
||||
// Path to appimage
|
||||
const char* appimage_env = std::getenv("APPIMAGE");
|
||||
std::string excutable_path;
|
||||
if (appimage_env) {
|
||||
try {
|
||||
excutable_path = boost::filesystem::canonical(boost::filesystem::path(appimage_env)).string();
|
||||
}
|
||||
catch (std::exception&) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed - boost::filesystem::canonical did not return appimage path.";
|
||||
show_error(nullptr, _L("Performing downloader desktop integration failed - boost::filesystem::canonical did not return appimage path."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// not appimage - find executable
|
||||
excutable_path = boost::dll::program_location().string();
|
||||
//excutable_path = wxStandardPaths::Get().GetExecutablePath().string();
|
||||
BOOST_LOG_TRIVIAL(debug) << "non-appimage path to executable: " << excutable_path;
|
||||
if (excutable_path.empty())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed - no executable found.";
|
||||
show_error(nullptr, _L("Performing downloader desktop integration failed - Could not find executable."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Escape ' characters in appimage, other special symbols will be esacaped in desktop file by 'excutable_path'
|
||||
//boost::replace_all(excutable_path, "'", "'\\''");
|
||||
excutable_path = escape_string(excutable_path);
|
||||
|
||||
// Find directories icons and applications
|
||||
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored.
|
||||
// If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
|
||||
// $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory.
|
||||
// The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.
|
||||
// If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.
|
||||
std::vector<std::string>target_candidates;
|
||||
resolve_path_from_var("XDG_DATA_HOME", target_candidates);
|
||||
resolve_path_from_var("XDG_DATA_DIRS", target_candidates);
|
||||
|
||||
AppConfig* app_config = wxGetApp().app_config;
|
||||
// suffix string to create different desktop file for alpha, beta.
|
||||
|
||||
std::string version_suffix;
|
||||
std::string name_suffix;
|
||||
std::string version(SLIC3R_VERSION);
|
||||
if (version.find("alpha") != std::string::npos)
|
||||
{
|
||||
version_suffix = "-alpha";
|
||||
name_suffix = " - alpha";
|
||||
}
|
||||
else if (version.find("beta") != std::string::npos)
|
||||
{
|
||||
version_suffix = "-beta";
|
||||
name_suffix = " - beta";
|
||||
}
|
||||
|
||||
// theme path to icon destination
|
||||
std::string icon_theme_path;
|
||||
std::string icon_theme_dirs;
|
||||
|
||||
if (platform_flavor() == PlatformFlavor::LinuxOnChromium) {
|
||||
icon_theme_path = "hicolor/96x96/apps/";
|
||||
icon_theme_dirs = "/hicolor/96x96/apps";
|
||||
}
|
||||
|
||||
std::string target_dir_desktop;
|
||||
|
||||
// desktop file
|
||||
// iterate thru target_candidates to find applications folder
|
||||
|
||||
std::string desktop_file_downloader = GUI::format(
|
||||
"[Desktop Entry]\n"
|
||||
"Name=PrusaSlicer URL Protocol%1%\n"
|
||||
"Exec=\"%2%\" --single-instance %%u\n"
|
||||
"Terminal=false\n"
|
||||
"Type=Application\n"
|
||||
"MimeType=x-scheme-handler/prusaslicer;\n"
|
||||
"StartupNotify=false\n"
|
||||
"NoDisplay=true\n"
|
||||
, name_suffix, excutable_path);
|
||||
|
||||
// desktop file for downloader as part of main app
|
||||
std::string desktop_path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (create_desktop_file(desktop_path, desktop_file_downloader)) {
|
||||
// save path to desktop file
|
||||
app_config->set("desktop_integration_URL_path", desktop_path);
|
||||
// finish registration on mime type
|
||||
std::string command = GUI::format("xdg-mime default PrusaSlicerURLProtocol%1%.desktop x-scheme-handler/prusaslicer", version_suffix);
|
||||
BOOST_LOG_TRIVIAL(debug) << "system command: " << command;
|
||||
int r = system(command.c_str());
|
||||
BOOST_LOG_TRIVIAL(debug) << "system result: " << r;
|
||||
|
||||
}
|
||||
|
||||
bool candidate_found = false;
|
||||
for (size_t i = 0; i < target_candidates.size(); ++i) {
|
||||
if (contains_path_dir(target_candidates[i], "applications")) {
|
||||
target_dir_desktop = target_candidates[i];
|
||||
// Write slicer desktop file
|
||||
std::string path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (create_desktop_file(path, desktop_file_downloader)) {
|
||||
app_config->set("desktop_integration_URL_path", path);
|
||||
candidate_found = true;
|
||||
BOOST_LOG_TRIVIAL(debug) << "PrusaSlicerURLProtocol.desktop file installation success.";
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// write failed - try another path
|
||||
BOOST_LOG_TRIVIAL(debug) << "Attempt to PrusaSlicerURLProtocol.desktop file installation failed. failed path: " << target_candidates[i];
|
||||
target_dir_desktop.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
// if all failed - try creating default home folder
|
||||
if (!candidate_found) {
|
||||
// create $HOME/.local/share
|
||||
create_path(boost::nowide::narrow(wxFileName::GetHomeDir()), ".local/share/applications");
|
||||
// create desktop file
|
||||
target_dir_desktop = GUI::format("%1%/.local/share", wxFileName::GetHomeDir());
|
||||
std::string path = GUI::format("%1%/applications/PrusaSlicerURLProtocol%2%.desktop", target_dir_desktop, version_suffix);
|
||||
if (contains_path_dir(target_dir_desktop, "applications")) {
|
||||
if (!create_desktop_file(path, desktop_file_downloader)) {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed - could not create desktop file.";
|
||||
return;
|
||||
}
|
||||
app_config->set("desktop_integration_URL_path", path);
|
||||
}
|
||||
else {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed because the application directory was not found.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(!target_dir_desktop.empty());
|
||||
if (target_dir_desktop.empty()) {
|
||||
// Desktop file not written - end desktop integration
|
||||
BOOST_LOG_TRIVIAL(error) << "Performing downloader desktop integration failed because the application directory was not found.";
|
||||
show_error(nullptr, _L("Performing downloader desktop integration failed because the application directory was not found."));
|
||||
return;
|
||||
}
|
||||
|
||||
// finish registration on mime type
|
||||
std::string command = GUI::format("xdg-mime default PrusaSlicerURLProtocol%1%.desktop x-scheme-handler/prusaslicer", version_suffix);
|
||||
BOOST_LOG_TRIVIAL(debug) << "system command: " << command;
|
||||
int r = system(command.c_str());
|
||||
BOOST_LOG_TRIVIAL(debug) << "system result: " << r;
|
||||
|
||||
wxGetApp().plater()->get_notification_manager()->push_notification(NotificationType::DesktopIntegrationSuccess);
|
||||
}
|
||||
void DesktopIntegrationDialog::undo_downloader_registration()
|
||||
{
|
||||
const AppConfig *app_config = wxGetApp().app_config;
|
||||
@ -527,7 +647,7 @@ DesktopIntegrationDialog::DesktopIntegrationDialog(wxWindow *parent)
|
||||
wxButton *btn_perform = new wxButton(this, wxID_ANY, _L("Perform"));
|
||||
btn_szr->Add(btn_perform, 0, wxALL, 10);
|
||||
|
||||
btn_perform->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { DesktopIntegrationDialog::perform_desktop_integration(false); EndModal(wxID_ANY); });
|
||||
btn_perform->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { DesktopIntegrationDialog::perform_desktop_integration(); EndModal(wxID_ANY); });
|
||||
|
||||
if (can_undo){
|
||||
wxButton *btn_undo = new wxButton(this, wxID_ANY, _L("Undo"));
|
||||
|
@ -29,10 +29,11 @@ public:
|
||||
// if perform_downloader:
|
||||
// Creates Destktop files for PrusaSlicer downloader feature
|
||||
// Regiters PrusaSlicer to start on prusaslicer:// URL
|
||||
static void perform_desktop_integration(bool perform_downloader);
|
||||
static void perform_desktop_integration();
|
||||
// Deletes Desktop files and icons for both PrusaSlicer and GcodeViewer at paths stored in App Config.
|
||||
static void undo_desktop_intgration();
|
||||
|
||||
static void perform_downloader_desktop_integration();
|
||||
static void undo_downloader_registration();
|
||||
private:
|
||||
|
||||
|