mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 19:15:56 +08:00
Merge branch 'master' into SPE-1597-per-glyph-transformation-over-surface
This commit is contained in:
commit
7d867e5dc2
BIN
resources/localization/be/PrusaSlicer.mo
Normal file
BIN
resources/localization/be/PrusaSlicer.mo
Normal file
Binary file not shown.
Binary file not shown.
@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-05-26 13:11+0200\n"
|
||||
"PO-Revision-Date: 2023-05-17 19:36+0200\n"
|
||||
"PO-Revision-Date: 2023-05-27 14:17+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: ca\n"
|
||||
@ -16,7 +16,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.2.2\n"
|
||||
"X-Generator: Poedit 3.3.1\n"
|
||||
|
||||
#: src/slic3r/GUI/AboutDialog.cpp:46 src/slic3r/GUI/AboutDialog.cpp:304
|
||||
msgid "Portions copyright"
|
||||
@ -1498,23 +1498,23 @@ msgstr "Col·loca els rodaments a les ranures i segueix imprimint"
|
||||
#: src/slic3r/GUI/DoubleSlider.cpp:711 src/libslic3r/Utils.cpp:1015
|
||||
#, boost-format
|
||||
msgid "%1%d"
|
||||
msgstr ""
|
||||
msgstr "%1%d"
|
||||
|
||||
#: src/slic3r/GUI/DoubleSlider.cpp:712 src/libslic3r/Utils.cpp:1016
|
||||
#, boost-format
|
||||
msgid "%1%h"
|
||||
msgstr ""
|
||||
msgstr "%1%h"
|
||||
|
||||
#. TRN "m" means "minutes"
|
||||
#: src/slic3r/GUI/DoubleSlider.cpp:713 src/libslic3r/Utils.cpp:1018
|
||||
#, boost-format
|
||||
msgid "%1%m"
|
||||
msgstr ""
|
||||
msgstr "%1%m"
|
||||
|
||||
#: src/slic3r/GUI/DoubleSlider.cpp:714 src/libslic3r/Utils.cpp:1026
|
||||
#, boost-format
|
||||
msgid "%1%s"
|
||||
msgstr ""
|
||||
msgstr "%1%s"
|
||||
|
||||
#: src/slic3r/GUI/DoubleSlider.cpp:1448
|
||||
msgid "One layer mode"
|
||||
@ -2303,7 +2303,7 @@ msgstr "a"
|
||||
#: src/slic3r/GUI/GCodeViewer.cpp:3278
|
||||
msgctxt "Metre"
|
||||
msgid "m"
|
||||
msgstr ""
|
||||
msgstr "m"
|
||||
|
||||
#: src/slic3r/GUI/GCodeViewer.cpp:3289
|
||||
msgid "Click to hide"
|
||||
@ -2451,11 +2451,11 @@ msgstr "Filament"
|
||||
|
||||
#: src/slic3r/GUI/GCodeViewer.cpp:3961
|
||||
msgid "Hide Custom G-code"
|
||||
msgstr ""
|
||||
msgstr "Ocultar Codi G personalitzat"
|
||||
|
||||
#: src/slic3r/GUI/GCodeViewer.cpp:3961
|
||||
msgid "Show Custom G-code"
|
||||
msgstr ""
|
||||
msgstr "Mostrar Codi G personalitzat"
|
||||
|
||||
#: src/slic3r/GUI/GCodeViewer.cpp:3974
|
||||
msgid "Estimated printing times"
|
||||
@ -2614,15 +2614,15 @@ msgstr "Seq."
|
||||
|
||||
#: src/slic3r/GUI/GLCanvas3D.cpp:1305
|
||||
msgid "SLA view"
|
||||
msgstr ""
|
||||
msgstr "Vista SLA"
|
||||
|
||||
#: src/slic3r/GUI/GLCanvas3D.cpp:1324
|
||||
msgid "Show as processed"
|
||||
msgstr ""
|
||||
msgstr "Mostrar com a processat"
|
||||
|
||||
#: src/slic3r/GUI/GLCanvas3D.cpp:1325
|
||||
msgid "Show as original"
|
||||
msgstr ""
|
||||
msgstr "Mostrar com a original"
|
||||
|
||||
#: src/slic3r/GUI/GLCanvas3D.cpp:1758
|
||||
msgid "Variable layer height - Reset"
|
||||
@ -2948,6 +2948,9 @@ msgid ""
|
||||
"Drag to move the cut plane\n"
|
||||
"Right-click a part to assign it to the other side"
|
||||
msgstr ""
|
||||
"Feu clic per capgirar el pla de tall\n"
|
||||
"Arrossegueu per moure el pla tallat\n"
|
||||
"Feu clic amb el botó dret a una part per assignar-la a l'altre costat"
|
||||
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:259 src/libslic3r/PrintConfig.cpp:495
|
||||
#: src/libslic3r/PrintConfig.cpp:1189 src/libslic3r/PrintConfig.cpp:2324
|
||||
@ -3836,7 +3839,7 @@ msgstr "La pintura automàtica requereix una configuració d'impressió vàlida.
|
||||
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:527
|
||||
msgid "Automatic painting requires printable object."
|
||||
msgstr ""
|
||||
msgstr "La pintura automàtica requereix un objecte imprimible."
|
||||
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:537
|
||||
msgid "Automatic painting will erase all currently painted areas."
|
||||
@ -4134,13 +4137,13 @@ msgstr "Farciment de cubs"
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:340
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:356
|
||||
msgid "Current"
|
||||
msgstr ""
|
||||
msgstr "Actual"
|
||||
|
||||
#. TRN Means "original color"
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:342
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:356
|
||||
msgid "Original"
|
||||
msgstr ""
|
||||
msgstr "Original"
|
||||
|
||||
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:404
|
||||
msgid "Paints neighboring facets that have the same color."
|
||||
@ -5129,6 +5132,7 @@ msgstr "Actualment esteu executant l'última versió publicada %1%."
|
||||
msgid ""
|
||||
"There are no new released versions online. The latest release version is %1%."
|
||||
msgstr ""
|
||||
"No hi ha noves versions en línia. L'última versió de llançament és %1%."
|
||||
|
||||
#: src/slic3r/GUI/GUI_App.cpp:3437
|
||||
#, boost-format
|
||||
@ -11181,7 +11185,7 @@ msgstr "Connexió de les varetes de suport i unions"
|
||||
|
||||
#: src/slic3r/GUI/Tab.cpp:5157
|
||||
msgid "Branching"
|
||||
msgstr ""
|
||||
msgstr "Ramificació"
|
||||
|
||||
#: src/slic3r/GUI/Tab.cpp:5159
|
||||
msgid "Automatic generation"
|
||||
@ -12099,6 +12103,8 @@ msgid ""
|
||||
"Couldn't locate index file for vendor %1% when performing updates. The "
|
||||
"profile will not be installed."
|
||||
msgstr ""
|
||||
"No s'ha pogut localitzar el fitxer d'índex per als %1% del proveïdor en "
|
||||
"realitzar actualitzacions. El perfil no s'instal·larà."
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:1344
|
||||
#, boost-format
|
||||
@ -12106,6 +12112,8 @@ msgid ""
|
||||
"Couldn't load index file for vendor %1% when performing updates. The profile "
|
||||
"will not be installed. Reason: Corrupted index file %2%."
|
||||
msgstr ""
|
||||
"No s'ha pogut carregar el fitxer d'índex per al proveïdor %1% en realitzar "
|
||||
"actualitzacions. El perfil no s'instal·larà. Motiu: fitxer índex malmès %2%."
|
||||
|
||||
#: src/slic3r/Utils/PresetUpdater.cpp:1382
|
||||
#, boost-format
|
||||
@ -12113,6 +12121,9 @@ msgid ""
|
||||
"Couldn't open profile file for vendor %1% when performing updates. The "
|
||||
"profile will not be installed. This installation might be corrupted."
|
||||
msgstr ""
|
||||
"No s'ha pogut obrir el fitxer de perfil per al proveïdor %1% en realitzar "
|
||||
"actualitzacions. El perfil no s'instal·larà. Aquesta instal·lació pot estar "
|
||||
"corrompuda."
|
||||
|
||||
#: src/slic3r/Utils/Http.cpp:73
|
||||
msgid ""
|
||||
@ -12276,19 +12287,19 @@ msgstr ""
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:38 src/libslic3r/ExtrusionRole.cpp:59
|
||||
msgid "Perimeter"
|
||||
msgstr ""
|
||||
msgstr "Perímetre"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:39 src/libslic3r/ExtrusionRole.cpp:61
|
||||
msgid "External perimeter"
|
||||
msgstr ""
|
||||
msgstr "Perímetre extern"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:40 src/libslic3r/ExtrusionRole.cpp:63
|
||||
msgid "Overhang perimeter"
|
||||
msgstr ""
|
||||
msgstr "Perímetre de voladís"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:41 src/libslic3r/ExtrusionRole.cpp:65
|
||||
msgid "Internal infill"
|
||||
msgstr ""
|
||||
msgstr "Farciment intern"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:42 src/libslic3r/ExtrusionRole.cpp:67
|
||||
#: src/libslic3r/PrintConfig.cpp:1452 src/libslic3r/PrintConfig.cpp:2432
|
||||
@ -12304,7 +12315,7 @@ msgstr "Farciment sòlid superior"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:45 src/libslic3r/ExtrusionRole.cpp:73
|
||||
msgid "Bridge infill"
|
||||
msgstr ""
|
||||
msgstr "Farciment del pont"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:46 src/libslic3r/ExtrusionRole.cpp:75
|
||||
#: src/libslic3r/PrintConfig.cpp:1380
|
||||
@ -12313,7 +12324,7 @@ msgstr "Farciment del buit"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:47 src/libslic3r/ExtrusionRole.cpp:77
|
||||
msgid "Skirt/Brim"
|
||||
msgstr ""
|
||||
msgstr "Faldilla/Bassa"
|
||||
|
||||
#: src/libslic3r/ExtrusionRole.cpp:49 src/libslic3r/ExtrusionRole.cpp:81
|
||||
#: src/libslic3r/PrintConfig.cpp:2781
|
||||
@ -12570,7 +12581,7 @@ msgstr ""
|
||||
#: src/libslic3r/Print.cpp:525
|
||||
#, boost-format
|
||||
msgid "The object %1% exceeds the maximum build volume height."
|
||||
msgstr ""
|
||||
msgstr "L'objecte %1% supera l'alçada màxima de volum de construcció."
|
||||
|
||||
#: src/libslic3r/Print.cpp:526
|
||||
#, boost-format
|
||||
@ -12578,12 +12589,16 @@ msgid ""
|
||||
"While the object %1% itself fits the build volume, its last layer exceeds "
|
||||
"the maximum build volume height."
|
||||
msgstr ""
|
||||
"Tot i que l'objecte %1% s'adapta al volum de construcció, la seva última "
|
||||
"capa supera l'alçada màxima del volum de construcció."
|
||||
|
||||
#: src/libslic3r/Print.cpp:527
|
||||
msgid ""
|
||||
"You might want to reduce the size of your model or change current print "
|
||||
"settings and retry."
|
||||
msgstr ""
|
||||
"És possible que vulgueu reduir la mida del model o canviar la configuració "
|
||||
"d'impressió actual i tornar-ho a provar."
|
||||
|
||||
#: src/libslic3r/Print.cpp:543
|
||||
msgid "Variable layer height is not supported with Organic supports."
|
||||
@ -16410,7 +16425,7 @@ msgstr ""
|
||||
|
||||
#: src/libslic3r/PrintConfig.cpp:2943
|
||||
msgid "Branch Diameter with double walls"
|
||||
msgstr ""
|
||||
msgstr "Diàmetre de branca amb parets dobles"
|
||||
|
||||
#. TRN PrintSettings: "Organic supports" > "Branch Diameter"
|
||||
#: src/libslic3r/PrintConfig.cpp:2946
|
||||
@ -16419,6 +16434,9 @@ msgid ""
|
||||
"printed with double walls for stability. Set this value to zero for no "
|
||||
"double walls."
|
||||
msgstr ""
|
||||
"Les branques amb una superfície més gran que l'àrea d'un cercle d'aquest "
|
||||
"diàmetre s'imprimiran amb parets dobles per a l'estabilitat. Establiu aquest "
|
||||
"valor a zero per a cap paret doble."
|
||||
|
||||
#. TRN PrintSettings: #lmFIXME
|
||||
#: src/libslic3r/PrintConfig.cpp:2959
|
||||
@ -21360,11 +21378,6 @@ msgstr "S'ha produït un error en imprimir: "
|
||||
msgid "Error: "
|
||||
msgstr "Error: "
|
||||
|
||||
#. TRANSLATORS: Name of keyboard key
|
||||
#: ../src/common/accelcmn.cpp:69
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#. TRANSLATORS: Name of keyboard key
|
||||
#: ../src/common/accelcmn.cpp:70
|
||||
msgid "Escape"
|
||||
@ -23363,11 +23376,6 @@ msgstr "Nom nou"
|
||||
msgid "Next page"
|
||||
msgstr "Pàgina següent"
|
||||
|
||||
#: ../include/wx/msgdlg.h:277 ../src/common/stockitem.cpp:177
|
||||
#: ../src/motif/msgdlg.cpp:196
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#. TRANSLATORS: System cursor name
|
||||
#: ../src/propgrid/advprops.cpp:1764
|
||||
msgid "No Entry"
|
||||
@ -26080,11 +26088,6 @@ msgstr "XPM: dades de la imatge truncades a la línia %d!"
|
||||
msgid "Yellow"
|
||||
msgstr "Groc"
|
||||
|
||||
#: ../include/wx/msgdlg.h:276 ../src/common/stockitem.cpp:206
|
||||
#: ../src/motif/msgdlg.cpp:196
|
||||
msgid "Yes"
|
||||
msgstr "Sí"
|
||||
|
||||
#: ../src/osx/carbon/overlay.cpp:155
|
||||
msgid "You cannot Clear an overlay that is not inited"
|
||||
msgstr "No podeu netejar una superposició que no s'ha inicialitzat"
|
||||
@ -27032,3 +27035,18 @@ msgstr "s'ha produït un error de zlib %d"
|
||||
#: ../src/richtext/richtextbulletspage.cpp:288
|
||||
msgid "~"
|
||||
msgstr "~"
|
||||
|
||||
#. TRANSLATORS: Name of keyboard key
|
||||
#: ../src/common/accelcmn.cpp:69
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#: ../include/wx/msgdlg.h:277 ../src/common/stockitem.cpp:177
|
||||
#: ../src/motif/msgdlg.cpp:196
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#: ../include/wx/msgdlg.h:276 ../src/common/stockitem.cpp:206
|
||||
#: ../src/motif/msgdlg.cpp:196
|
||||
msgid "Yes"
|
||||
msgstr "Sí"
|
||||
|
BIN
resources/localization/fi/PrusaSlicer.mo
Normal file
BIN
resources/localization/fi/PrusaSlicer.mo
Normal file
Binary file not shown.
25287
resources/localization/fi/PrusaSlicer_fi.po
Normal file
25287
resources/localization/fi/PrusaSlicer_fi.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
||||
min_slic3r_version = 2.6.0-beta2
|
||||
1.9.0-beta2 Added profiles for Original Prusa MK4 Input Shaper (Alpha).
|
||||
min_slic3r_version = 2.6.0-beta0
|
||||
1.9.0-beta1 Updated cooling settings for some ASA filaments to increase interlayer adhesion (XL/MK4).
|
||||
1.9.0-beta0 Updated start g-code script for MK4/XL.
|
||||
|
@ -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.9.0-beta1
|
||||
config_version = 1.9.0-beta2
|
||||
# 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%
|
||||
@ -23,6 +23,16 @@ bed_model = mk4_bed.stl
|
||||
bed_texture = mk4.svg
|
||||
default_materials = Generic PLA @PG; Generic ABS @MK4; Generic PETG @PG; Prusament PLA @PG; Prusament PETG @PG; Prusament ASA @MK4; Prusament PC Blend @MK4; Prusament PC Blend Carbon Fiber @MK4; Prusament PVB @PG; Prusament PA11 Carbon Fiber @PG
|
||||
|
||||
[printer_model:MK4IS]
|
||||
name = Original Prusa MK4 Input Shaper (Alpha)
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = MK4
|
||||
bed_model = mk4_bed.stl
|
||||
bed_texture = mk4is.svg
|
||||
thumbnail = MK4IS_thumbnail.png
|
||||
default_materials = Prusament PLA @MK4IS; Prusament PLA Blend @MK4IS; Prusament PETG @MK4IS; Generic PLA @MK4IS; Prusa PLA @MK4IS; Prusa PETG @MK4IS; Generic ASA @MK4; Generic PETG @MK4IS; Prusa PLA @MK4IS; Generic PLA Silk @MK4IS
|
||||
|
||||
[printer_model:MINI]
|
||||
name = Original Prusa MINI && MINI+
|
||||
variants = 0.4; 0.25; 0.6; 0.8
|
||||
@ -452,6 +462,7 @@ thick_bridges = 1
|
||||
bridge_flow_ratio = 0.95
|
||||
bridge_speed = 25
|
||||
infill_overlap = 15%
|
||||
support_tree_branch_diameter_double_wall = 0
|
||||
|
||||
[print:*0.6nozzleMK3*]
|
||||
inherits = *0.6nozzle*
|
||||
@ -528,6 +539,7 @@ bottom_solid_min_thickness = 0.8
|
||||
single_extruder_multi_material_priming = 0
|
||||
thick_bridges = 1
|
||||
overhangs = 0
|
||||
support_tree_branch_diameter_double_wall = 0
|
||||
|
||||
[print:*0.8nozzleXL*]
|
||||
inherits = *0.8nozzle*
|
||||
@ -3564,6 +3576,135 @@ solid_infill_acceleration = 1500
|
||||
infill_acceleration = 2000
|
||||
compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8
|
||||
|
||||
## MK4 - Input Shaper 0.4mm nozzle
|
||||
|
||||
[print:0.20mm Input Shaper @MK4IS 0.4]
|
||||
bottom_solid_layers = 4
|
||||
bottom_solid_min_thickness = 0
|
||||
bridge_acceleration = 1500
|
||||
bridge_flow_ratio = 1
|
||||
bridge_speed = 50
|
||||
brim_separation = 0.1
|
||||
default_acceleration = 4000
|
||||
dont_support_bridges = 0
|
||||
elefant_foot_compensation = 0.2
|
||||
enable_dynamic_overhang_speeds = 1
|
||||
external_perimeter_acceleration = 4000
|
||||
external_perimeter_extrusion_width = 0.45
|
||||
external_perimeter_speed = 170
|
||||
external_perimeters_first = 0
|
||||
extra_perimeters = 0
|
||||
extruder_clearance_height = 14
|
||||
extruder_clearance_radius = 45
|
||||
extrusion_width = 0.45
|
||||
fill_angle = 45
|
||||
fill_density = 15%
|
||||
fill_pattern = grid
|
||||
first_layer_acceleration = 500
|
||||
first_layer_acceleration_over_raft = 0
|
||||
first_layer_extrusion_width = 0.5
|
||||
first_layer_height = 0.2
|
||||
first_layer_speed = 40
|
||||
first_layer_speed_over_raft = 30
|
||||
gap_fill_enabled = 1
|
||||
gap_fill_speed = 120
|
||||
gcode_comments = 0
|
||||
gcode_label_objects = 0
|
||||
gcode_resolution = 0.008
|
||||
infill_acceleration = 4000
|
||||
infill_anchor = 2
|
||||
infill_anchor_max = 12
|
||||
infill_every_layers = 1
|
||||
infill_extruder = 1
|
||||
infill_extrusion_width = 0.45
|
||||
infill_first = 0
|
||||
infill_overlap = 15%
|
||||
infill_speed = 200
|
||||
interface_shells = 0
|
||||
ironing_type = top
|
||||
layer_height = 0.2
|
||||
max_print_speed = 200
|
||||
max_volumetric_extrusion_rate_slope_negative = 0
|
||||
max_volumetric_extrusion_rate_slope_positive = 0
|
||||
max_volumetric_speed = 0
|
||||
min_bead_width = 85%
|
||||
min_feature_size = 25%
|
||||
min_skirt_length = 4
|
||||
mmu_segmented_region_max_width = 0
|
||||
only_retract_when_crossing_perimeters = 0
|
||||
ooze_prevention = 0
|
||||
output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
|
||||
overhang_speed_0 = 15
|
||||
overhang_speed_1 = 25
|
||||
overhang_speed_2 = 30
|
||||
overhang_speed_3 = 120
|
||||
overhangs = 1
|
||||
perimeter_acceleration = 4000
|
||||
perimeter_extruder = 1
|
||||
perimeter_extrusion_width = 0.45
|
||||
perimeter_generator = arachne
|
||||
perimeter_speed = 170
|
||||
perimeters = 2
|
||||
raft_contact_distance = 0.15
|
||||
raft_expansion = 1.5
|
||||
raft_first_layer_density = 80%
|
||||
raft_first_layer_expansion = 3.5
|
||||
seam_position = aligned
|
||||
slice_closing_radius = 0.049
|
||||
small_perimeter_speed = 170
|
||||
solid_infill_acceleration = 4000
|
||||
solid_infill_below_area = 0
|
||||
solid_infill_every_layers = 0
|
||||
solid_infill_extruder = 1
|
||||
solid_infill_extrusion_width = 0.45
|
||||
solid_infill_speed = 200
|
||||
skirts = 0
|
||||
support_material = 0
|
||||
support_material_angle = 0
|
||||
support_material_auto = 1
|
||||
support_material_bottom_contact_distance = 0
|
||||
support_material_bottom_interface_layers = 0
|
||||
support_material_buildplate_only = 0
|
||||
support_material_closing_radius = 2
|
||||
support_material_contact_distance = 0.2
|
||||
support_material_enforce_layers = 0
|
||||
support_material_extruder = 0
|
||||
support_material_extrusion_width = 0.36
|
||||
support_material_interface_contact_loops = 0
|
||||
support_material_interface_extruder = 0
|
||||
support_material_interface_layers = 0
|
||||
support_material_interface_pattern = auto
|
||||
support_material_interface_spacing = 0.2
|
||||
support_material_interface_speed = 50%
|
||||
support_material_pattern = rectilinear
|
||||
support_material_spacing = 2
|
||||
support_material_speed = 120
|
||||
support_material_style = organic
|
||||
support_material_synchronize_layers = 0
|
||||
support_material_threshold = 40
|
||||
support_material_with_sheath = 0
|
||||
support_material_xy_spacing = 80%
|
||||
support_tree_angle = 40
|
||||
support_tree_angle_slow = 25
|
||||
support_tree_branch_diameter = 2
|
||||
support_tree_branch_diameter_angle = 5
|
||||
support_tree_branch_diameter_double_wall = 3
|
||||
support_tree_branch_distance = 1
|
||||
support_tree_tip_diameter = 0.8
|
||||
support_tree_top_rate = 30%
|
||||
top_fill_pattern = monotoniclines
|
||||
top_infill_extrusion_width = 0.42
|
||||
top_solid_infill_acceleration = 1000
|
||||
top_solid_infill_speed = 100
|
||||
top_solid_layers = 5
|
||||
top_solid_min_thickness = 0
|
||||
travel_acceleration = 4000
|
||||
travel_speed = 300
|
||||
travel_speed_z = 12
|
||||
thick_bridges = 0
|
||||
thin_walls = 0
|
||||
compatible_printers_condition = printer_model=="MK4IS" and nozzle_diameter[0]==0.4
|
||||
|
||||
# XXXXXXxxXXXXXXXXXXXXXX
|
||||
# XXX--- filament ---XXX
|
||||
# XXXXXXXXxxXXXXXXXXXXXX
|
||||
@ -3618,7 +3759,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no
|
||||
compatible_printers_condition = ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) and printer_notes!~/.*PG.*/
|
||||
|
||||
[filament:*PLAPG*]
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.05{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.07{elsif nozzle_diameter[0]==0.35}0.06{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.015{else}0{endif} ; Filament gcode\n\nM142 S36 ; set heatbreak target temp"
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.05{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.07{elsif nozzle_diameter[0]==0.35}0.06{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.04{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
slowdown_below_layer_time = 8
|
||||
filament_cooling_final_speed = 2
|
||||
@ -3632,7 +3773,8 @@ filament_unloading_speed = 20
|
||||
filament_loading_speed_start = 19
|
||||
filament_minimal_purge_on_wipe_tower = 15
|
||||
filament_unloading_speed_start = 100
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 70
|
||||
full_fan_speed_layer = 3
|
||||
|
||||
[filament:*PLA06PG*]
|
||||
inherits = *PLAPG*
|
||||
@ -3675,7 +3817,7 @@ filament_max_volumetric_speed = 15
|
||||
[filament:*PETPG*]
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8
|
||||
filament_max_volumetric_speed = 10
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S40 ; set heatbreak target temp"
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.055{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
|
||||
filament_cooling_final_speed = 1
|
||||
filament_cooling_initial_speed = 2
|
||||
filament_cooling_moves = 1
|
||||
@ -3686,7 +3828,7 @@ filament_unload_time = 12
|
||||
filament_unloading_speed = 20
|
||||
filament_unloading_speed_start = 120
|
||||
filament_loading_speed_start = 19
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 70
|
||||
filament_retract_length = 1
|
||||
filament_retract_lift = 0.15
|
||||
filament_retract_before_wipe = 0
|
||||
@ -3823,7 +3965,7 @@ compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*
|
||||
[filament:*ABSPG*]
|
||||
compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8
|
||||
filament_max_volumetric_speed = 12
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.04{elsif nozzle_diameter[0]==0.25}0.1{elsif nozzle_diameter[0]==0.3}0.06{elsif nozzle_diameter[0]==0.35}0.05{elsif nozzle_diameter[0]==0.5}0.03{elsif nozzle_diameter[0]==0.6}0.02{elsif nozzle_diameter[0]==0.8}0.01{else}0{endif} ; Filament gcode\n\nM142 S40 ; set heatbreak target temp"
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.04{elsif nozzle_diameter[0]==0.25}0.1{elsif nozzle_diameter[0]==0.3}0.06{elsif nozzle_diameter[0]==0.35}0.05{elsif nozzle_diameter[0]==0.5}0.03{elsif nozzle_diameter[0]==0.6}0.02{elsif nozzle_diameter[0]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.02{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
|
||||
filament_cooling_final_speed = 50
|
||||
filament_cooling_initial_speed = 10
|
||||
filament_cooling_moves = 5
|
||||
@ -3833,7 +3975,7 @@ filament_load_time = 15
|
||||
filament_unload_time = 12
|
||||
filament_loading_speed = 14
|
||||
filament_unloading_speed = 20
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 100
|
||||
|
||||
[filament:*ABS06PG*]
|
||||
inherits = *ABSPG*
|
||||
@ -3848,7 +3990,7 @@ slowdown_below_layer_time = 25
|
||||
|
||||
[filament:*ABSMK4*]
|
||||
inherits = *ABSPG*
|
||||
compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8
|
||||
compatible_printers_condition = printer_model=~/(MK4|MK4IS)/ and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8
|
||||
|
||||
[filament:*ABS06MK4*]
|
||||
inherits = *ABSMK4*
|
||||
@ -3864,10 +4006,10 @@ slowdown_below_layer_time = 25
|
||||
[filament:*PCPG*]
|
||||
inherits = *ABSPG*
|
||||
filament_max_volumetric_speed = 8
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.05{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
first_layer_bed_temperature = 100
|
||||
bed_temperature = 105
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 150
|
||||
|
||||
[filament:*PC06PG*]
|
||||
inherits = *PCPG*
|
||||
@ -3882,8 +4024,8 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8
|
||||
[filament:*PCMK4*]
|
||||
inherits = *ABSMK4*
|
||||
filament_max_volumetric_speed = 8
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
## idle_temperature = 170
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.05{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
idle_temperature = 150
|
||||
|
||||
[filament:*PC06MK4*]
|
||||
inherits = *PCMK4*
|
||||
@ -3898,9 +4040,9 @@ compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8
|
||||
[filament:*PAPG*]
|
||||
inherits = *ABSPG*
|
||||
filament_max_volumetric_speed = 5
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.05{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
bed_temperature = 105
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 150
|
||||
|
||||
[filament:*PA06PG*]
|
||||
inherits = *PAPG*
|
||||
@ -3915,8 +4057,8 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8
|
||||
[filament:*PAMK4*]
|
||||
inherits = *ABSMK4*
|
||||
filament_max_volumetric_speed = 5
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
## idle_temperature = 170
|
||||
start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*PRINTER_MODEL_MK4IS.*/}\nM572 S{if nozzle_diameter[0]==0.4}0.05{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp\n"
|
||||
idle_temperature = 70
|
||||
|
||||
[filament:*PA06MK4*]
|
||||
inherits = *PAMK4*
|
||||
@ -3959,7 +4101,7 @@ filament_retract_speed = 60
|
||||
filament_deretract_speed = 20
|
||||
filament_retract_before_travel = 2
|
||||
compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]>=0.3 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 70
|
||||
start_filament_gcode = "M900 K0 ; Filament gcode\n\nM142 S36 ; set heatbreak target temp"
|
||||
|
||||
[filament:*FLEX06PG*]
|
||||
@ -3978,7 +4120,7 @@ filament_retract_speed = 60
|
||||
filament_deretract_speed = 20
|
||||
filament_retract_before_travel = 2
|
||||
compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]>=0.3 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8
|
||||
## idle_temperature = 170
|
||||
idle_temperature = 70
|
||||
start_filament_gcode = "M900 K0 ; Filament gcode\n\nM142 S36 ; set heatbreak target temp"
|
||||
|
||||
[filament:*FLEX06MK4*]
|
||||
@ -4950,6 +5092,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MK2S
|
||||
|
||||
[filament:Generic PETG @PG]
|
||||
inherits = Generic PETG; *PETPG*
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model!="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Generic PETG @PG 0.6]
|
||||
inherits = Generic PETG; *PET06PG*
|
||||
@ -4960,6 +5103,19 @@ inherits = Generic PETG; *PET08PG*
|
||||
first_layer_temperature = 240
|
||||
temperature = 250
|
||||
|
||||
[filament:Generic PETG @MK4IS]
|
||||
inherits = Generic PETG @PG
|
||||
filament_max_volumetric_speed = 13
|
||||
min_fan_speed = 35
|
||||
max_fan_speed = 60
|
||||
first_layer_temperature = 240
|
||||
temperature = 245
|
||||
filament_retract_length = 0.8
|
||||
filament_wipe = 1
|
||||
filament_retract_before_wipe = 20
|
||||
filament_retract_lift = nil
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Extrudr DuraPro ASA]
|
||||
inherits = Fillamentum ASA
|
||||
filament_vendor = Extrudr
|
||||
@ -5870,6 +6026,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG
|
||||
|
||||
[filament:Generic PLA @PG]
|
||||
inherits = Generic PLA; *PLAPG*
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model!="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Generic PLA @PG 0.6]
|
||||
inherits = Generic PLA; *PLA06PG*
|
||||
@ -5880,6 +6037,21 @@ inherits = Generic PLA; *PLA08PG*
|
||||
first_layer_temperature = 220
|
||||
temperature = 220
|
||||
|
||||
[filament:Generic PLA @MK4IS]
|
||||
inherits = Generic PLA @PG
|
||||
first_layer_temperature = 230
|
||||
temperature = 220
|
||||
slowdown_below_layer_time = 5
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Generic PLA Silk @MK4IS]
|
||||
inherits = Generic PLA @PG
|
||||
first_layer_temperature = 230
|
||||
temperature = 220
|
||||
slowdown_below_layer_time = 8
|
||||
filament_max_volumetric_speed = 7
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:3D-Fuel Standard PLA]
|
||||
inherits = *PLA*
|
||||
filament_vendor = 3D-Fuel
|
||||
@ -8218,6 +8390,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=
|
||||
|
||||
[filament:Prusa PETG @PG]
|
||||
inherits = Prusa PETG; *PETPG*
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model!="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusa PETG @PG 0.6]
|
||||
inherits = Prusa PETG; *PET06PG*
|
||||
@ -8225,6 +8398,19 @@ inherits = Prusa PETG; *PET06PG*
|
||||
[filament:Prusa PETG @PG 0.8]
|
||||
inherits = Prusa PETG; *PET08PG*
|
||||
|
||||
[filament:Prusa PETG @MK4IS]
|
||||
inherits = Generic PETG @PG
|
||||
filament_max_volumetric_speed = 15
|
||||
min_fan_speed = 35
|
||||
max_fan_speed = 60
|
||||
first_layer_temperature = 240
|
||||
temperature = 250
|
||||
filament_retract_length = 0.8
|
||||
filament_wipe = 1
|
||||
filament_retract_before_wipe = 20
|
||||
filament_retract_lift = nil
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Verbatim PETG]
|
||||
inherits = *PET*
|
||||
filament_vendor = Verbatim
|
||||
@ -8255,6 +8441,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=
|
||||
|
||||
[filament:Prusament PETG @PG]
|
||||
inherits = Prusament PETG; *PETPG*
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model!="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusament PETG @PG 0.6]
|
||||
inherits = Prusament PETG; *PET06PG*
|
||||
@ -8264,6 +8451,17 @@ inherits = Prusament PETG; *PET08PG*
|
||||
first_layer_temperature = 250
|
||||
temperature = 260
|
||||
|
||||
[filament:Prusament PETG @MK4IS]
|
||||
inherits = Prusament PETG @PG
|
||||
filament_max_volumetric_speed = 15
|
||||
min_fan_speed = 35
|
||||
max_fan_speed = 60
|
||||
filament_retract_length = 0.8
|
||||
filament_wipe = 1
|
||||
filament_retract_before_wipe = 20
|
||||
filament_retract_lift = nil
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusament PETG Carbon Fiber]
|
||||
inherits = Prusament PETG
|
||||
filament_vendor = Prusa Polymers
|
||||
@ -8484,6 +8682,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG
|
||||
|
||||
[filament:Prusa PLA @PG]
|
||||
inherits = Prusa PLA; *PLAPG*
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model!="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusa PLA @PG 0.6]
|
||||
inherits = Prusa PLA; *PLA06PG*
|
||||
@ -8492,6 +8691,14 @@ filament_max_volumetric_speed = 15.5
|
||||
[filament:Prusa PLA @PG 0.8]
|
||||
inherits = Prusa PLA; *PLA08PG*
|
||||
|
||||
[filament:Prusa PLA @MK4IS]
|
||||
inherits = Prusa PLA @PG
|
||||
first_layer_temperature = 230
|
||||
temperature = 220
|
||||
slowdown_below_layer_time = 5
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
|
||||
[filament:Eolas Prints PLA]
|
||||
inherits = *PLA*
|
||||
filament_vendor = Eolas Prints
|
||||
@ -9595,6 +9802,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG
|
||||
|
||||
[filament:Prusament PLA @PG]
|
||||
inherits = Prusament PLA; *PLAPG*
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model!="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusament PLA @PG 0.6]
|
||||
inherits = Prusament PLA; *PLA06PG*
|
||||
@ -9605,6 +9813,21 @@ inherits = Prusament PLA; *PLA08PG*
|
||||
first_layer_temperature = 225
|
||||
temperature = 225
|
||||
|
||||
[filament:Prusament PLA @MK4IS]
|
||||
inherits = Prusament PLA @PG
|
||||
first_layer_temperature = 230
|
||||
temperature = 225
|
||||
slowdown_below_layer_time = 5
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusament PLA Blend @MK4IS]
|
||||
inherits = Prusament PLA @PG
|
||||
first_layer_temperature = 230
|
||||
temperature = 220
|
||||
filament_max_volumetric_speed = 7
|
||||
slowdown_below_layer_time = 7
|
||||
compatible_printers_condition = printer_notes=~/.*PG.*/ and printer_model=="MK4IS" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusament PVB]
|
||||
inherits = *PLA*
|
||||
filament_vendor = Prusa Polymers
|
||||
@ -15970,6 +16193,41 @@ min_layer_height = 0.2
|
||||
default_print_profile = 0.40mm QUALITY @MK4 0.8
|
||||
default_filament_profile = "Prusament PLA @PG 0.8"
|
||||
|
||||
[printer:Original Prusa MK4 Input Shaper (Alpha)]
|
||||
inherits = *commonMK4*
|
||||
printer_model = MK4IS
|
||||
printer_variant = 0.4
|
||||
max_layer_height = 0.30
|
||||
machine_limits_usage = emit_to_gcode
|
||||
machine_max_acceleration_e = 2500,5000
|
||||
machine_max_acceleration_extruding = 4000,2000
|
||||
machine_max_acceleration_retracting = 1200,2000
|
||||
machine_max_acceleration_travel = 4000,1250
|
||||
machine_max_acceleration_x = 4000,2000
|
||||
machine_max_acceleration_y = 4000,2000
|
||||
machine_max_acceleration_z = 200,2000
|
||||
machine_max_feedrate_e = 100,120
|
||||
machine_max_feedrate_x = 300,100
|
||||
machine_max_feedrate_y = 300,100
|
||||
machine_max_feedrate_z = 40,12
|
||||
machine_max_jerk_e = 10,1.5
|
||||
machine_max_jerk_x = 8,8
|
||||
machine_max_jerk_y = 8,8
|
||||
machine_max_jerk_z = 2,0.4
|
||||
machine_min_extruding_rate = 0,0
|
||||
machine_min_travel_rate = 0,0
|
||||
max_print_height = 220
|
||||
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_MODEL_MK4IS\nPG
|
||||
retract_length = 0.7
|
||||
wipe = 0
|
||||
retract_speed = 35
|
||||
deretract_speed = 0
|
||||
start_gcode = M17 ; enable steppers\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM862.3 P "MK4" ; printer model check\nM862.5 P2 ; g-code level check\nM862.6 P"Input shaper" ; firmware feature check\n\nM555 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} W{((min(print_bed_max[0], max(first_layer_print_min[0] + 32, first_layer_print_max[0])))) - ((min(print_bed_max[0], first_layer_print_min[0] + 32) - 32))} H{((first_layer_print_max[1])) - ((max(0, first_layer_print_min[1]) - 4))}\n\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\n\nM140 S[first_layer_bed_temperature] ; set bed temp\n{if filament_type[initial_tool]=="PC" or filament_type[initial_tool]=="PA"}\nM104 S{first_layer_temperature[initial_tool]-25} ; set extruder temp for bed leveling\nM109 R{first_layer_temperature[initial_tool]-25} ; wait for temp\n{elsif filament_type[initial_tool]=="FLEX"}\nM104 S210 ; set extruder temp for bed leveling\nM109 R210 ; wait for temp\n{else}\nM104 S170 ; set extruder temp for bed leveling\nM109 R170 ; wait for temp\n{endif}\n\nM84 E ; turn off E motor\n\nG28 ; home all without mesh bed level\n\n; probe to clean the nozzle\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)+32} Y{((first_layer_print_min[1]) - 4)} Z{5} F4800\n\nM302 S160 ; lower cold extrusion limit to 160C\n\n{if filament_type[initial_tool]=="FLEX"}\nG1 E-4 F2400 ; retraction\n{else}\nG1 E-2 F2400 ; retraction\n{endif}\n\nM84 E ; turn off E motor\n\nG29 P9 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} W{32} H{4}\n\n{if first_layer_bed_temperature[initial_tool]<=60}M106 S100{endif}\n\nG0 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} Z{40} F10000\n\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\nM107\n\n;\n; MBL\n;\nM84 E ; turn off E motor\nG29 ; mesh bed leveling\nM104 S[first_layer_temperature] ; set extruder temp\nG0 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4) + 4 - 4.5} Z{30} F4800\n\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.2 F720\nG92 E0\n\nM569 S0 E ; set spreadcycle mode for extruder\n\n;\n; Extrude purge line\n;\n{if filament_type[initial_tool]=="FLEX"}\nG1 E4 F2400 ; deretraction\n{else}\nG1 E2 F2400 ; deretraction\n{endif}\n\n; move right\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32) + 32} E{32 * 0.15} F1000\n; move down\nG1 Y{(max(0, first_layer_print_min[1]) - 4) + 4 - 4.5 - 1.5} E{1.5 * 0.15} F1000\n; move left\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} E{32 * 0.30} F800\n\nG92 E0\nM221 S100 ; set flow to 100%\n\nM593 X T2 F50.7\nM593 Y T2 F40.6
|
||||
end_gcode = {if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X241 Y170 F3600 ; park\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+23, max_print_height)} F300 ; Move print head up{endif}\nG4 ; wait\nM572 S0 ; reset PA\nM593 X T2 F0 ; disable IS\nM593 Y T2 F0 ; disable IS\nM84 X Y E ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\nM593 Y T2 F{interpolate_table(extruded_weight_total, (0,40), (300,30), (800,20), (10000,20)) }\nM201 X{interpolate_table(extruded_weight_total, (0,4000), (1400,2500), (10000,2500))} Y{interpolate_table(extruded_weight_total, (0,4000), (1400,2500), (10000,2500))}\nM74 W[extruded_weight_total]
|
||||
default_print_profile = 0.20mm Input Shaper @MK4IS 0.4
|
||||
default_filament_profile = "Prusament PLA @MK4IS"
|
||||
|
||||
[printer:Original Prusa SL1]
|
||||
printer_technology = SLA
|
||||
printer_model = SL1
|
||||
|
BIN
resources/profiles/PrusaResearch/MK4IS_thumbnail.png
Normal file
BIN
resources/profiles/PrusaResearch/MK4IS_thumbnail.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
109
resources/profiles/PrusaResearch/mk4is.svg
Normal file
109
resources/profiles/PrusaResearch/mk4is.svg
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="svg3128" xmlns="http://www.w3.org/2000/svg" width="710.1" height="596.7" viewBox="0 0 710.1 596.7">
|
||||
<line id="line2794" x1=".7" y1=".7" x2=".7" y2="596" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2796" x1="142.4" y1=".7" x2="142.4" y2="595.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2798" x1="284.2" y1=".7" x2="284.2" y2="595.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2800" x1="709.4" y1="596" x2="709.4" y2=".7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2802" x1="1.2" y1="581.8" x2="709.4" y2="581.8" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2804" x1=".7" y1="596" x2="709.4" y2="596" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2806" x1="1.2" y1="440.1" x2="709.4" y2="440.1" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2808" x1="1.2" y1="298.4" x2="709.4" y2="298.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2810" x1="1.2" y1="156.6" x2="709.4" y2="156.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2812" x1="1.2" y1="14.9" x2="709.4" y2="14.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2814" x1="709.4" y1=".7" x2=".7" y2=".7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2816" x1="425.9" y1=".7" x2="425.9" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2818" x1="425.9" y1="522.5" x2="425.9" y2="595.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2820" x1="567.6" y1=".7" x2="567.6" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2822" x1="567.6" y1="522.5" x2="567.6" y2="527.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2824" x1="567.6" y1="548.6" x2="567.6" y2="595.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.4px;"/>
|
||||
<line id="line2826" x1="85.8" y1=".7" x2="85.8" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2828" x1="114.1" y1=".7" x2="114.1" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2830" x1="170.8" y1=".7" x2="170.8" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2832" x1="199.1" y1=".7" x2="199.1" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2834" x1="227.5" y1=".7" x2="227.5" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2836" x1="255.8" y1=".7" x2="255.8" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2838" x1="312.5" y1=".7" x2="312.5" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2840" x1="340.9" y1=".7" x2="340.9" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2842" x1="681" y1=".7" x2="681" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2844" x1="29.1" y1=".7" x2="29.1" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2846" x1="57.4" y1=".7" x2="57.4" y2="595.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2848" x1="1.5" y1="468.4" x2="709.4" y2="468.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2850" x1="1.5" y1="496.8" x2="709.4" y2="496.8" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2852" x1="1.5" y1="525.1" x2="709.4" y2="525.1" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2854" x1="1.5" y1="553.5" x2="709.4" y2="553.5" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2856" x1="1.5" y1="411.7" x2="709.4" y2="411.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2858" x1="1.5" y1="383.4" x2="709.4" y2="383.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2860" x1="1.5" y1="355" x2="709.4" y2="355" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2862" x1="1.5" y1="326.7" x2="709.4" y2="326.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2864" x1="1.5" y1="270" x2="709.4" y2="270" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2866" x1="1.5" y1="241.6" x2="709.4" y2="241.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2868" x1="1.5" y1="213.3" x2="709.4" y2="213.3" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2870" x1="1.5" y1="185" x2="709.4" y2="185" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2872" x1="1.5" y1="128.3" x2="709.4" y2="128.3" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2874" x1="1.5" y1="99.9" x2="709.4" y2="99.9" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2876" x1="1.5" y1="71.6" x2="709.4" y2="71.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2878" x1="1.5" y1="43.2" x2="709.4" y2="43.2" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2880" x1="369.2" y1=".7" x2="369.2" y2="522.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2882" x1="369.2" y1="522.6" x2="369.2" y2="595.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2884" x1="397.6" y1=".7" x2="397.6" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2886" x1="397.5" y1="522.6" x2="397.5" y2="595.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2888" x1="454.2" y1=".7" x2="454.2" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2890" x1="454.3" y1="522.6" x2="454.3" y2="595.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2892" x1="482.6" y1=".7" x2="482.6" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2894" x1="482.6" y1="522.6" x2="482.6" y2="595.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2896" x1="510.9" y1=".7" x2="510.9" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2898" x1="510.9" y1="522.6" x2="510.9" y2="595.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2900" x1="539.3" y1=".7" x2="539.3" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2902" x1="539.3" y1="522.6" x2="539.3" y2="595.6" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2904" x1="596" y1=".7" x2="596" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2906" x1="624.3" y1=".7" x2="624.3" y2="499.4" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2908" x1="652.7" y1=".7" x2="652.7" y2="522.5" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2910" x1="652.7" y1="522.5" x2="652.7" y2="527.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2912" x1="652.6" y1="548.3" x2="652.6" y2="596" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2914" x1="624.3" y1="522.5" x2="624.3" y2="527.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2916" x1="624.3" y1="548.3" x2="624.3" y2="596" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2918" x1="596" y1="522.5" x2="596" y2="527.7" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<line id="line2920" x1="596" y1="548.3" x2="596" y2="596" style="fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; stroke-width: .4px;"/>
|
||||
<path id="path3098" d="m548.6,532h2.1v4.8h0c.1-.2.3-.4.5-.6.2-.2.4-.3.7-.5.2-.1.5-.2.8-.3.3,0,.5-.1.8,0,.7,0,1.3.1,1.9.4.5.2,1,.6,1.4,1.1.4.5.6,1,.8,1.6.2.6.3,1.3.3,1.9,0,.6,0,1.2-.2,1.8-.2.6-.4,1.1-.7,1.6-.7,1-1.8,1.5-3,1.5-.3,0-.6,0-1,0-.3,0-.6-.1-.9-.2-.3-.1-.5-.3-.8-.5-.2-.2-.4-.5-.6-.8h0v1.3h-2v-12.9Zm7.2,8.2c0-.4,0-.8-.2-1.2-.1-.4-.3-.7-.5-1-.2-.3-.5-.6-.8-.7-.3-.2-.7-.3-1.1-.3-.8,0-1.5.3-2,.9-.5.7-.7,1.6-.7,2.4,0,.4,0,.9.2,1.3.1.4.3.7.5,1,.2.3.5.5.8.7.3.2.7.3,1.1.2.4,0,.8,0,1.2-.3.3-.2.6-.4.8-.7.2-.3.4-.7.5-1,0-.4.1-.8.1-1.2Z" style="fill: #fff;"/>
|
||||
<path id="path3100" d="m558.5,535.6h2.2l2.4,7h0l2.4-7h2.1l-3.6,9.8c-.2.4-.3.8-.5,1.2-.2.4-.4.7-.6,1-.2.3-.5.5-.9.7-.4.2-.9.3-1.3.3-.5,0-1,0-1.4-.1v-1.7h.5c.2,0,.3,0,.5,0,.2,0,.4,0,.6,0,.1,0,.3-.1.4-.3.1-.1.2-.3.3-.4,0-.2.1-.4.2-.5l.2-.7-3.5-9.2Z" style="fill: #fff;"/>
|
||||
<path id="path3102" d="m581.1,540.8c0,.5,0,1.1-.1,1.6,0,.5-.3,1-.6,1.4-.3.4-.8.8-1.3,1-.7.3-1.5.4-2.2.4-.6,0-1.2,0-1.7-.3-.5-.2-.9-.5-1.2-.9-.3-.4-.6-.8-.7-1.3-.1-.5-.2-1.1-.2-1.6v-.7h2.2v.7c0,.6,0,1.2.4,1.7.3.4.9.7,1.4.6.3,0,.6,0,.9-.2.2-.1.4-.3.6-.5.1-.2.2-.5.3-.8,0-.4,0-.7,0-1.1v-8.8h2.2v8.7Z" style="fill: #fff;"/>
|
||||
<path id="path3104" d="m587.8,545.1c-.7,0-1.4-.1-2-.4-.6-.2-1.1-.6-1.5-1-.4-.4-.7-1-.9-1.5-.2-.6-.3-1.3-.3-2,0-.7,0-1.4.3-2,.2-.6.5-1.1.9-1.5.4-.4.9-.8,1.5-1,1.3-.5,2.7-.5,4,0,.6.2,1.1.6,1.5,1,.4.4.7,1,.9,1.5.2.6.3,1.3.3,2,0,.7,0,1.4-.3,2-.2.6-.5,1.1-.9,1.5-.4.4-.9.8-1.5,1-.6.3-1.3.4-2,.4Zm0-1.6c.4,0,.8,0,1.2-.3.3-.2.6-.4.8-.8.2-.3.4-.7.5-1.1.1-.4.2-.8.2-1.2,0-.4,0-.8-.2-1.2,0-.4-.3-.7-.5-1-.2-.3-.5-.6-.8-.8-.7-.4-1.6-.4-2.4,0-.3.2-.6.4-.8.8-.2.3-.4.6-.5,1,0,.4-.1.8-.2,1.2,0,.4,0,.8.2,1.2,0,.4.3.7.5,1.1.2.3.5.6.8.8.4.2.8.3,1.2.3h0Z" style="fill: #fff;"/>
|
||||
<path id="path3106" d="m595.7,541.9c0,.5.3,1,.7,1.3.4.2.9.4,1.4.4.2,0,.4,0,.7,0,.2,0,.5,0,.7-.2.2,0,.4-.2.5-.4.3-.4.2-.9,0-1.3-.2-.2-.4-.3-.7-.4-.3-.1-.7-.2-1-.3l-1.1-.2c-.4,0-.7-.2-1.1-.3-.4-.1-.7-.3-1-.5-.3-.2-.5-.5-.6-.9-.2-.4-.3-.8-.2-1.2,0-.5.1-.9.4-1.3.2-.3.6-.6.9-.8.4-.2.8-.4,1.3-.4.4,0,.9-.1,1.3-.1.5,0,.9,0,1.4.2.4,0,.8.3,1.2.5.4.2.7.5.9.9.2.4.4.9.4,1.3h-2.1c0-.4-.3-.8-.7-1-.4-.2-.8-.3-1.2-.2-.2,0-.3,0-.5,0-.2,0-.4,0-.6.1-.2,0-.3.2-.4.3-.1.1-.2.3-.2.5,0,.2,0,.5.3.6.2.2.4.3.7.4.3.1.7.2,1,.3l1.1.2c.4,0,.7.2,1.1.3.4.1.7.3,1,.5.3.2.5.5.7.8.2.4.3.8.3,1.2,0,.5-.1,1-.4,1.4-.3.4-.6.7-1,.9-.4.2-.9.4-1.3.5-.5.1-1,.2-1.5.2-.5,0-1.1,0-1.6-.2-.5-.1-.9-.3-1.3-.6-.4-.3-.7-.6-.9-1-.2-.4-.3-.9-.3-1.4h2Z" style="fill: #fff;"/>
|
||||
<path id="path3108" d="m605.1,540.8c0,.3,0,.7.2,1,0,.3.3.6.5.9.2.3.5.5.8.6.4.2.7.2,1.1.2.5,0,1.1,0,1.5-.3.4-.3.7-.7.8-1.2h1.9c0,.5-.3.9-.6,1.3-.3.4-.6.7-1,1-.4.3-.8.5-1.2.6-.5.1-1,.2-1.5.2-.7,0-1.3-.1-1.9-.4-.5-.2-1-.6-1.4-1-.4-.4-.7-1-.9-1.5-.2-.6-.3-1.3-.3-2,0-.6.1-1.3.3-1.9.2-.6.5-1.1.9-1.6.8-1,2-1.5,3.3-1.5.7,0,1.4.1,2,.5.6.3,1.1.7,1.5,1.2.4.5.7,1.1.8,1.7.2.7.2,1.3.1,2h-6.9Zm4.8-1.3c0-.3,0-.6-.2-.9-.1-.3-.3-.6-.5-.8-.2-.2-.4-.4-.7-.5-.3-.1-.6-.2-.9-.2-.3,0-.7,0-1,.2-.3.1-.5.3-.8.5-.2.2-.4.5-.5.8-.1.3-.2.7-.2,1h4.8Z" style="fill: #fff;"/>
|
||||
<path id="path3110" d="m612.6,535.6h1.5v-.8c0-.5,0-1,.2-1.4.1-.3.3-.6.6-.8.2-.2.5-.3.8-.4.3,0,.7-.1,1,0,.5,0,.9,0,1.4,0v1.6c-.1,0-.3,0-.4,0h-.5c-.3,0-.5,0-.7.2-.2.2-.3.5-.3.8v1h1.7v1.5h-1.7v7.8h-2v-7.8h-1.5v-1.5Z" style="fill: #fff;"/>
|
||||
<path id="path3112" d="m624.5,532h5.7c.8,0,1.5.1,2.2.4.5.2,1,.6,1.3,1,.3.4.5.8.6,1.3.1.4.2.9.2,1.3,0,.4,0,.9-.2,1.3-.1.5-.3.9-.6,1.3-.4.4-.8.8-1.3,1-.7.3-1.5.4-2.2.4h-3.4v4.9h-2.2v-12.9Zm2.2,6.1h3.3c.3,0,.5,0,.8-.1.3,0,.5-.2.7-.3.2-.2.4-.4.5-.7.1-.3.2-.7.2-1,0-.3,0-.7-.2-1-.2-.5-.7-.9-1.2-1-.3,0-.6,0-.8,0h-3.3v4.2Z" style="fill: #fff;"/>
|
||||
<path id="path3114" d="m636.2,535.6h1.9v1.8h0c0-.3.2-.5.4-.7.2-.2.4-.5.6-.7.2-.2.5-.4.8-.5.3-.1.6-.2.9-.2h.8v2h-.4c-.1,0-.3,0-.5,0-.7,0-1.3.3-1.8.8-.2.3-.4.6-.5,1-.1.4-.2.9-.2,1.4v4.4h-2v-9.3Z" style="fill: #fff;"/>
|
||||
<path id="path3116" d="m650.7,544.9h-2v-1.3h0c-.3.5-.7.9-1.1,1.1-.5.3-1,.4-1.5.4-1,0-1.9-.2-2.7-.9-.6-.8-.9-1.8-.8-2.7v-5.9h2v5.7c0,.6.1,1.2.5,1.7.3.3.8.5,1.3.5.4,0,.7,0,1.1-.2.3-.1.5-.3.7-.5.2-.2.3-.5.4-.8,0-.3.1-.7.1-1v-5.4h2v9.3Z" style="fill: #fff;"/>
|
||||
<path id="path3118" d="m654.4,541.9c0,.5.3,1,.7,1.2.4.2.9.4,1.4.4.2,0,.4,0,.7,0,.2,0,.5,0,.7-.2.2,0,.4-.2.5-.4.1-.2.2-.4.2-.6,0-.2-.1-.5-.3-.7-.2-.2-.4-.3-.7-.4-.3-.1-.7-.2-1-.3l-1.1-.2c-.4,0-.7-.2-1.1-.3-.4-.1-.7-.3-1-.5-.3-.2-.5-.5-.7-.8-.2-.4-.3-.8-.3-1.2,0-.5.1-.9.4-1.3.2-.3.6-.6.9-.8.4-.2.8-.4,1.3-.4.4,0,.9-.1,1.3-.1.5,0,.9,0,1.4.2.4.1.8.3,1.2.5.4.2.7.5.9.9.2.4.4.9.4,1.3h-2.1c0-.4-.3-.8-.7-1-.4-.2-.8-.3-1.2-.2-.2,0-.3,0-.5,0-.2,0-.4,0-.5.1-.2,0-.3.2-.4.3-.1.1-.2.3-.2.5,0,.2,0,.5.3.6.2.2.4.3.7.4.3.1.7.2,1,.3l1.1.2c.4,0,.7.2,1.1.3.4.1.7.3,1,.5.3.2.5.5.7.8.2.4.3.8.3,1.2,0,.5-.1,1-.4,1.4-.3.4-.6.7-1,.9-.4.2-.9.4-1.3.5-.5.1-1,.2-1.5.2-.6,0-1.1,0-1.6-.2-.5-.1-.9-.3-1.3-.6-.4-.3-.7-.6-.9-1-.2-.4-.3-.9-.3-1.4h2.1Z" style="fill: #fff;"/>
|
||||
<path id="path3120" d="m670,542.8c0,.2,0,.4,0,.5,0,.1.2.2.4.2h.5v1.4h-.3c0,0-.3.2-.3.2h-.4c-.1,0-.2,0-.3,0-.3,0-.7,0-1-.2-.3-.2-.5-.5-.5-.9-.4.4-.9.7-1.5.9-.6.2-1.1.3-1.7.3-.4,0-.8,0-1.2-.2-.4-.1-.7-.3-1-.5-.3-.2-.5-.5-.7-.8-.2-.4-.3-.8-.3-1.2,0-.5,0-1,.3-1.4.2-.3.5-.6.8-.8.4-.2.7-.4,1.2-.4.4,0,.9-.2,1.3-.2.3,0,.7-.1,1.1-.2.3,0,.6,0,.9-.2.2,0,.4-.2.6-.3.2-.2.2-.4.2-.7,0-.2,0-.5-.2-.7-.1-.2-.3-.3-.5-.4-.2,0-.4-.2-.6-.2-.2,0-.4,0-.7,0-.5,0-1,.1-1.4.4-.4.3-.6.7-.6,1.1h-2c0-.5.2-1,.4-1.5.3-.4.6-.7,1-1,.4-.2.9-.4,1.3-.5.5-.1,1-.2,1.5-.2.5,0,.9,0,1.3.2.4,0,.8.2,1.2.5.3.2.6.5.8.8.2.4.3.8.3,1.2v4.8Zm-2.1-2.6c-.3.2-.7.3-1.2.4-.5,0-.9.1-1.4.2-.2,0-.4,0-.6.2-.2,0-.4.1-.5.3-.2.1-.3.3-.4.5,0,.2-.1.4-.1.7,0,.2,0,.4.2.6.1.2.3.3.5.4.2,0,.4.2.6.2.2,0,.4,0,.6,0,.2,0,.5,0,.7,0,.3,0,.5-.2.8-.3.2-.1.4-.3.6-.5.2-.2.2-.5.2-.8v-1.5Z" style="fill: #fff;"/>
|
||||
<g>
|
||||
<path d="m385.6,511.3c0-1.3.2-2.6.6-3.7s1-2.1,1.7-3c.7-.9,1.7-1.5,2.8-2,1.1-.5,2.3-.7,3.7-.7s2.6.2,3.7.7c1.1.5,2,1.2,2.8,2s1.3,1.8,1.7,3,.6,2.4.6,3.7-.2,2.5-.6,3.6-1,2.1-1.7,2.9c-.7.8-1.7,1.5-2.8,2-1.1.5-2.3.7-3.7.7s-2.6-.2-3.7-.7c-1.1-.5-2-1.1-2.8-2-.7-.8-1.3-1.8-1.7-2.9-.4-1.1-.6-2.3-.6-3.6Zm3.9,0c0,.7.1,1.5.3,2.2.2.7.4,1.3.9,1.9.4.6.9,1,1.5,1.4s1.4.5,2.2.5,1.6-.2,2.2-.5,1.1-.8,1.5-1.4c.4-.6.6-1.2.9-1.9.2-.7.3-1.4.3-2.2s-.1-1.5-.3-2.3c-.2-.7-.4-1.4-.9-1.9-.4-.6-.9-1-1.5-1.4-.6-.3-1.4-.5-2.2-.5s-1.6.2-2.2.5c-.6.3-1.1.8-1.5,1.4s-.6,1.2-.9,1.9c-.2.7-.3,1.5-.3,2.3Z" style="fill: #959998;"/>
|
||||
<path d="m404.8,502.3h9.6c.8,0,1.5.1,2.1.4.6.3,1.2.6,1.6,1.1.4.4.8,1,1.1,1.6.2.6.4,1.2.4,1.9,0,1.1-.2,1.9-.6,2.7-.4.7-1.2,1.4-2.1,1.7h0c.5.2.9.4,1.2.6s.6.6.8,1c.2.4.3.8.4,1.2s.2.9.2,1.3,0,.6,0,1,0,.8.1,1.2c0,.4.1.8.2,1.1.1.4.2.7.4.9h-3.9c-.1-.3-.2-.6-.3-.9,0-.3-.1-.7-.1-1.1s0-.7-.1-1.2c0-.4,0-.7-.1-1.1-.1-.9-.4-1.6-.9-2s-1.1-.6-2.1-.6h-3.9v6.9h-3.9v-17.7Zm3.9,8.1h4.3c.9,0,1.6-.2,2-.6.4-.4.7-1.1.7-1.9s-.2-1.5-.7-1.9-1.1-.6-2-.6h-4.3v5Z" style="fill: #959998;"/>
|
||||
<path d="m421.8,502.3h3.9v17.8h-3.9v-17.8Z" style="fill: #959998;"/>
|
||||
<path d="m441,518.1c-.7.9-1.5,1.5-2.3,1.9s-1.7.5-2.6.5c-1.4,0-2.6-.2-3.7-.7-1.1-.5-2-1.1-2.8-2-.7-.8-1.3-1.8-1.7-2.9-.4-1.1-.6-2.3-.6-3.6s.2-2.6.6-3.7,1-2.1,1.7-3c.7-.9,1.7-1.5,2.8-2,1.1-.5,2.3-.7,3.7-.7s1.8.1,2.7.4c.9.3,1.6.7,2.3,1.2s1.3,1.2,1.7,2,.7,1.7.9,2.7h-3.7c-.2-1-.7-1.7-1.4-2.2s-1.5-.7-2.4-.7-1.6.2-2.2.5-1.1.8-1.5,1.4c-.4.6-.6,1.2-.9,1.9-.2.7-.3,1.5-.3,2.3s.1,1.5.3,2.2c.2.7.4,1.3.9,1.9.4.6.9,1,1.5,1.4.6.3,1.4.5,2.2.5,1.3,0,2.3-.3,3-1s1.1-1.6,1.3-2.9h-3.9v-2.9h7.5v9.6h-2.5l-.4-2Z" style="fill: #959998;"/>
|
||||
<path d="m446.3,502.3h3.9v17.8h-3.9v-17.8Z" style="fill: #959998;"/>
|
||||
<path d="m452.7,502.3h3.9l7.4,11.9h0v-11.9h3.7v17.8h-3.9l-7.4-11.9h0v11.9h-3.7v-17.8Z" style="fill: #959998;"/>
|
||||
<path d="m475.1,502.3h4l6.6,17.8h-4l-1.4-3.9h-6.6l-1.4,3.9h-3.9l6.7-17.8Zm-.4,10.9h4.6l-2.2-6.5h0l-2.3,6.5Z" style="fill: #959998;"/>
|
||||
<path d="m486.5,502.3h3.9v14.5h8.6v3.3h-12.6v-17.8h0Z" style="fill: #959998;"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="m506.9,502.3h8c1.1,0,2.1.2,2.8.5s1.4.7,1.9,1.3c.5.5.9,1.2,1.1,1.8.2.7.3,1.4.3,2.1s-.1,1.4-.3,2.1-.6,1.3-1.1,1.8c-.5.5-1.1,1-1.9,1.3s-1.7.5-2.8.5h-4.1v6.4h-3.9v-17.8Zm3.9,8.4h3c.4,0,.9,0,1.3-.1.4,0,.8-.2,1.1-.4.3-.2.6-.5.7-.8.2-.3.3-.8.3-1.4s-.1-1-.3-1.4c-.2-.3-.4-.6-.7-.8-.3-.2-.7-.3-1.1-.4s-.9-.1-1.3-.1h-3v5.3Z" style="fill: #fff;"/>
|
||||
<path d="m522.2,502.3h9.6c.8,0,1.5.1,2.1.4.6.3,1.2.6,1.6,1.1.4.4.8,1,1.1,1.6.2.6.4,1.2.4,1.9,0,1.1-.2,1.9-.6,2.7-.4.7-1.2,1.4-2.1,1.7h0c.5.2.9.4,1.2.6s.6.6.8,1c.2.4.3.8.4,1.2s.2.9.2,1.3,0,.6,0,1,0,.8.1,1.2c0,.4.1.8.2,1.1.1.4.2.7.4.9h-3.9c-.1-.3-.2-.6-.3-.9,0-.3-.1-.7-.1-1.1s0-.7-.1-1.2c0-.4,0-.7-.1-1.1-.1-.9-.4-1.6-.9-2s-1.1-.6-2.1-.6h-3.9v6.9h-3.9v-17.7Zm3.9,8.1h4.3c.9,0,1.5-.2,2-.6.4-.4.7-1.1.7-1.9s-.2-1.5-.7-1.9-1.1-.6-2-.6h-4.3v5Z" style="fill: #fff;"/>
|
||||
<path d="m554.1,513.3c0,2.4-.7,4.2-2,5.4-1.4,1.2-3.2,1.8-5.6,1.8s-4.3-.6-5.6-1.8c-1.3-1.2-2-3-2-5.4v-11.1h3.9v11.1c0,.5,0,1,.1,1.4,0,.5.3.9.5,1.3.3.4.6.6,1.1.9.5.2,1.1.3,1.9.3,1.4,0,2.3-.3,2.9-.9s.8-1.6.8-2.9v-11.1h3.9v11h0Z" style="fill: #fff;"/>
|
||||
<path d="m559.1,514.2c0,.6.1,1.1.3,1.5.2.4.5.7.9,1s.8.4,1.3.6,1,.2,1.5.2.7,0,1.1-.1.8-.2,1.1-.3.6-.4.9-.7c.2-.3.3-.6.3-1.1s-.2-.9-.5-1.2-.7-.5-1.2-.7c-.5-.2-1.1-.4-1.7-.5s-1.3-.3-1.9-.5c-.7-.2-1.3-.4-1.9-.6-.6-.2-1.2-.5-1.7-.9s-.9-.9-1.2-1.4c-.3-.6-.5-1.3-.5-2.1s.2-1.7.6-2.4.9-1.2,1.5-1.7,1.4-.8,2.1-1,1.6-.3,2.4-.3,1.8.1,2.7.3,1.6.5,2.3,1,1.2,1.1,1.6,1.8.6,1.6.6,2.6h-3.8c0-.5-.1-1-.3-1.3s-.4-.6-.7-.8-.7-.3-1.1-.4-.9-.1-1.3-.1-.6,0-1,.1c-.3,0-.6.2-.9.3-.3.2-.5.4-.6.6s-.2.6-.2.9,0,.6.2.9c.1.2.4.4.8.6s.9.4,1.6.5c.7.2,1.6.4,2.7.7.2,0,.5.1.9.2.3.1.7.2,1.1.4.4.2.8.4,1.2.6.4.2.7.5,1.1.9.3.4.6.8.8,1.3.2.5.3,1.1.3,1.8s-.2,1.6-.5,2.3c-.3.7-.8,1.3-1.4,1.8s-1.4.9-2.3,1.2c-.9.3-2,.4-3.2.4s-1.9-.1-2.9-.4-1.7-.6-2.4-1.2-1.3-1.2-1.7-2c-.4-.8-.6-1.7-.6-2.8h3.8Z" style="fill: #fff;"/>
|
||||
<path d="m576.5,502.3h4l6.6,17.8h-4l-1.4-3.9h-6.6l-1.4,3.9h-3.9l6.7-17.8Zm-.4,10.9h4.6l-2.2-6.5h0l-2.3,6.5Z" style="fill: #fff;"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="m594.3,502.3h5.5l4.1,12.2h0l3.9-12.2h5.5v17.8h-3.7v-12.6h0l-4.4,12.6h-3l-4.4-12.5h0v12.5h-3.7v-17.8h0Z" style="fill: #ed6b21;"/>
|
||||
<path d="m616,502.3h3.9v7.4l6.9-7.4h4.9l-6.9,7,7.6,10.7h-4.9l-5.3-8-2.2,2.3v5.7h-3.9v-17.8Z" style="fill: #ed6b21;"/>
|
||||
<path d="m638.4,516.1h-7.4v-3.2l7.6-10.2h3.2v10.5h2.3v2.9h-2.3v4h-3.4v-4h0Zm0-9h0l-4.5,6.1h4.6v-6.1Z" style="fill: #ed6b21;"/>
|
||||
</g>
|
||||
<rect x="385.6" y="528.9" width="54.9" height="21" style="fill: #ff3c00;"/>
|
||||
<g>
|
||||
<path d="m401.3,545.4c0,.2,0,.4-.2.4h-2c-.2,0-.4,0-.4-.3l-.4-1.7h-3.2l-.4,1.7c0,.2-.2.3-.4.3h-2c-.2,0-.3-.1-.2-.4l3.3-11.9c0-.2.2-.3.4-.3h1.7c.2,0,.3,0,.4.3l3.3,11.9Zm-4.5-9.2l-.2,1.2-.9,4.2h2.2l-.9-4.2-.2-1.2Z" style="fill: #fff;"/>
|
||||
<path d="m402.5,532.1c0-.2.1-.4.3-.4h1.8c.2,0,.3.1.3.4v13.3c0,.2,0,.4-.3.4h-1.8c-.2,0-.3-.1-.3-.4v-13.3Z" style="fill: #fff;"/>
|
||||
<path d="m415,541.9c0,2.3-1.4,4.1-3.7,4.1s-1.4-.5-1.8-1.1v3.9c0,.2-.2.4-.4.4h-1.7c-.2,0-.3-.1-.3-.4v-13.5c0-.2.1-.4.3-.4h1.3c.2,0,.4.1.4.4l.2.9c.4-.8,1.1-1.5,2.1-1.5,2.2,0,3.6,1.9,3.6,4.1v3.1Zm-2.5-3.2c0-.9-.6-1.7-1.5-1.7s-1.4.8-1.5,1.8v3c0,1,.6,1.9,1.5,1.9s1.5-.8,1.5-1.7v-3.3Z" style="fill: #fff;"/>
|
||||
<path d="m422,538.6c0-.8-.6-1.6-1.5-1.6s-1.5.9-1.5,1.6v6.8c0,.2-.3.4-.5.4h-1.7c-.2,0-.3-.1-.3-.4v-13.3c0-.2.1-.4.3-.4h1.8c.2,0,.3,0,.3.3v3.9c.5-.8,1.2-1.3,2.2-1.3,1.9,0,3.3,1.3,3.3,4v6.7c0,.2-.1.4-.3.4h-1.8c-.2,0-.3-.1-.3-.4v-6.8Z" style="fill: #fff;"/>
|
||||
<path d="m426,538.8c0-2.2,1.5-4.1,3.7-4.1s1.6.6,2,1.4v-.8c.2-.2.3-.4.6-.4h1.3c.2,0,.3.1.3.4v10.1c0,.2-.1.4-.3.4h-1.3c-.2,0-.4-.1-.4-.4v-.9c-.5.8-1.1,1.4-2.2,1.4-2.2,0-3.7-1.8-3.7-4.1v-3.1Zm2.5,3.2c0,.9.6,1.7,1.5,1.7s1.4-.8,1.5-1.8v-3.1c0-1-.6-1.8-1.5-1.8s-1.5.8-1.5,1.7v3.3Z" style="fill: #fff;"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 22 KiB |
@ -138,6 +138,8 @@ set(SLIC3R_SOURCES
|
||||
GCode/ThumbnailData.hpp
|
||||
GCode/Thumbnails.cpp
|
||||
GCode/Thumbnails.hpp
|
||||
GCode/ConflictChecker.cpp
|
||||
GCode/ConflictChecker.hpp
|
||||
GCode/CoolingBuffer.cpp
|
||||
GCode/CoolingBuffer.hpp
|
||||
GCode/FindReplace.cpp
|
||||
|
290
src/libslic3r/GCode/ConflictChecker.cpp
Normal file
290
src/libslic3r/GCode/ConflictChecker.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
#include "libslic3r.h"
|
||||
#include "ConflictChecker.hpp"
|
||||
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/concurrent_vector.h>
|
||||
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace RasterizationImpl {
|
||||
using IndexPair = std::pair<int64_t, int64_t>;
|
||||
using Grids = std::vector<IndexPair>;
|
||||
|
||||
inline constexpr int64_t RasteXDistance = scale_(1);
|
||||
inline constexpr int64_t RasteYDistance = scale_(1);
|
||||
|
||||
inline IndexPair point_map_grid_index(const Point &pt, int64_t xdist, int64_t ydist)
|
||||
{
|
||||
auto x = pt.x() / xdist;
|
||||
auto y = pt.y() / ydist;
|
||||
return std::make_pair(x, y);
|
||||
}
|
||||
|
||||
inline bool nearly_equal(const Point &p1, const Point &p2) { return std::abs(p1.x() - p2.x()) < SCALED_EPSILON && std::abs(p1.y() - p2.y()) < SCALED_EPSILON; }
|
||||
|
||||
inline Grids line_rasterization(const Line &line, int64_t xdist = RasteXDistance, int64_t ydist = RasteYDistance)
|
||||
{
|
||||
Grids res;
|
||||
Point rayStart = line.a;
|
||||
Point rayEnd = line.b;
|
||||
IndexPair currentVoxel = point_map_grid_index(rayStart, xdist, ydist);
|
||||
IndexPair lastVoxel = point_map_grid_index(rayEnd, xdist, ydist);
|
||||
|
||||
Point ray = rayEnd - rayStart;
|
||||
|
||||
double stepX = ray.x() >= 0 ? 1 : -1;
|
||||
double stepY = ray.y() >= 0 ? 1 : -1;
|
||||
|
||||
double nextVoxelBoundaryX = (currentVoxel.first + stepX) * xdist;
|
||||
double nextVoxelBoundaryY = (currentVoxel.second + stepY) * ydist;
|
||||
|
||||
if (stepX < 0) { nextVoxelBoundaryX += xdist; }
|
||||
if (stepY < 0) { nextVoxelBoundaryY += ydist; }
|
||||
|
||||
double tMaxX = ray.x() != 0 ? (nextVoxelBoundaryX - rayStart.x()) / ray.x() : DBL_MAX;
|
||||
double tMaxY = ray.y() != 0 ? (nextVoxelBoundaryY - rayStart.y()) / ray.y() : DBL_MAX;
|
||||
|
||||
double tDeltaX = ray.x() != 0 ? static_cast<double>(xdist) / ray.x() * stepX : DBL_MAX;
|
||||
double tDeltaY = ray.y() != 0 ? static_cast<double>(ydist) / ray.y() * stepY : DBL_MAX;
|
||||
|
||||
res.push_back(currentVoxel);
|
||||
|
||||
double tx = tMaxX;
|
||||
double ty = tMaxY;
|
||||
|
||||
while (lastVoxel != currentVoxel) {
|
||||
if (lastVoxel.first == currentVoxel.first) {
|
||||
for (int64_t i = currentVoxel.second; i != lastVoxel.second; i += (int64_t) stepY) {
|
||||
currentVoxel.second += (int64_t) stepY;
|
||||
res.push_back(currentVoxel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (lastVoxel.second == currentVoxel.second) {
|
||||
for (int64_t i = currentVoxel.first; i != lastVoxel.first; i += (int64_t) stepX) {
|
||||
currentVoxel.first += (int64_t) stepX;
|
||||
res.push_back(currentVoxel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx < ty) {
|
||||
currentVoxel.first += (int64_t) stepX;
|
||||
tx += tDeltaX;
|
||||
} else {
|
||||
currentVoxel.second += (int64_t) stepY;
|
||||
ty += tDeltaY;
|
||||
}
|
||||
res.push_back(currentVoxel);
|
||||
if (res.size() >= 100000) { // bug
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
} // namespace RasterizationImpl
|
||||
|
||||
void LinesBucketQueue::emplace_back_bucket(std::vector<ExtrusionPaths> &&paths, const void *objPtr, Points offsets)
|
||||
{
|
||||
if (_objsPtrToId.find(objPtr) == _objsPtrToId.end()) {
|
||||
_objsPtrToId.insert({objPtr, _objsPtrToId.size()});
|
||||
_idToObjsPtr.insert({_objsPtrToId.size() - 1, objPtr});
|
||||
}
|
||||
_buckets.emplace_back(std::move(paths), _objsPtrToId[objPtr], offsets);
|
||||
}
|
||||
|
||||
void LinesBucketQueue::build_queue()
|
||||
{
|
||||
assert(_pq.empty());
|
||||
for (LinesBucket &bucket : _buckets)
|
||||
_pq.push(&bucket);
|
||||
}
|
||||
|
||||
double LinesBucketQueue::removeLowests()
|
||||
{
|
||||
auto lowest = _pq.top();
|
||||
_pq.pop();
|
||||
double curHeight = lowest->curHeight();
|
||||
std::vector<LinesBucket *> lowests;
|
||||
lowests.push_back(lowest);
|
||||
|
||||
while (_pq.empty() == false && std::abs(_pq.top()->curHeight() - lowest->curHeight()) < EPSILON) {
|
||||
lowests.push_back(_pq.top());
|
||||
_pq.pop();
|
||||
}
|
||||
|
||||
for (LinesBucket *bp : lowests) {
|
||||
bp->raise();
|
||||
if (bp->valid()) { _pq.push(bp); }
|
||||
}
|
||||
return curHeight;
|
||||
}
|
||||
|
||||
LineWithIDs LinesBucketQueue::getCurLines() const
|
||||
{
|
||||
LineWithIDs lines;
|
||||
for (const LinesBucket &bucket : _buckets) {
|
||||
if (bucket.valid()) {
|
||||
LineWithIDs tmpLines = bucket.curLines();
|
||||
lines.insert(lines.end(), tmpLines.begin(), tmpLines.end());
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
void getExtrusionPathsFromEntity(const ExtrusionEntityCollection *entity, ExtrusionPaths &paths)
|
||||
{
|
||||
std::function<void(const ExtrusionEntityCollection *, ExtrusionPaths &)> getExtrusionPathImpl = [&](const ExtrusionEntityCollection *entity, ExtrusionPaths &paths) {
|
||||
for (auto entityPtr : entity->entities) {
|
||||
if (const ExtrusionEntityCollection *collection = dynamic_cast<ExtrusionEntityCollection *>(entityPtr)) {
|
||||
getExtrusionPathImpl(collection, paths);
|
||||
} else if (const ExtrusionPath *path = dynamic_cast<ExtrusionPath *>(entityPtr)) {
|
||||
paths.push_back(*path);
|
||||
} else if (const ExtrusionMultiPath *multipath = dynamic_cast<ExtrusionMultiPath *>(entityPtr)) {
|
||||
for (const ExtrusionPath &path : multipath->paths) { paths.push_back(path); }
|
||||
} else if (const ExtrusionLoop *loop = dynamic_cast<ExtrusionLoop *>(entityPtr)) {
|
||||
for (const ExtrusionPath &path : loop->paths) { paths.push_back(path); }
|
||||
}
|
||||
}
|
||||
};
|
||||
getExtrusionPathImpl(entity, paths);
|
||||
}
|
||||
|
||||
ExtrusionPaths getExtrusionPathsFromLayer(LayerRegionPtrs layerRegionPtrs)
|
||||
{
|
||||
ExtrusionPaths paths;
|
||||
for (auto regionPtr : layerRegionPtrs) {
|
||||
getExtrusionPathsFromEntity(®ionPtr->perimeters(), paths);
|
||||
if (!regionPtr->perimeters().empty()) { getExtrusionPathsFromEntity(®ionPtr->fills(), paths); }
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
ExtrusionPaths getExtrusionPathsFromSupportLayer(SupportLayer *supportLayer)
|
||||
{
|
||||
ExtrusionPaths paths;
|
||||
getExtrusionPathsFromEntity(&supportLayer->support_fills, paths);
|
||||
return paths;
|
||||
}
|
||||
|
||||
std::pair<std::vector<ExtrusionPaths>, std::vector<ExtrusionPaths>> getAllLayersExtrusionPathsFromObject(PrintObject *obj)
|
||||
{
|
||||
std::vector<ExtrusionPaths> objPaths, supportPaths;
|
||||
|
||||
for (auto layerPtr : obj->layers()) { objPaths.push_back(getExtrusionPathsFromLayer(layerPtr->regions())); }
|
||||
|
||||
for (auto supportLayerPtr : obj->support_layers()) { supportPaths.push_back(getExtrusionPathsFromSupportLayer(supportLayerPtr)); }
|
||||
|
||||
return {std::move(objPaths), std::move(supportPaths)};
|
||||
}
|
||||
|
||||
ConflictComputeOpt ConflictChecker::find_inter_of_lines(const LineWithIDs &lines)
|
||||
{
|
||||
using namespace RasterizationImpl;
|
||||
std::map<IndexPair, std::vector<int>> indexToLine;
|
||||
|
||||
for (int i = 0; i < (int)lines.size(); ++i) {
|
||||
const LineWithID &l1 = lines[i];
|
||||
auto indexes = line_rasterization(l1._line);
|
||||
for (auto index : indexes) {
|
||||
const auto &possibleIntersectIdxs = indexToLine[index];
|
||||
for (auto possibleIntersectIdx : possibleIntersectIdxs) {
|
||||
const LineWithID &l2 = lines[possibleIntersectIdx];
|
||||
if (auto interRes = line_intersect(l1, l2); interRes.has_value()) { return interRes; }
|
||||
}
|
||||
indexToLine[index].push_back(i);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
ConflictResultOpt ConflictChecker::find_inter_of_lines_in_diff_objs(PrintObjectPtrs objs,
|
||||
std::optional<const FakeWipeTower *> wtdptr) // find the first intersection point of lines in different objects
|
||||
{
|
||||
if (objs.empty() || (objs.size() == 1 && objs.front()->instances().size() == 1)) { return {}; }
|
||||
|
||||
LinesBucketQueue conflictQueue;
|
||||
if (wtdptr.has_value()) { // wipe tower at 0 by default
|
||||
std::vector<ExtrusionPaths> wtpaths = (*wtdptr)->getFakeExtrusionPathsFromWipeTower();
|
||||
conflictQueue.emplace_back_bucket(std::move(wtpaths), *wtdptr, Points{Point((*wtdptr)->plate_origin)});
|
||||
}
|
||||
for (PrintObject *obj : objs) {
|
||||
std::pair<std::vector<ExtrusionPaths>, std::vector<ExtrusionPaths>> layers = getAllLayersExtrusionPathsFromObject(obj);
|
||||
|
||||
Points instances_shifts;
|
||||
for (const PrintInstance& inst : obj->instances())
|
||||
instances_shifts.emplace_back(inst.shift);
|
||||
|
||||
conflictQueue.emplace_back_bucket(std::move(layers.first), obj, instances_shifts);
|
||||
conflictQueue.emplace_back_bucket(std::move(layers.second), obj, instances_shifts);
|
||||
}
|
||||
conflictQueue.build_queue();
|
||||
|
||||
std::vector<LineWithIDs> layersLines;
|
||||
std::vector<double> heights;
|
||||
while (conflictQueue.valid()) {
|
||||
LineWithIDs lines = conflictQueue.getCurLines();
|
||||
double curHeight = conflictQueue.removeLowests();
|
||||
heights.push_back(curHeight);
|
||||
layersLines.push_back(std::move(lines));
|
||||
}
|
||||
|
||||
bool find = false;
|
||||
tbb::concurrent_vector<std::pair<ConflictComputeResult,double>> conflict;
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, layersLines.size()), [&](tbb::blocked_range<size_t> range) {
|
||||
for (size_t i = range.begin(); i < range.end(); i++) {
|
||||
auto interRes = find_inter_of_lines(layersLines[i]);
|
||||
if (interRes.has_value()) {
|
||||
find = true;
|
||||
conflict.emplace_back(*interRes, heights[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (find) {
|
||||
std::sort(conflict.begin(), conflict.end(), [](const std::pair<ConflictComputeResult, double>& i1, const std::pair<ConflictComputeResult, double>& i2) {
|
||||
return i1.second < i2.second;
|
||||
});
|
||||
|
||||
const void *ptr1 = conflictQueue.idToObjsPtr(conflict[0].first._obj1);
|
||||
const void *ptr2 = conflictQueue.idToObjsPtr(conflict[0].first._obj2);
|
||||
double conflictHeight = conflict[0].second;
|
||||
if (wtdptr.has_value()) {
|
||||
const FakeWipeTower* wtdp = *wtdptr;
|
||||
if (ptr1 == wtdp || ptr2 == wtdp) {
|
||||
if (ptr2 == wtdp) { std::swap(ptr1, ptr2); }
|
||||
const PrintObject *obj2 = reinterpret_cast<const PrintObject *>(ptr2);
|
||||
return std::make_optional<ConflictResult>("WipeTower", obj2->model_object()->name, conflictHeight, nullptr, ptr2);
|
||||
}
|
||||
}
|
||||
const PrintObject *obj1 = reinterpret_cast<const PrintObject *>(ptr1);
|
||||
const PrintObject *obj2 = reinterpret_cast<const PrintObject *>(ptr2);
|
||||
return std::make_optional<ConflictResult>(obj1->model_object()->name, obj2->model_object()->name, conflictHeight, ptr1, ptr2);
|
||||
} else
|
||||
return {};
|
||||
}
|
||||
|
||||
ConflictComputeOpt ConflictChecker::line_intersect(const LineWithID &l1, const LineWithID &l2)
|
||||
{
|
||||
if (l1._obj_id == l2._obj_id && l1._inst_id == l2._inst_id) { return {}; } // lines are from same instance
|
||||
|
||||
Point inter;
|
||||
bool intersect = l1._line.intersection(l2._line, &inter);
|
||||
if (intersect) {
|
||||
auto dist1 = std::min(unscale(Point(l1._line.a - inter)).norm(), unscale(Point(l1._line.b - inter)).norm());
|
||||
auto dist2 = std::min(unscale(Point(l2._line.a - inter)).norm(), unscale(Point(l2._line.b - inter)).norm());
|
||||
auto dist = std::min(dist1, dist2);
|
||||
if (dist > 0.01) { return std::make_optional<ConflictComputeResult>(l1._obj_id, l2._obj_id); } // the two lines intersects if dist>0.01mm
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
129
src/libslic3r/GCode/ConflictChecker.hpp
Normal file
129
src/libslic3r/GCode/ConflictChecker.hpp
Normal file
@ -0,0 +1,129 @@
|
||||
#ifndef slic3r_ConflictChecker_hpp_
|
||||
#define slic3r_ConflictChecker_hpp_
|
||||
|
||||
#include "../Utils.hpp"
|
||||
#include "../Model.hpp"
|
||||
#include "../Print.hpp"
|
||||
#include "../Layer.hpp"
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
struct LineWithID
|
||||
{
|
||||
Line _line;
|
||||
int _obj_id;
|
||||
int _inst_id;
|
||||
ExtrusionRole _role;
|
||||
|
||||
LineWithID(const Line& line, int obj_id, int inst_id, const ExtrusionRole& role) :
|
||||
_line(line), _obj_id(obj_id), _inst_id(inst_id), _role(role) {}
|
||||
};
|
||||
|
||||
using LineWithIDs = std::vector<LineWithID>;
|
||||
|
||||
class LinesBucket
|
||||
{
|
||||
private:
|
||||
double _curHeight = 0.0;
|
||||
unsigned _curPileIdx = 0;
|
||||
|
||||
std::vector<ExtrusionPaths> _piles;
|
||||
int _id;
|
||||
Points _offsets;
|
||||
|
||||
public:
|
||||
LinesBucket(std::vector<ExtrusionPaths> &&paths, int id, Points offsets) : _piles(paths), _id(id), _offsets(offsets) {}
|
||||
LinesBucket(LinesBucket &&) = default;
|
||||
|
||||
bool valid() const { return _curPileIdx < _piles.size(); }
|
||||
void raise()
|
||||
{
|
||||
if (valid()) {
|
||||
if (_piles[_curPileIdx].empty() == false) { _curHeight += _piles[_curPileIdx].front().height; }
|
||||
_curPileIdx++;
|
||||
}
|
||||
}
|
||||
double curHeight() const { return _curHeight; }
|
||||
LineWithIDs curLines() const
|
||||
{
|
||||
LineWithIDs lines;
|
||||
for (const ExtrusionPath &path : _piles[_curPileIdx]) {
|
||||
Polyline check_polyline;
|
||||
for (int i = 0; i < (int)_offsets.size(); ++i) {
|
||||
check_polyline = path.polyline;
|
||||
check_polyline.translate(_offsets[i]);
|
||||
Lines tmpLines = check_polyline.lines();
|
||||
for (const Line& line : tmpLines) { lines.emplace_back(line, _id, i, path.role()); }
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
friend bool operator>(const LinesBucket &left, const LinesBucket &right) { return left._curHeight > right._curHeight; }
|
||||
friend bool operator<(const LinesBucket &left, const LinesBucket &right) { return left._curHeight < right._curHeight; }
|
||||
friend bool operator==(const LinesBucket &left, const LinesBucket &right) { return left._curHeight == right._curHeight; }
|
||||
};
|
||||
|
||||
struct LinesBucketPtrComp
|
||||
{
|
||||
bool operator()(const LinesBucket *left, const LinesBucket *right) { return *left > *right; }
|
||||
};
|
||||
|
||||
class LinesBucketQueue
|
||||
{
|
||||
private:
|
||||
std::vector<LinesBucket> _buckets;
|
||||
std::priority_queue<LinesBucket *, std::vector<LinesBucket *>, LinesBucketPtrComp> _pq;
|
||||
std::map<int, const void *> _idToObjsPtr;
|
||||
std::map<const void *, int> _objsPtrToId;
|
||||
|
||||
public:
|
||||
void emplace_back_bucket(std::vector<ExtrusionPaths> &&paths, const void *objPtr, Points offset);
|
||||
void build_queue();
|
||||
bool valid() const { return _pq.empty() == false; }
|
||||
const void *idToObjsPtr(int id)
|
||||
{
|
||||
if (_idToObjsPtr.find(id) != _idToObjsPtr.end())
|
||||
return _idToObjsPtr[id];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
double removeLowests();
|
||||
LineWithIDs getCurLines() const;
|
||||
};
|
||||
|
||||
void getExtrusionPathsFromEntity(const ExtrusionEntityCollection *entity, ExtrusionPaths &paths);
|
||||
|
||||
ExtrusionPaths getExtrusionPathsFromLayer(LayerRegionPtrs layerRegionPtrs);
|
||||
|
||||
ExtrusionPaths getExtrusionPathsFromSupportLayer(SupportLayer *supportLayer);
|
||||
|
||||
std::pair<std::vector<ExtrusionPaths>, std::vector<ExtrusionPaths>> getAllLayersExtrusionPathsFromObject(PrintObject *obj);
|
||||
|
||||
struct ConflictComputeResult
|
||||
{
|
||||
int _obj1;
|
||||
int _obj2;
|
||||
|
||||
ConflictComputeResult(int o1, int o2) : _obj1(o1), _obj2(o2) {}
|
||||
ConflictComputeResult() = default;
|
||||
};
|
||||
|
||||
using ConflictComputeOpt = std::optional<ConflictComputeResult>;
|
||||
|
||||
using ConflictObjName = std::optional<std::pair<std::string, std::string>>;
|
||||
|
||||
struct ConflictChecker
|
||||
{
|
||||
static ConflictResultOpt find_inter_of_lines_in_diff_objs(PrintObjectPtrs objs, std::optional<const FakeWipeTower *> wtdptr);
|
||||
static ConflictComputeOpt find_inter_of_lines(const LineWithIDs &lines);
|
||||
static ConflictComputeOpt line_intersect(const LineWithID &l1, const LineWithID &l2);
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
@ -189,13 +189,13 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
||||
head_window_acc -= distances_for_curvature[point_idx - 1];
|
||||
head_angle_acc -= angles_for_curvature[point_idx - 1];
|
||||
}
|
||||
while (tail_window_acc > window_size * 0.5 && tail_point < point_idx) {
|
||||
while (tail_window_acc > window_size * 0.5 && int(tail_point) < point_idx) {
|
||||
tail_window_acc -= distances_for_curvature[tail_point];
|
||||
tail_angle_acc -= angles_for_curvature[tail_point];
|
||||
tail_point++;
|
||||
}
|
||||
|
||||
while (head_window_acc < window_size * 0.5 && head_point < int(points.size()) - 1) {
|
||||
while (head_window_acc < window_size * 0.5 && int(head_point) < int(points.size()) - 1) {
|
||||
head_window_acc += distances_for_curvature[head_point];
|
||||
head_angle_acc += angles_for_curvature[head_point];
|
||||
head_point++;
|
||||
|
@ -450,6 +450,7 @@ void GCodeProcessorResult::reset() {
|
||||
filament_cost = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST);
|
||||
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
|
||||
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
|
||||
conflict_result = std::nullopt;
|
||||
time = 0;
|
||||
}
|
||||
#else
|
||||
@ -468,6 +469,7 @@ void GCodeProcessorResult::reset() {
|
||||
filament_cost = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST);
|
||||
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
|
||||
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
|
||||
conflict_result = std::nullopt;
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
|
@ -82,6 +82,22 @@ namespace Slic3r {
|
||||
}
|
||||
};
|
||||
|
||||
struct ConflictResult
|
||||
{
|
||||
std::string _objName1;
|
||||
std::string _objName2;
|
||||
double _height;
|
||||
const void* _obj1; // nullptr means wipe tower
|
||||
const void* _obj2;
|
||||
int layer = -1;
|
||||
ConflictResult(const std::string& objName1, const std::string& objName2, double height, const void* obj1, const void* obj2)
|
||||
: _objName1(objName1), _objName2(objName2), _height(height), _obj1(obj1), _obj2(obj2)
|
||||
{}
|
||||
ConflictResult() = default;
|
||||
};
|
||||
|
||||
using ConflictResultOpt = std::optional<ConflictResult>;
|
||||
|
||||
struct GCodeProcessorResult
|
||||
{
|
||||
struct SettingsIds
|
||||
@ -137,6 +153,8 @@ namespace Slic3r {
|
||||
std::vector<CustomGCode::Item> custom_gcode_per_print_z;
|
||||
std::vector<std::pair<float, std::pair<size_t, size_t>>> spiral_vase_layers;
|
||||
|
||||
ConflictResultOpt conflict_result;
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
int64_t time{ 0 };
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
@ -1563,4 +1563,19 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<std::pair<float, float>> WipeTower::get_z_and_depth_pairs() const
|
||||
{
|
||||
std::vector<std::pair<float, float>> out = {{0.f, m_wipe_tower_depth}};
|
||||
for (const WipeTowerInfo& wti : m_plan) {
|
||||
assert(wti.depth < wti.depth + WT_EPSILON);
|
||||
if (wti.depth < out.back().second - WT_EPSILON)
|
||||
out.emplace_back(wti.z, wti.depth);
|
||||
}
|
||||
if (out.back().first < m_wipe_tower_height - WT_EPSILON)
|
||||
out.emplace_back(m_wipe_tower_height, 0.f);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -143,6 +143,7 @@ public:
|
||||
void generate(std::vector<std::vector<ToolChangeResult>> &result);
|
||||
|
||||
float get_depth() const { return m_wipe_tower_depth; }
|
||||
std::vector<std::pair<float, float>> get_z_and_depth_pairs() const;
|
||||
float get_brim_width() const { return m_wipe_tower_brim_width_real; }
|
||||
float get_wipe_tower_height() const { return m_wipe_tower_height; }
|
||||
|
||||
|
@ -1353,37 +1353,6 @@ void ModelObject::delete_connectors()
|
||||
}
|
||||
}
|
||||
|
||||
void ModelObject::synchronize_model_after_cut()
|
||||
{
|
||||
for (ModelObject* obj : m_model->objects) {
|
||||
if (obj == this || obj->cut_id.is_equal(this->cut_id))
|
||||
continue;
|
||||
if (obj->is_cut() && obj->cut_id.has_same_id(this->cut_id))
|
||||
obj->cut_id.copy(this->cut_id);
|
||||
}
|
||||
this->invalidate_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) ||
|
||||
attributes.has(ModelObjectCutAttribute::InvalidateCutInfo))
|
||||
return;
|
||||
|
||||
if (cut_id.id().invalid())
|
||||
cut_id.init();
|
||||
{
|
||||
int cut_obj_cnt = -1;
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) cut_obj_cnt++;
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower)) cut_obj_cnt++;
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels)) cut_obj_cnt++;
|
||||
if (cut_obj_cnt > 0)
|
||||
cut_id.increase_check_sum(size_t(cut_obj_cnt));
|
||||
}
|
||||
}
|
||||
|
||||
void ModelObject::clone_for_cut(ModelObject** obj)
|
||||
{
|
||||
(*obj) = ModelObject::new_clone(*this);
|
||||
@ -1636,9 +1605,6 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "ModelObject::cut - start";
|
||||
|
||||
// apply cut attributes for object
|
||||
apply_cut_attributes(attributes);
|
||||
|
||||
// Clone the object to duplicate instances, materials etc.
|
||||
ModelObject* upper{ nullptr };
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper))
|
||||
@ -1709,8 +1675,6 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "ModelObject::cut - end";
|
||||
|
||||
synchronize_model_after_cut();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -469,13 +469,7 @@ public:
|
||||
void delete_connectors();
|
||||
void clone_for_cut(ModelObject **obj);
|
||||
|
||||
void apply_cut_attributes(ModelObjectCutAttributes attributes);
|
||||
private:
|
||||
// FIXME: These functions would best not be here at all. It might make sense to separate the
|
||||
// cut-related methods elsewhere. Same holds for cut_connectors data member, which is currently
|
||||
// just a temporary variable used by cut gizmo only.
|
||||
void synchronize_model_after_cut();
|
||||
|
||||
void process_connector_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
|
||||
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower,
|
||||
std::vector<ModelObject*>& dowels);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "Thread.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include "GCode/WipeTower.hpp"
|
||||
#include "GCode/ConflictChecker.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "BuildVolume.hpp"
|
||||
#include "format.hpp"
|
||||
@ -26,7 +27,6 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
template class PrintState<PrintStep, psCount>;
|
||||
@ -962,6 +962,18 @@ void Print::process()
|
||||
this->finalize_first_layer_convex_hull();
|
||||
this->set_done(psSkirtBrim);
|
||||
}
|
||||
|
||||
std::optional<const FakeWipeTower*> wipe_tower_opt = {};
|
||||
if (this->has_wipe_tower()) {
|
||||
m_fake_wipe_tower.set_pos_and_rotation({ m_config.wipe_tower_x, m_config.wipe_tower_y }, m_config.wipe_tower_rotation_angle);
|
||||
wipe_tower_opt = std::make_optional<const FakeWipeTower*>(&m_fake_wipe_tower);
|
||||
}
|
||||
auto conflictRes = ConflictChecker::find_inter_of_lines_in_diff_objs(m_objects, wipe_tower_opt);
|
||||
|
||||
m_conflict_result = conflictRes;
|
||||
if (conflictRes.has_value())
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("gcode path conflicts found between %1% and %2%") % conflictRes->_objName1 % conflictRes->_objName2;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
|
||||
}
|
||||
|
||||
@ -987,6 +999,10 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor
|
||||
// Create GCode on heap, it has quite a lot of data.
|
||||
std::unique_ptr<GCode> gcode(new GCode);
|
||||
gcode->do_export(this, path.c_str(), result, thumbnail_cb);
|
||||
|
||||
if (m_conflict_result.has_value())
|
||||
result->conflict_result = *m_conflict_result;
|
||||
|
||||
return path.c_str();
|
||||
}
|
||||
|
||||
@ -1485,6 +1501,7 @@ void Print::_make_wipe_tower()
|
||||
m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
|
||||
wipe_tower.generate(m_wipe_tower_data.tool_changes);
|
||||
m_wipe_tower_data.depth = wipe_tower.get_depth();
|
||||
m_wipe_tower_data.z_and_depth_pairs = wipe_tower.get_z_and_depth_pairs();
|
||||
m_wipe_tower_data.brim_width = wipe_tower.get_brim_width();
|
||||
m_wipe_tower_data.height = wipe_tower.get_wipe_tower_height();
|
||||
|
||||
@ -1509,6 +1526,10 @@ void Print::_make_wipe_tower()
|
||||
|
||||
m_wipe_tower_data.used_filament = wipe_tower.get_used_filament();
|
||||
m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();
|
||||
const Vec3d origin = Vec3d::Zero();
|
||||
m_fake_wipe_tower.set_fake_extrusion_data(wipe_tower.position(), wipe_tower.width(), wipe_tower.get_wipe_tower_height(), config().first_layer_height, m_wipe_tower_data.depth,
|
||||
m_wipe_tower_data.z_and_depth_pairs, m_wipe_tower_data.brim_width, config().wipe_tower_rotation_angle, config().wipe_tower_cone_angle, {scale_(origin.x()), scale_(origin.y())});
|
||||
|
||||
}
|
||||
|
||||
// Generate a recommended G-code output file name based on the format template, default extension, and template parameters
|
||||
@ -1576,4 +1597,80 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
|
||||
return final_path;
|
||||
}
|
||||
|
||||
std::vector<ExtrusionPaths> FakeWipeTower::getFakeExtrusionPathsFromWipeTower() const
|
||||
{
|
||||
float h = height;
|
||||
float lh = layer_height;
|
||||
int d = scale_(depth);
|
||||
int w = scale_(width);
|
||||
int bd = scale_(brim_width);
|
||||
Point minCorner = { -bd, -bd };
|
||||
Point maxCorner = { minCorner.x() + w + bd, minCorner.y() + d + bd };
|
||||
|
||||
const auto [cone_base_R, cone_scale_x] = WipeTower::get_wipe_tower_cone_base(width, height, depth, cone_angle);
|
||||
|
||||
std::vector<ExtrusionPaths> paths;
|
||||
for (float hh = 0.f; hh < h; hh += lh) {
|
||||
|
||||
if (hh != 0.f) {
|
||||
// The wipe tower may be getting smaller. Find the depth for this layer.
|
||||
size_t i = 0;
|
||||
for (i=0; i<z_and_depth_pairs.size()-1; ++i)
|
||||
if (hh >= z_and_depth_pairs[i].first && hh < z_and_depth_pairs[i+1].first)
|
||||
break;
|
||||
d = scale_(z_and_depth_pairs[i].second);
|
||||
minCorner = {0.f, -d/2 + scale_(z_and_depth_pairs.front().second/2.f)};
|
||||
maxCorner = { minCorner.x() + w, minCorner.y() + d };
|
||||
}
|
||||
|
||||
|
||||
ExtrusionPath path(ExtrusionRole::WipeTower, 0.0, 0.0, lh);
|
||||
path.polyline = { minCorner, {maxCorner.x(), minCorner.y()}, maxCorner, {minCorner.x(), maxCorner.y()}, minCorner };
|
||||
paths.push_back({ path });
|
||||
|
||||
// We added the border, now add several parallel lines so we can detect an object that is fully inside the tower.
|
||||
// For now, simply use fixed spacing of 3mm.
|
||||
for (coord_t y=minCorner.y()+scale_(3.); y<maxCorner.y(); y+=scale_(3.)) {
|
||||
path.polyline = { {minCorner.x(), y}, {maxCorner.x(), y} };
|
||||
paths.back().emplace_back(path);
|
||||
}
|
||||
|
||||
// And of course the stabilization cone and its base...
|
||||
if (cone_base_R > 0.) {
|
||||
path.polyline.clear();
|
||||
double r = cone_base_R * (1 - hh/height);
|
||||
for (double alpha=0; alpha<2.01*M_PI; alpha+=2*M_PI/20.)
|
||||
path.polyline.points.emplace_back(Point::new_scale(width/2. + r * std::cos(alpha)/cone_scale_x, depth/2. + r * std::sin(alpha)));
|
||||
paths.back().emplace_back(path);
|
||||
if (hh == 0.f) { // Cone brim.
|
||||
for (float bw=brim_width; bw>0.f; bw-=3.f) {
|
||||
path.polyline.clear();
|
||||
for (double alpha=0; alpha<2.01*M_PI; alpha+=2*M_PI/20.) // see load_wipe_tower_preview, where the same is a bit clearer
|
||||
path.polyline.points.emplace_back(Point::new_scale(
|
||||
width/2. + cone_base_R * std::cos(alpha)/cone_scale_x * (1. + cone_scale_x*bw/cone_base_R),
|
||||
depth/2. + cone_base_R * std::sin(alpha) * (1. + bw/cone_base_R))
|
||||
);
|
||||
paths.back().emplace_back(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only the first layer has brim.
|
||||
if (hh == 0.f) {
|
||||
minCorner = minCorner + Point(bd, bd);
|
||||
maxCorner = maxCorner - Point(bd, bd);
|
||||
}
|
||||
}
|
||||
|
||||
// Rotate and translate the tower into the final position.
|
||||
for (ExtrusionPaths& ps : paths) {
|
||||
for (ExtrusionPath& p : ps) {
|
||||
p.polyline.rotate(Geometry::deg2rad(rotation_angle));
|
||||
p.polyline.translate(scale_(pos.x()), scale_(pos.y()));
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -418,6 +418,39 @@ private:
|
||||
FillLightning::GeneratorPtr m_lightning_generator;
|
||||
};
|
||||
|
||||
struct FakeWipeTower
|
||||
{
|
||||
// generate fake extrusion
|
||||
Vec2f pos;
|
||||
float width;
|
||||
float height;
|
||||
float layer_height;
|
||||
float depth;
|
||||
std::vector<std::pair<float, float>> z_and_depth_pairs;
|
||||
float brim_width;
|
||||
float rotation_angle;
|
||||
float cone_angle;
|
||||
Vec2d plate_origin;
|
||||
|
||||
void set_fake_extrusion_data(const Vec2f& p, float w, float h, float lh, float d, const std::vector<std::pair<float, float>>& zad, float bd, float ra, float ca, const Vec2d& o)
|
||||
{
|
||||
pos = p;
|
||||
width = w;
|
||||
height = h;
|
||||
layer_height = lh;
|
||||
depth = d;
|
||||
z_and_depth_pairs = zad;
|
||||
brim_width = bd;
|
||||
rotation_angle = ra;
|
||||
cone_angle = ca;
|
||||
plate_origin = o;
|
||||
}
|
||||
|
||||
void set_pos_and_rotation(const Vec2f& p, float rotation) { pos = p; rotation_angle = rotation; }
|
||||
|
||||
std::vector<ExtrusionPaths> getFakeExtrusionPathsFromWipeTower() const;
|
||||
};
|
||||
|
||||
struct WipeTowerData
|
||||
{
|
||||
// Following section will be consumed by the GCodeGenerator.
|
||||
@ -433,6 +466,7 @@ struct WipeTowerData
|
||||
|
||||
// Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
|
||||
float depth;
|
||||
std::vector<std::pair<float, float>> z_and_depth_pairs;
|
||||
float brim_width;
|
||||
float height;
|
||||
|
||||
@ -668,6 +702,9 @@ private:
|
||||
friend class GCodeProcessor;
|
||||
// Allow PrintObject to access m_mutex and m_cancel_callback.
|
||||
friend class PrintObject;
|
||||
|
||||
ConflictResultOpt m_conflict_result;
|
||||
FakeWipeTower m_fake_wipe_tower;
|
||||
};
|
||||
|
||||
} /* slic3r_Print_hpp_ */
|
||||
|
@ -981,12 +981,11 @@ void PrintObject::detect_surfaces_type()
|
||||
surface_type_bottom_other);
|
||||
#else
|
||||
// Any surface lying on the void is a true bottom bridge (an overhang)
|
||||
surfaces_append(
|
||||
bottom,
|
||||
opening_ex(
|
||||
diff_ex(layerm->slices().surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
|
||||
offset),
|
||||
surface_type_bottom_other);
|
||||
ExPolygons true_bridge = diff_ex(layerm->slices().surfaces, lower_layer->lslices, ApplySafetyOffset::Yes);
|
||||
// expand the bridges by one extrusion width, to ensure reasonable anchoring whenever possible
|
||||
true_bridge = intersection_ex(layerm->slices().surfaces,
|
||||
offset_ex(true_bridge, layerm->bridging_flow(frSolidInfill).scaled_spacing()));
|
||||
surfaces_append(bottom, true_bridge, surface_type_bottom_other);
|
||||
// if user requested internal shells, we need to identify surfaces
|
||||
// lying on other slices not belonging to this region
|
||||
if (interface_shells) {
|
||||
|
@ -650,7 +650,7 @@ std::tuple<ObjectPart, float> build_object_part_from_slice(const size_t &slice_i
|
||||
new_object_part.volume += volume;
|
||||
new_object_part.volume_centroid_accumulator += to_3d(Vec2f((line.a + line.b) / 2.0f), slice_z) * volume;
|
||||
|
||||
if (l->id() == params.raft_layers_count) { // layer attached on bed/raft
|
||||
if (int(l->id()) == params.raft_layers_count) { // layer attached on bed/raft
|
||||
new_object_part.connected_to_bed = true;
|
||||
float sticking_area = line.len * flow_width;
|
||||
new_object_part.sticking_area += sticking_area;
|
||||
@ -673,7 +673,7 @@ std::tuple<ObjectPart, float> build_object_part_from_slice(const size_t &slice_i
|
||||
|
||||
for (const auto &island : slice.islands) {
|
||||
const LayerRegion *perimeter_region = layer->get_region(island.perimeters.region());
|
||||
for (const auto &perimeter_idx : island.perimeters) {
|
||||
for (size_t perimeter_idx : island.perimeters) {
|
||||
for (const ExtrusionEntity *perimeter :
|
||||
static_cast<const ExtrusionEntityCollection *>(perimeter_region->perimeters().entities[perimeter_idx])->entities) {
|
||||
add_extrusions_to_object(perimeter, perimeter_region);
|
||||
@ -681,20 +681,20 @@ std::tuple<ObjectPart, float> build_object_part_from_slice(const size_t &slice_i
|
||||
}
|
||||
for (const LayerExtrusionRange &fill_range : island.fills) {
|
||||
const LayerRegion *fill_region = layer->get_region(fill_range.region());
|
||||
for (const auto &fill_idx : fill_range) {
|
||||
for (size_t fill_idx : fill_range) {
|
||||
for (const ExtrusionEntity *fill :
|
||||
static_cast<const ExtrusionEntityCollection *>(fill_region->fills().entities[fill_idx])->entities) {
|
||||
add_extrusions_to_object(fill, fill_region);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto &thin_fill_idx : island.thin_fills) {
|
||||
for (size_t thin_fill_idx : island.thin_fills) {
|
||||
add_extrusions_to_object(perimeter_region->thin_fills().entities[thin_fill_idx], perimeter_region);
|
||||
}
|
||||
}
|
||||
|
||||
// BRIM HANDLING
|
||||
if (layer->id() == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim &&
|
||||
if (int(layer->id()) == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim &&
|
||||
params.brim_width > 0.0) {
|
||||
// TODO: The algorithm here should take into account that multiple slices may have coliding Brim areas and the final brim area is
|
||||
// smaller,
|
||||
@ -911,7 +911,7 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject
|
||||
for (const auto &island : slice.islands) {
|
||||
for (const LayerExtrusionRange &fill_range : island.fills) {
|
||||
const LayerRegion *fill_region = layer->get_region(fill_range.region());
|
||||
for (const auto &fill_idx : fill_range) {
|
||||
for (size_t fill_idx : fill_range) {
|
||||
for (const ExtrusionEntity *e : get_flat_entities(fill_region->fills().entities[fill_idx])) {
|
||||
if (e->role() == ExtrusionRole::BridgeInfill) {
|
||||
entities_to_check.push_back({e, fill_region, slice_idx});
|
||||
@ -921,7 +921,7 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject
|
||||
}
|
||||
|
||||
const LayerRegion *perimeter_region = layer->get_region(island.perimeters.region());
|
||||
for (const size_t &perimeter_idx : island.perimeters) {
|
||||
for (size_t perimeter_idx : island.perimeters) {
|
||||
for (const ExtrusionEntity *e : get_flat_entities(perimeter_region->perimeters().entities[perimeter_idx])) {
|
||||
entities_to_check.push_back({e, perimeter_region, slice_idx});
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Platform.hpp"
|
||||
#include "Time.hpp"
|
||||
#include "format.hpp"
|
||||
#include "libslic3r.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -194,6 +194,7 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/Jobs/BoostThreadWorker.cpp
|
||||
GUI/Jobs/UIThreadWorker.hpp
|
||||
GUI/Jobs/BusyCursorJob.hpp
|
||||
GUI/Jobs/CancellableJob.hpp
|
||||
GUI/Jobs/PlaterWorker.hpp
|
||||
GUI/Jobs/ArrangeJob.hpp
|
||||
GUI/Jobs/ArrangeJob.cpp
|
||||
|
@ -480,11 +480,11 @@ int GLVolumeCollection::load_object_volume(
|
||||
|
||||
#if ENABLE_OPENGL_ES
|
||||
int GLVolumeCollection::load_wipe_tower_preview(
|
||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle,
|
||||
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle,
|
||||
float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh)
|
||||
#else
|
||||
int GLVolumeCollection::load_wipe_tower_preview(
|
||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle,
|
||||
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle,
|
||||
float rotation_angle, bool size_unknown, float brim_width)
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
{
|
||||
@ -534,8 +534,13 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||
|
||||
mesh.scale(Vec3f(width / (n * min_width), 1.f, height)); // Scaling to proper width
|
||||
}
|
||||
else
|
||||
mesh = make_cube(width, depth, height);
|
||||
else {
|
||||
for (size_t i=1; i<z_and_depth_pairs.size(); ++i) {
|
||||
TriangleMesh m = make_cube(width, z_and_depth_pairs[i-1].second, z_and_depth_pairs[i].first-z_and_depth_pairs[i-1].first);
|
||||
m.translate(0.f, -z_and_depth_pairs[i-1].second/2.f + z_and_depth_pairs[0].second/2.f, z_and_depth_pairs[i-1].first);
|
||||
mesh.merge(m);
|
||||
}
|
||||
}
|
||||
|
||||
// We'll make another mesh to show the brim (fixed layer height):
|
||||
TriangleMesh brim_mesh = make_cube(width + 2.f * brim_width, depth + 2.f * brim_width, 0.2f);
|
||||
|
@ -396,10 +396,10 @@ public:
|
||||
|
||||
#if ENABLE_OPENGL_ES
|
||||
int load_wipe_tower_preview(
|
||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
|
||||
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
|
||||
#else
|
||||
int load_wipe_tower_preview(
|
||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width);
|
||||
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width);
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
// Load SLA auxiliary GLVolumes (for support trees or pad).
|
||||
|
@ -799,6 +799,9 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
|
||||
short_time(get_time_dhms(time)) == short_time(get_time_dhms(m_print_statistics.modes[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].time)))
|
||||
m_time_estimate_mode = PrintEstimatedStatistics::ETimeMode::Normal;
|
||||
}
|
||||
|
||||
m_conflict_result = gcode_result.conflict_result;
|
||||
if (m_conflict_result.has_value()) { m_conflict_result->layer = m_layers.get_l_at(m_conflict_result->_height); }
|
||||
}
|
||||
|
||||
void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors)
|
||||
@ -2257,8 +2260,10 @@ void GCodeViewer::load_shells(const Print& print)
|
||||
if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) {
|
||||
const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count);
|
||||
const float depth = wipe_tower_data.depth;
|
||||
const std::vector<std::pair<float, float>> z_and_depth_pairs = print.wipe_tower_data(extruders_count).z_and_depth_pairs;
|
||||
const float brim_width = wipe_tower_data.brim_width;
|
||||
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_cone_angle, config.wipe_tower_rotation_angle,
|
||||
if (depth != 0.)
|
||||
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, z_and_depth_pairs, max_z, config.wipe_tower_cone_angle, config.wipe_tower_rotation_angle,
|
||||
!print.is_step_done(psWipeTower), brim_width);
|
||||
}
|
||||
}
|
||||
|
@ -526,6 +526,10 @@ class GCodeViewer
|
||||
std::vector<Range>& get_ranges() { return m_ranges; }
|
||||
double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; }
|
||||
Range get_range_at(unsigned int id) const { return (id < m_ranges.size()) ? m_ranges[id] : Range(); }
|
||||
int get_l_at(double z) const {
|
||||
auto iter = std::upper_bound(m_zs.begin(), m_zs.end(), z);
|
||||
return std::distance(m_zs.begin(), iter);
|
||||
}
|
||||
|
||||
bool operator != (const Layers& other) const {
|
||||
if (m_zs != other.m_zs)
|
||||
@ -784,6 +788,8 @@ private:
|
||||
|
||||
bool m_contained_in_bed{ true };
|
||||
|
||||
ConflictResultOpt m_conflict_result;
|
||||
|
||||
public:
|
||||
GCodeViewer();
|
||||
~GCodeViewer() { reset(); }
|
||||
@ -841,6 +847,8 @@ public:
|
||||
|
||||
void invalidate_legend() { m_legend_resizer.reset(); }
|
||||
|
||||
const ConflictResultOpt& get_conflict_result() const { return m_conflict_result; }
|
||||
|
||||
private:
|
||||
void load_toolpaths(const GCodeProcessorResult& gcode_result);
|
||||
void load_shells(const Print& print);
|
||||
|
@ -2554,24 +2554,27 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
|
||||
const Print *print = m_process->fff_print();
|
||||
const float depth = print->wipe_tower_data(extruders_count).depth;
|
||||
const std::vector<std::pair<float, float>> z_and_depth_pairs = print->wipe_tower_data(extruders_count).z_and_depth_pairs;
|
||||
const float height_real = print->wipe_tower_data(extruders_count).height; // -1.f = unknown
|
||||
|
||||
// Height of a print (Show at least a slab).
|
||||
const double height = height_real < 0.f ? std::max(m_model->max_z(), 10.0) : height_real;
|
||||
|
||||
if (depth != 0.) {
|
||||
#if ENABLE_OPENGL_ES
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||
x, y, w, depth, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
||||
x, y, w, depth, z_and_depth_pairs, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
||||
bw, &m_wipe_tower_mesh);
|
||||
#else
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||
x, y, w, depth, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
||||
x, y, w, depth, z_and_depth_pairs, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
||||
bw);
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
if (volume_idx_wipe_tower_old != -1)
|
||||
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_volumes_colors_by_extruder();
|
||||
// Update selection indices based on the old/new GLVolumeCollection.
|
||||
@ -2691,6 +2694,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, co
|
||||
if (wxGetApp().is_editor()) {
|
||||
m_gcode_viewer.update_shells_color_by_extruder(m_config);
|
||||
_set_warning_notification_if_needed(EWarning::ToolpathOutside);
|
||||
_set_warning_notification_if_needed(EWarning::GCodeConflict);
|
||||
}
|
||||
|
||||
m_gcode_viewer.refresh(gcode_result, str_tool_colors);
|
||||
@ -7439,8 +7443,12 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
|
||||
}
|
||||
else {
|
||||
if (wxGetApp().is_editor()) {
|
||||
if (current_printer_technology() != ptSLA)
|
||||
if (current_printer_technology() != ptSLA) {
|
||||
if (warning == EWarning::ToolpathOutside)
|
||||
show = m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed();
|
||||
else if (warning == EWarning::GCodeConflict)
|
||||
show = m_gcode_viewer.has_data() && m_gcode_viewer.is_contained_in_bed() && m_gcode_viewer.get_conflict_result().has_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7466,8 +7474,53 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||
"Resolve the current problem to continue slicing.");
|
||||
error = ErrorType::PLATER_ERROR;
|
||||
break;
|
||||
case EWarning::GCodeConflict: {
|
||||
const ConflictResultOpt& conflict_result = m_gcode_viewer.get_conflict_result();
|
||||
if (!conflict_result.has_value()) { break; }
|
||||
std::string objName1 = conflict_result->_objName1;
|
||||
std::string objName2 = conflict_result->_objName2;
|
||||
double height = conflict_result->_height;
|
||||
int layer = conflict_result->layer;
|
||||
text = (boost::format(_u8L("Conflicts of gcode paths have been found at layer %d, z = %.2lf mm. Please separate the conflicted objects farther (%s <-> %s).")) % layer %
|
||||
height % objName1 % objName2).str();
|
||||
error = ErrorType::SLICING_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto& notification_manager = *wxGetApp().plater()->get_notification_manager();
|
||||
|
||||
const ConflictResultOpt& conflict_result = m_gcode_viewer.get_conflict_result();
|
||||
if (warning == EWarning::GCodeConflict) {
|
||||
if (conflict_result.has_value()) {
|
||||
const PrintObject* obj2 = reinterpret_cast<const PrintObject*>(conflict_result->_obj2);
|
||||
auto mo = obj2->model_object();
|
||||
ObjectID id = mo->id();
|
||||
int layer_id = conflict_result->layer;
|
||||
auto action_fn = [id, layer_id](wxEvtHandler*) {
|
||||
auto& objects = wxGetApp().model().objects;
|
||||
auto iter = id.id ? std::find_if(objects.begin(), objects.end(), [id](auto o) { return o->id() == id; }) : objects.end();
|
||||
if (iter != objects.end()) {
|
||||
const unsigned int obj_idx = std::distance(objects.begin(), iter);
|
||||
wxGetApp().CallAfter([obj_idx, layer_id]() {
|
||||
wxGetApp().plater()->set_preview_layers_slider_values_range(0, layer_id - 1);
|
||||
wxGetApp().plater()->select_view_3D("3D");
|
||||
wxGetApp().plater()->canvas3D()->get_selection().add_object(obj_idx, true);
|
||||
wxGetApp().obj_list()->update_selections();
|
||||
});
|
||||
}
|
||||
return false;
|
||||
};
|
||||
auto hypertext = _u8L("Jump to");
|
||||
hypertext += std::string(" [") + mo->name + "]";
|
||||
notification_manager.push_notification(NotificationType::SlicingError, NotificationManager::NotificationLevel::ErrorNotificationLevel,
|
||||
_u8L("ERROR:") + "\n" + text, hypertext, action_fn);
|
||||
}
|
||||
else
|
||||
notification_manager.close_slicing_error_notification(text);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case PLATER_WARNING:
|
||||
|
@ -362,7 +362,8 @@ class GLCanvas3D
|
||||
ToolpathOutside,
|
||||
SlaSupportsOutside,
|
||||
SomethingNotShown,
|
||||
ObjectClashed
|
||||
ObjectClashed,
|
||||
GCodeConflict
|
||||
};
|
||||
|
||||
class RenderStats
|
||||
|
@ -2306,38 +2306,18 @@ void ObjectList::merge(bool to_multipart_object)
|
||||
for (int obj_idx : obj_idxs) {
|
||||
ModelObject* object = (*m_objects)[obj_idx];
|
||||
|
||||
const Geometry::Transformation& transformation = object->instances[0]->get_transformation();
|
||||
const Vec3d scale = transformation.get_scaling_factor();
|
||||
const Vec3d mirror = transformation.get_mirror();
|
||||
const Vec3d rotation = transformation.get_rotation();
|
||||
|
||||
if (object->id() == (*m_objects)[obj_idxs.front()]->id()) {
|
||||
new_object->add_instance();
|
||||
new_object->instances[0]->printable = false;
|
||||
}
|
||||
new_object->instances[0]->printable |= object->instances[0]->printable;
|
||||
|
||||
const Transform3d& volume_offset_correction = transformation.get_matrix();
|
||||
const Transform3d new_inst_trafo = new_object->instances[0]->get_matrix().inverse() * object->instances[0]->get_matrix();
|
||||
|
||||
// merge volumes
|
||||
for (const ModelVolume* volume : object->volumes) {
|
||||
ModelVolume* new_volume = new_object->add_volume(*volume);
|
||||
|
||||
//set rotation
|
||||
const Vec3d vol_rot = new_volume->get_rotation() + rotation;
|
||||
new_volume->set_rotation(vol_rot);
|
||||
|
||||
// set scale
|
||||
const Vec3d vol_sc_fact = new_volume->get_scaling_factor().cwiseProduct(scale);
|
||||
new_volume->set_scaling_factor(vol_sc_fact);
|
||||
|
||||
// set mirror
|
||||
const Vec3d vol_mirror = new_volume->get_mirror().cwiseProduct(mirror);
|
||||
new_volume->set_mirror(vol_mirror);
|
||||
|
||||
// set offset
|
||||
const Vec3d vol_offset = volume_offset_correction* new_volume->get_offset();
|
||||
new_volume->set_offset(vol_offset);
|
||||
new_volume->set_transformation(new_inst_trafo * new_volume->get_matrix());
|
||||
}
|
||||
new_object->sort_volumes(wxGetApp().app_config->get_bool("order_volumes"));
|
||||
|
||||
|
@ -181,6 +181,12 @@ Preview::Preview(
|
||||
load_print();
|
||||
}
|
||||
|
||||
void Preview::set_layers_slider_values_range(int bottom, int top)
|
||||
{
|
||||
m_layers_slider->SetHigherValue(std::min(top, m_layers_slider->GetMaxValue()));
|
||||
m_layers_slider->SetLowerValue(std::max(bottom, m_layers_slider->GetMinValue()));
|
||||
}
|
||||
|
||||
bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
||||
{
|
||||
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
|
||||
|
@ -151,6 +151,8 @@ public:
|
||||
|
||||
void set_keep_current_preview_type(bool value) { m_keep_current_preview_type = value; }
|
||||
|
||||
void set_layers_slider_values_range(int bottom, int top);
|
||||
|
||||
private:
|
||||
bool init(wxWindow* parent, Bed3D& bed, Model* model);
|
||||
|
||||
|
@ -1488,8 +1488,7 @@ void GLGizmoCut3D::PartSelection::render(const Vec3d* normal, GLModel& sphere_mo
|
||||
if (!m_parts[id].is_modifier && normal && ((is_looking_forward && m_parts[id].selected) ||
|
||||
(!is_looking_forward && !m_parts[id].selected) ) )
|
||||
continue;
|
||||
const Vec3d volume_offset = model_object()->volumes[id]->get_offset();
|
||||
shader->set_uniform("view_model_matrix", view_inst_matrix * translation_transform(volume_offset));
|
||||
shader->set_uniform("view_model_matrix", view_inst_matrix * model_object()->volumes[id]->get_matrix());
|
||||
if (m_parts[id].is_modifier) {
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
@ -2425,7 +2424,7 @@ bool GLGizmoCut3D::has_valid_contour() const
|
||||
return clipper && clipper->has_valid_contour();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::apply_connectors_in_model(ModelObject* mo, bool &create_dowels_as_separate_object)
|
||||
void GLGizmoCut3D::apply_connectors_in_model(ModelObject* mo, int &dowels_count)
|
||||
{
|
||||
if (m_connector_mode == CutConnectorMode::Manual) {
|
||||
clear_selection();
|
||||
@ -2436,7 +2435,7 @@ void GLGizmoCut3D::apply_connectors_in_model(ModelObject* mo, bool &create_dowel
|
||||
if (connector.attribs.type == CutConnectorType::Dowel) {
|
||||
if (connector.attribs.style == CutConnectorStyle::Prism)
|
||||
connector.height *= 2;
|
||||
create_dowels_as_separate_object = true;
|
||||
dowels_count ++;
|
||||
}
|
||||
else {
|
||||
// calculate shift of the connector center regarding to the position on the cut plane
|
||||
@ -2465,6 +2464,34 @@ Transform3d GLGizmoCut3D::get_cut_matrix(const Selection& selection)
|
||||
return translation_transform(cut_center_offset) * m_rotation_m;
|
||||
}
|
||||
|
||||
void update_object_cut_id(CutObjectBase& cut_id, ModelObjectCutAttributes attributes, const int dowels_count)
|
||||
{
|
||||
// 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) ||
|
||||
attributes.has(ModelObjectCutAttribute::InvalidateCutInfo))
|
||||
return;
|
||||
|
||||
if (cut_id.id().invalid())
|
||||
cut_id.init();
|
||||
// increase check sum, if it's needed
|
||||
{
|
||||
int cut_obj_cnt = -1;
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) cut_obj_cnt++;
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower)) cut_obj_cnt++;
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels)) cut_obj_cnt+= dowels_count;
|
||||
if (cut_obj_cnt > 0)
|
||||
cut_id.increase_check_sum(size_t(cut_obj_cnt));
|
||||
}
|
||||
}
|
||||
|
||||
void synchronize_model_after_cut(Model& model, const CutObjectBase& cut_id)
|
||||
{
|
||||
for (ModelObject* obj : model.objects)
|
||||
if (obj->is_cut() && obj->cut_id.has_same_id(cut_id) && !obj->cut_id.is_equal(cut_id))
|
||||
obj->cut_id.copy(cut_id);
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
{
|
||||
if (!can_perform_cut())
|
||||
@ -2493,11 +2520,13 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
ModelObject* cut_mo = cut_by_contour ? m_part_selection.model_object() : nullptr;
|
||||
if (cut_mo)
|
||||
cut_mo->cut_connectors = mo->cut_connectors;
|
||||
else
|
||||
cut_mo = mo;
|
||||
|
||||
bool create_dowels_as_separate_object = false;
|
||||
int dowels_count = 0;
|
||||
const bool has_connectors = !mo->cut_connectors.empty();
|
||||
// update connectors pos as offset of its center before cut performing
|
||||
apply_connectors_in_model(cut_mo ? cut_mo : mo , create_dowels_as_separate_object);
|
||||
apply_connectors_in_model(cut_mo , dowels_count);
|
||||
|
||||
wxBusyCursor wait;
|
||||
|
||||
@ -2510,33 +2539,27 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
only_if(m_place_on_cut_lower, ModelObjectCutAttribute::PlaceOnCutLower) |
|
||||
only_if(m_rotate_upper, ModelObjectCutAttribute::FlipUpper) |
|
||||
only_if(m_rotate_lower, ModelObjectCutAttribute::FlipLower) |
|
||||
only_if(create_dowels_as_separate_object, ModelObjectCutAttribute::CreateDowels) |
|
||||
only_if(!has_connectors, ModelObjectCutAttribute::InvalidateCutInfo);
|
||||
only_if(dowels_count > 0, ModelObjectCutAttribute::CreateDowels) |
|
||||
only_if(!has_connectors && cut_mo->cut_id.id().invalid(), ModelObjectCutAttribute::InvalidateCutInfo);
|
||||
|
||||
// update cut_id for the cut object in respect to the attributes
|
||||
update_object_cut_id(cut_mo->cut_id, attributes, dowels_count);
|
||||
|
||||
ModelObjectPtrs cut_object_ptrs;
|
||||
if (cut_by_contour) {
|
||||
// apply cut attributes for object
|
||||
if (m_keep_upper && m_keep_lower)
|
||||
cut_mo->apply_cut_attributes(ModelObjectCutAttribute::KeepLower | ModelObjectCutAttribute::KeepUpper |
|
||||
only_if(create_dowels_as_separate_object, ModelObjectCutAttribute::CreateDowels));
|
||||
|
||||
// Clone the object to duplicate instances, materials etc.
|
||||
ModelObject* upper{ nullptr };
|
||||
if (m_keep_upper) cut_mo->clone_for_cut(&upper);
|
||||
ModelObject* lower{ nullptr };
|
||||
if (m_keep_lower) cut_mo->clone_for_cut(&lower);
|
||||
|
||||
auto add_cut_objects = [this, &instance_idx, &cut_matrix](ModelObjectPtrs& cut_objects, ModelObject* upper, ModelObject* lower, bool invalidate_cut = true) {
|
||||
auto add_cut_objects = [this, &instance_idx, &cut_matrix](ModelObjectPtrs& cut_objects, ModelObject* upper, ModelObject* lower) {
|
||||
if (upper && !upper->volumes.empty()) {
|
||||
ModelObject::reset_instance_transformation(upper, instance_idx, cut_matrix, m_place_on_cut_upper, m_rotate_upper);
|
||||
if (invalidate_cut)
|
||||
upper->invalidate_cut();
|
||||
cut_objects.push_back(upper);
|
||||
}
|
||||
if (lower && !lower->volumes.empty()) {
|
||||
ModelObject::reset_instance_transformation(lower, instance_idx, cut_matrix, m_place_on_cut_lower, m_place_on_cut_lower || m_rotate_lower);
|
||||
if (invalidate_cut)
|
||||
lower->invalidate_cut();
|
||||
cut_objects.push_back(lower);
|
||||
}
|
||||
};
|
||||
@ -2574,7 +2597,7 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
if (volumes.size() == cut_parts_cnt) {
|
||||
// Means that object is cut without connectors
|
||||
|
||||
// Just add Upper and Lower objects to cut_object_ptrs and invalidate any cut information
|
||||
// Just add Upper and Lower objects to cut_object_ptrs
|
||||
add_cut_objects(cut_object_ptrs, upper, lower);
|
||||
}
|
||||
else if (volumes.size() > cut_parts_cnt) {
|
||||
@ -2588,7 +2611,7 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
|
||||
// Perform cut just to get connectors
|
||||
const ModelObjectPtrs cut_connectors_obj = cut_mo->cut(instance_idx, get_cut_matrix(selection), attributes);
|
||||
assert(create_dowels_as_separate_object ? cut_connectors_obj.size() >= 3 : cut_connectors_obj.size() == 2);
|
||||
assert(dowels_count > 0 ? cut_connectors_obj.size() >= 3 : cut_connectors_obj.size() == 2);
|
||||
|
||||
// Connectors from upper object
|
||||
for (const ModelVolume* volume : cut_connectors_obj[0]->volumes)
|
||||
@ -2598,8 +2621,8 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
for (const ModelVolume* volume : cut_connectors_obj[1]->volumes)
|
||||
lower->add_volume(*volume, volume->type());
|
||||
|
||||
// Add Upper and Lower objects to cut_object_ptrs with saved cut information
|
||||
add_cut_objects(cut_object_ptrs, upper, lower, false);
|
||||
// Add Upper and Lower objects to cut_object_ptrs
|
||||
add_cut_objects(cut_object_ptrs, upper, lower);
|
||||
|
||||
// Add Dowel-connectors as separate objects to cut_object_ptrs
|
||||
if (cut_connectors_obj.size() >= 3)
|
||||
@ -2633,14 +2656,18 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
}
|
||||
}
|
||||
else
|
||||
cut_object_ptrs = mo->cut(instance_idx, cut_matrix, attributes);
|
||||
cut_object_ptrs = cut_mo->cut(instance_idx, cut_matrix, attributes);
|
||||
|
||||
// save cut_id to post update synchronization
|
||||
const CutObjectBase cut_id = cut_mo->cut_id;
|
||||
|
||||
// update cut results on plater and in the model
|
||||
plater->cut(object_idx, cut_object_ptrs);
|
||||
|
||||
synchronize_model_after_cut(plater->model(), cut_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Unprojects the mouse position on the mesh and saves hit point and normal of the facet into pos_and_normal
|
||||
// Return false if no intersection was found, true otherwise.
|
||||
bool GLGizmoCut3D::unproject_on_cut_plane(const Vec2d& mouse_position, Vec3d& pos, Vec3d& pos_world, bool respect_disabled_contour/* = true*/)
|
||||
|
@ -315,7 +315,7 @@ private:
|
||||
|
||||
bool can_perform_cut() const;
|
||||
bool has_valid_contour() const;
|
||||
void apply_connectors_in_model(ModelObject* mo, bool &create_dowels_as_separate_object);
|
||||
void apply_connectors_in_model(ModelObject* mo, int &dowels_count);
|
||||
bool cut_line_processing() const;
|
||||
void discard_cut_line_processing();
|
||||
|
||||
|
@ -243,7 +243,7 @@ coord_t get_skirt_offset(const Plater* plater) {
|
||||
|
||||
void ArrangeJob::prepare()
|
||||
{
|
||||
wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all();
|
||||
m_selection_only ? prepare_selected() : prepare_all();
|
||||
|
||||
coord_t min_offset = 0;
|
||||
for (auto &ap : m_selected) {
|
||||
@ -307,7 +307,10 @@ void ArrangeJob::process(Ctl &ctl)
|
||||
_u8L("Arranging done."));
|
||||
}
|
||||
|
||||
ArrangeJob::ArrangeJob() : m_plater{wxGetApp().plater()} {}
|
||||
ArrangeJob::ArrangeJob(Mode mode)
|
||||
: m_plater{wxGetApp().plater()},
|
||||
m_selection_only{mode == Mode::SelectionOnly}
|
||||
{}
|
||||
|
||||
static std::string concat_strings(const std::set<std::string> &strings,
|
||||
const std::string &delim = "\n")
|
||||
|
@ -24,6 +24,7 @@ class ArrangeJob : public Job
|
||||
coord_t m_min_bed_inset = 0.;
|
||||
|
||||
Plater *m_plater;
|
||||
bool m_selection_only = false;
|
||||
|
||||
// clear m_selected and m_unselected, reserve space for next usage
|
||||
void clear_input();
|
||||
@ -39,11 +40,13 @@ class ArrangeJob : public Job
|
||||
|
||||
public:
|
||||
|
||||
enum Mode { Full, SelectionOnly };
|
||||
|
||||
void prepare();
|
||||
|
||||
void process(Ctl &ctl) override;
|
||||
|
||||
ArrangeJob();
|
||||
ArrangeJob(Mode mode = Full);
|
||||
|
||||
int status_range() const
|
||||
{
|
||||
|
60
src/slic3r/GUI/Jobs/CancellableJob.hpp
Normal file
60
src/slic3r/GUI/Jobs/CancellableJob.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef CANCELLABLEJOB_HPP
|
||||
#define CANCELLABLEJOB_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "Job.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
template<class JobSubclass>
|
||||
class CancellableJob: public Job {
|
||||
JobSubclass m_job;
|
||||
std::atomic_bool &m_flag;
|
||||
|
||||
public:
|
||||
template<class... Args>
|
||||
CancellableJob(std::atomic_bool &flag, Args &&...args)
|
||||
: m_job{std::forward<Args>(args)...}, m_flag{flag}
|
||||
{}
|
||||
|
||||
void process(Ctl &ctl) override
|
||||
{
|
||||
m_flag.store(false);
|
||||
|
||||
struct CancelCtl : public Ctl
|
||||
{
|
||||
Ctl &basectl;
|
||||
std::atomic_bool &cflag;
|
||||
|
||||
CancelCtl (Ctl &c, std::atomic_bool &f): basectl{c}, cflag{f} {}
|
||||
|
||||
void update_status(int st, const std::string &msg = "") override
|
||||
{
|
||||
basectl.update_status(st, msg);
|
||||
}
|
||||
|
||||
bool was_canceled() const override
|
||||
{
|
||||
return cflag.load() || basectl.was_canceled();
|
||||
}
|
||||
|
||||
std::future<void> call_on_main_thread(
|
||||
std::function<void()> fn) override
|
||||
{
|
||||
return basectl.call_on_main_thread(fn);
|
||||
}
|
||||
} cctl(ctl, m_flag);
|
||||
|
||||
m_job.process(cctl);
|
||||
}
|
||||
|
||||
void finalize(bool canceled, std::exception_ptr &eptr) override
|
||||
{
|
||||
m_job.finalize(m_flag.load() || canceled, eptr);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif // CANCELLABLEJOB_HPP
|
@ -1,4 +1,5 @@
|
||||
#include "Plater.hpp"
|
||||
#include "slic3r/GUI/Jobs/UIThreadWorker.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
@ -1794,6 +1795,8 @@ struct Plater::priv
|
||||
bool init_view_toolbar();
|
||||
bool init_collapse_toolbar();
|
||||
|
||||
void set_preview_layers_slider_values_range(int bottom, int top);
|
||||
|
||||
void update_preview_moves_slider();
|
||||
void enable_preview_moves_slider(bool enable);
|
||||
|
||||
@ -4632,6 +4635,11 @@ bool Plater::priv::init_collapse_toolbar()
|
||||
return true;
|
||||
}
|
||||
|
||||
void Plater::priv::set_preview_layers_slider_values_range(int bottom, int top)
|
||||
{
|
||||
preview->set_layers_slider_values_range(bottom, top);
|
||||
}
|
||||
|
||||
void Plater::priv::update_preview_moves_slider()
|
||||
{
|
||||
preview->update_moves_slider();
|
||||
@ -6311,7 +6319,9 @@ void Plater::cut(size_t obj_idx, const ModelObjectPtrs& new_objects)
|
||||
for (size_t i = 0; i < new_objects.size(); ++i)
|
||||
selection.add_object((unsigned int)(last_id - i), i == 0);
|
||||
|
||||
arrange();
|
||||
UIThreadWorker w;
|
||||
replace_job(w, std::make_unique<ArrangeJob>(ArrangeJob::SelectionOnly));
|
||||
w.process_events();
|
||||
}
|
||||
|
||||
void Plater::export_gcode(bool prefer_removable)
|
||||
@ -7196,7 +7206,11 @@ void Plater::arrange()
|
||||
if (p->can_arrange()) {
|
||||
auto &w = get_ui_job_worker();
|
||||
p->take_snapshot(_L("Arrange"));
|
||||
replace_job(w, std::make_unique<ArrangeJob>());
|
||||
|
||||
auto mode = wxGetKeyState(WXK_SHIFT) ? ArrangeJob::SelectionOnly :
|
||||
ArrangeJob::Full;
|
||||
|
||||
replace_job(w, std::make_unique<ArrangeJob>(mode));
|
||||
}
|
||||
}
|
||||
|
||||
@ -7506,6 +7520,11 @@ GLToolbar& Plater::get_collapse_toolbar()
|
||||
return p->collapse_toolbar;
|
||||
}
|
||||
|
||||
void Plater::set_preview_layers_slider_values_range(int bottom, int top)
|
||||
{
|
||||
p->set_preview_layers_slider_values_range(bottom, top);
|
||||
}
|
||||
|
||||
void Plater::update_preview_moves_slider()
|
||||
{
|
||||
p->update_preview_moves_slider();
|
||||
|
@ -399,6 +399,8 @@ public:
|
||||
const GLToolbar& get_collapse_toolbar() const;
|
||||
GLToolbar& get_collapse_toolbar();
|
||||
|
||||
void set_preview_layers_slider_values_range(int bottom, int top);
|
||||
|
||||
void update_preview_moves_slider();
|
||||
void enable_preview_moves_slider(bool enable);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user