Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
YuSanka 2021-01-13 14:18:55 +01:00
commit af6ef2cb8a
83 changed files with 5953 additions and 3249 deletions

View File

@ -0,0 +1,46 @@
# - Try to find GTK+ 3
# Once done, this will define
#
# GTK3_FOUND - system has GTK+ 3.
# GTK3_INCLUDE_DIRS - the GTK+ 3. include directories
# GTK3_LIBRARIES - link these to use GTK+ 3.
#
# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
# Copyright (C) 2013 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
find_package(PkgConfig)
pkg_check_modules(GTK3 QUIET gtk+-3.0)
set(VERSION_OK TRUE)
if (GTK3_VERSION)
if (GTK3_FIND_VERSION_EXACT)
if (NOT("${GTK3_FIND_VERSION}" VERSION_EQUAL "${GTK3_VERSION}"))
set(VERSION_OK FALSE)
endif ()
else ()
if ("${GTK3_VERSION}" VERSION_LESS "${GTK3_FIND_VERSION}")
set(VERSION_OK FALSE)
endif ()
endif ()
endif ()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK3 DEFAULT_MSG GTK3_INCLUDE_DIRS GTK3_LIBRARIES VERSION_OK)

View File

@ -5169,7 +5169,7 @@ msgid "The supplied name is empty. It can't be saved."
msgstr ""
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:547
msgid "You should to change a name of your printer device. It can't be saved."
msgid "You should change the name of your printer device."
msgstr ""
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:555

View File

@ -10371,6 +10371,10 @@ msgstr "Světové souřadnice"
msgid "Would you like to install it?\n\nNote that a full configuration snapshot will be created first. It can then be restored at any time should there be a problem with the new version.\n\nUpdated configuration bundles:"
msgstr "Přejete si spustit instalaci?\n\nNejprve bude provedena kompletní záloha nastavení. V případě problémů s novou verzí ji bude možné kdykoliv obnovit.\n\nAktualizované balíčky nastavení:"
#: src/slic3r/GUI/GUI_App.cpp:1802
msgid "Would you like to stop uploads and close the program?"
msgstr "Chcete zastavit nahrávání a ukončit program?"
#: src/libslic3r/miniz_extension.cpp:151
msgid "write calledback failed"
msgstr "zpětné volání se nezdařilo"
@ -10478,8 +10482,8 @@ msgid "You need to restart %s to make the changes effective."
msgstr "Chcete-li provést změny, musíte restartovat aplikaci %s."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:468
msgid "You should to change a name of your printer device. It can't be saved."
msgstr "Měli byste změnit název tiskového zařízení. Nemůže být uloženo."
msgid "You should change the name of your printer device."
msgstr "Měli byste změnit název tiskového zařízení."
#: src/slic3r/GUI/GUI_ObjectList.cpp:3884
#, possible-c-format

View File

@ -10369,6 +10369,10 @@ msgstr "Weltkoordinaten"
msgid "Would you like to install it?\n\nNote that a full configuration snapshot will be created first. It can then be restored at any time should there be a problem with the new version.\n\nUpdated configuration bundles:"
msgstr "Möchten Sie dies installieren?\n\nBeachten Sie, dass zuerst eine Momentaufnahme der gesamten Konfiguration erstellt wird. Diese kann dann jederzeit wiederhergestellt werden, falls es ein Problem mit der neuen Version gibt.\n\nAktualisierte Konfigurationssammlungen:"
#: src/slic3r/GUI/GUI_App.cpp:1802
msgid "Would you like to stop uploads and close the program?"
msgstr "Möchten Sie die Uploads stoppen und das Programm schließen?"
#: src/libslic3r/miniz_extension.cpp:151
msgid "write calledback failed"
msgstr "Schreibabruf fehlgeschlagen"
@ -10476,8 +10480,8 @@ msgid "You need to restart %s to make the changes effective."
msgstr "Sie müssen %s neu starten, damit die Änderungen wirksam werden."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:468
msgid "You should to change a name of your printer device. It can't be saved."
msgstr "Sie sollten den Namen Ihres Druckers ändern. Er kann nicht gespeichert werden."
msgid "You should change the name of your printer device."
msgstr "Sie sollten den Namen Ihres Druckers ändern."
#: src/slic3r/GUI/GUI_ObjectList.cpp:3884
#, possible-c-format

View File

@ -8607,7 +8607,7 @@ msgstr "Comenzar en altura"
#: src/slic3r/GUI/Tab.cpp:1873 src/slic3r/GUI/Tab.cpp:2161
#: src/libslic3r/PrintConfig.cpp:1928 src/libslic3r/PrintConfig.cpp:1943
msgid "Start G-code"
msgstr "Comenzar el código G"
msgstr "Código G inicial"
#: src/slic3r/GUI/MainFrame.cpp:1133
msgid "Start new slicing process"
@ -9521,7 +9521,7 @@ msgstr "Este procedimiento de inicio se inserta al principio, después de que cu
#: src/libslic3r/PrintConfig.cpp:1929
msgid "This start procedure is inserted at the beginning, after bed has reached the target temperature and extruder just started heating, and before extruder has finished heating. If PrusaSlicer detects M104 or M190 in your custom codes, such commands will not be prepended automatically so you're free to customize the order of heating commands and other custom actions. Note that you can use placeholder variables for all PrusaSlicer settings, so you can put a \"M109 S[first_layer_temperature]\" command wherever you want."
msgstr "Este procedimiento de inicio se inserta al principio, después de que la bse ha alcanzado la temperatura objetivo y el extrusor acaba de comenzar a calentar, y antes de que el extrusor haya terminado de calentar. Si PrusaSlicer detecta un M104 o M190 en tus códigos personalizados, dichos comandos no se agregarán automáticamente, por lo que se puede personalizar el orden de los comandos de calentamiento y otras acciones personalizadas. Ten en cuenta que puedes usar variables de marcador de posición para todas las configuraciones de PrusaSlicer, por lo que puedes colocar un comando \"M109 S [first_layer_temperature]\" donde lo desees."
msgstr "Este procedimiento de inicio se inserta al principio, después de que la base ha alcanzado la temperatura objetivo y el extrusor acaba de comenzar a calentar, y antes de que el extrusor haya terminado de calentar. Si PrusaSlicer detecta un M104 o M190 en tus códigos personalizados, dichos comandos no se agregarán automáticamente, por lo que se puede personalizar el orden de los comandos de calentamiento y otras acciones personalizadas. Ten en cuenta que puedes usar variables de marcador de posición para todas las configuraciones de PrusaSlicer, por lo que puedes colocar un comando \"M109 S [first_layer_temperature]\" donde lo desees."
#: src/libslic3r/PrintConfig.cpp:731
msgid "This string is edited by RammingDialog and contains ramming specific parameters."
@ -10369,6 +10369,10 @@ msgstr "Coordenadas mundiales"
msgid "Would you like to install it?\n\nNote that a full configuration snapshot will be created first. It can then be restored at any time should there be a problem with the new version.\n\nUpdated configuration bundles:"
msgstr "¿Te gustaría instalarlo?\n\nTen en cuenta que primero se creará una instantánea de la configuración. Así que se puede recuperar en cualquier momento en caso de que hubiera algún problema con la nueva versión.\nUpdated configuration bundles:"
#: src/slic3r/GUI/GUI_App.cpp:1802
msgid "Would you like to stop uploads and close the program?"
msgstr "¿Te gustaría detener las subidas y cerrar el programa?"
#: src/libslic3r/miniz_extension.cpp:151
msgid "write calledback failed"
msgstr "fallo write calledback"
@ -10476,8 +10480,8 @@ msgid "You need to restart %s to make the changes effective."
msgstr "Es necesario reiniciar %s para hacer los cambios efectivos."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:468
msgid "You should to change a name of your printer device. It can't be saved."
msgstr "Debería cambiar el nombre de su dispositivo de impresión. No se puede guardar."
msgid "You should change the name of your printer device."
msgstr "Debería cambiar el nombre de su dispositivo de impresión."
#: src/slic3r/GUI/GUI_ObjectList.cpp:3884
#, possible-c-format

View File

@ -10369,6 +10369,10 @@ msgstr "Les coordonnées mondiales"
msgid "Would you like to install it?\n\nNote that a full configuration snapshot will be created first. It can then be restored at any time should there be a problem with the new version.\n\nUpdated configuration bundles:"
msgstr "Voulez-vous l'installer ?\n\nNotez qu'un instantané complet de la configuration sera sauvegardé d'abord. Elle peut être restaurée à tout moment si vous rencontrez un problème avec la nouvelle version.\n\nEnsembles de configuration mis à jour :"
#: src/slic3r/GUI/GUI_App.cpp:1802
msgid "Would you like to stop uploads and close the program?"
msgstr "Souhaitez-vous arrêter les téléchargements et fermer le programme ?"
#: src/libslic3r/miniz_extension.cpp:151
msgid "write calledback failed"
msgstr "échec de l'écriture du rappel"
@ -10476,8 +10480,8 @@ msgid "You need to restart %s to make the changes effective."
msgstr "Vous devez redémarrer %s afin que les modifications soient appliquées."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:468
msgid "You should to change a name of your printer device. It can't be saved."
msgstr "Vous devez changer le nom de votre imprimante. Il ne peut pas être enregistré."
msgid "You should change the name of your printer device."
msgstr "Vous devez changer le nom de votre imprimante."
#: src/slic3r/GUI/GUI_ObjectList.cpp:3884
#, possible-c-format

View File

@ -10369,6 +10369,10 @@ msgstr "Coordinate reali"
msgid "Would you like to install it?\n\nNote that a full configuration snapshot will be created first. It can then be restored at any time should there be a problem with the new version.\n\nUpdated configuration bundles:"
msgstr "Vuoi installarlo?\n\nNota: verrà prima creata un'istantanea della configurazione completa. Potrà essere ripristinata in qualunque momento se dovessero presentarsi problemi con la nuova versione.\n\nGruppo di configurazioni aggiornate:"
#: src/slic3r/GUI/GUI_App.cpp:1802
msgid "Would you like to stop uploads and close the program?"
msgstr "Desideri interrompere il caricamento e chiudere il programma?"
#: src/libslic3r/miniz_extension.cpp:151
msgid "write calledback failed"
msgstr "scrittura richiamo non riuscita"
@ -10476,8 +10480,8 @@ msgid "You need to restart %s to make the changes effective."
msgstr "È necessario riavviare %s per rendere effettive le modifiche."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:468
msgid "You should to change a name of your printer device. It can't be saved."
msgstr "Devi cambiare il nome del dispositivo di stampa. Non può essere salvato."
msgid "You should change the name of your printer device."
msgstr "Devi cambiare il nome del dispositivo di stampa."
#: src/slic3r/GUI/GUI_ObjectList.cpp:3884
#, possible-c-format

View File

@ -5423,9 +5423,8 @@ msgid "The supplied name is empty. It can't be saved."
msgstr "De ingevoerde naam is leeg. Kan niet opgeslagen worden."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:547
msgid "You should to change a name of your printer device. It can't be saved."
msgstr ""
"Je moet de naam van de printer aanpassen. Het kan niet opgeslagen worden."
msgid "You should change the name of your printer device."
msgstr "Je moet de naam van de printer aanpassen."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:555
msgid "Printer with name \"%1%\" already exists."
@ -6831,7 +6830,7 @@ msgstr "Voorinstelling opslaan"
#: src/slic3r/GUI/SavePresetDialog.cpp:215
msgctxt "PresetName"
msgid "Copy"
msgstr "Kopieer"
msgstr "Kopie"
#: src/slic3r/GUI/SavePresetDialog.cpp:273
msgid ""

View File

@ -6570,7 +6570,7 @@ msgstr "Średnice"
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:209 src/slic3r/GUI/Tab.cpp:2024
msgid "Print Host upload"
msgstr "Wysyłanie do serwera druku"
msgstr "Przesyłanie do serwera druku"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:138
#: src/slic3r/GUI/PrintHostDialogs.cpp:136
@ -10373,6 +10373,10 @@ msgstr "Globalny układ współrzędnych"
msgid "Would you like to install it?\n\nNote that a full configuration snapshot will be created first. It can then be restored at any time should there be a problem with the new version.\n\nUpdated configuration bundles:"
msgstr "Czy chcesz kontynuować instalację?\n\nWeź pod uwagę, że najpierw zostanie stworzony zrzut konfiguracji. Może być przywrócony w każdej chwili, gdyby okazało się, że nowa wersja powoduje problemy.\n\nZaktualizowane paczki konfiguracyjne:"
#: src/slic3r/GUI/GUI_App.cpp:1802
msgid "Would you like to stop uploads and close the program?"
msgstr "Czy chcesz zatrzymać przesyłanie i zamknąć program?"
#: src/libslic3r/miniz_extension.cpp:151
msgid "write calledback failed"
msgstr "błąd write calledback"
@ -10480,8 +10484,8 @@ msgid "You need to restart %s to make the changes effective."
msgstr "Wymagany jest restart %s, aby wprowadzić zmiany."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:468
msgid "You should to change a name of your printer device. It can't be saved."
msgstr "Należy zmienić nazwę drukarki. Nie można jej zapisać."
msgid "You should change the name of your printer device."
msgstr "Należy zmienić nazwę drukarki."
#: src/slic3r/GUI/GUI_ObjectList.cpp:3884
#, possible-c-format

File diff suppressed because it is too large Load Diff

View File

@ -5122,7 +5122,7 @@ msgid "The supplied name is empty. It can't be saved."
msgstr "Имя не задано. Невозможно сохранить."
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:547
msgid "You should to change a name of your printer device. It can't be saved."
msgid "You should change the name of your printer device."
msgstr ""
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:555

View File

@ -1,4 +1,7 @@
min_slic3r_version = 2.3.0-rc2
0.0.12 Added Ender-3V2 and filament profiles.
min_slic3r_version = 2.3.0-beta2
0.0.11 Updated machine limits for Ender 5 and Ender 5 Plus.
0.0.10 Parameter consistency improvements. Enabled conservative elephant foot compensation.
0.0.9 Fixed end g-code for Ender 5.
0.0.8 Slight end g-code improvements and spool weights.

View File

@ -5,7 +5,7 @@
name = Creality
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.0.10
config_version = 0.0.12
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -23,6 +23,15 @@ bed_model = ender3_bed.stl
bed_texture = ender3.svg
default_materials = Creality PLA @CREALITY; Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY
[printer_model:ENDER3V2]
name = Creality Ender-3V2
variants = 0.4
technology = FFF
family = ENDER
bed_model = ender3_bed.stl
bed_texture = ender3.svg
default_materials = Creality PLA @CREALITY; Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY
[printer_model:ENDER3BLTOUCH]
name = Creality Ender-3 BLTouch
variants = 0.4
@ -576,6 +585,26 @@ filament_cost = 19.50
filament_density = 1.24
filament_colour = #FFE200
[filament:Das Filament PLA @CREALITY]
inherits = *PLA*
filament_vendor = Das Filament
temperature = 215
bed_temperature = 50
first_layer_temperature = 215
first_layer_bed_temperature = 50
filament_cost = 20.56
filament_density = 1.24
[filament:Das Filament PETG @CREALITY]
inherits = *PET*
filament_vendor = Das Filament
temperature = 240
bed_temperature = 70
first_layer_temperature = 240
first_layer_bed_temperature = 70
filament_cost = 27.44
filament_density = 1.29
# Common printer preset
[printer:*common*]
printer_technology = FFF
@ -669,6 +698,12 @@ retract_before_wipe = 70%
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print head up\nG1 X5 Y170 F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600{endif} ; Move print head further up\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors
[printer:Creality Ender-3V2]
inherits = Creality Ender-3
printer_model = ENDER3V2
printer_variant = 0.4
bed_shape = 0x0,220x0,220x220,0x220
[printer:*fastabl*]
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
@ -690,6 +725,8 @@ bed_shape = 5x2.5,225x2.5,225x222.5,5x222.5
printer_model = ENDER5
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER5\nPRINTER_HAS_BOWDEN
max_print_height = 300
machine_max_acceleration_e = 1000
machine_max_feedrate_z = 5
[printer:Creality Ender-5 Plus]
inherits = Creality Ender-3; *slowabl*; *invertedz*
@ -698,6 +735,10 @@ bed_shape = 5x5,355x5,355x355,5x355
printer_model = ENDER5PLUS
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER5PLUS\nPRINTER_HAS_BOWDEN
max_print_height = 400
machine_max_acceleration_e = 1000
machine_max_feedrate_z = 5
machine_max_feedrate_x = 300
machine_max_feedrate_y = 300
[printer:Creality Ender-2]
inherits = Creality Ender-3

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,2 @@
min_slic3r_version = 2.3.0-rc2
0.0.1 Initial Version

View File

@ -0,0 +1,842 @@
# Print profiles for the FLSun Delta printers.
##
# Author: https://github.com/Foxies-CSTL/PrusaSlicer
## Initial PR: https://github.com/prusa3d/PrusaSlicer/pull/5582
[vendor]
# Vendor name will be shown by the Config Wizard.
name = FLSun
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.0.1
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/FLSun/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
# The printer models will be shown by the Configuration Wizard in this order,
# also the first model installed & the first nozzle installed will be activated after install.
# Printer model name will be shown by the installation wizard.
[printer_model:QQSP]
name = FLSun QQS Pro
variants = 0.4; 0.6
technology = FFF
bed_model = QQSP_bed.stl
bed_texture = QQSP.svg
default_materials = Generic PLA @FLSUN; Generic PETG @FLSUN; Generic ABS @FLSUN; Generic SPLA @FLSUN; Generic FLEX @FLSUN
[printer_model:Q5]
name = FLSun Q5
variants = 0.4; 0.6
technology = FFF
bed_model = Q5_bed.stl
bed_texture = Q5.svg
default_materials = Generic PLA @FLSUN; Generic PETG @FLSUN; Generic ABS @FLSUN; Generic SPLA @FLSUN; Generic FLEX @FLSUN
#########################################
###### begin Common print presets #######
#########################################
# Common print preset
[print:*common_flsunq*]
avoid_crossing_perimeters = 1
avoid_crossing_perimeters_max_detour = 0
bottom_solid_min_thickness = 0.5
bridge_acceleration = 800
bridge_angle = 0
bridge_flow_ratio = 0.8
bridge_speed = 30
brim_width = 0
clip_multipart_objects = 1
compatible_printers =
complete_objects = 0
default_acceleration = 800
dont_support_bridges = 1
elefant_foot_compensation = 0.2
ensure_vertical_shell_thickness = 1
external_fill_pattern = rectilinear
external_perimeters_first = 0
external_perimeter_extrusion_width = 0.45
extra_perimeters = 0
extruder_clearance_height = 45
extruder_clearance_radius = 45
extrusion_width = 0.45
fill_angle = 45
fill_density = 15%
fill_pattern = gyroid
first_layer_acceleration = 800
first_layer_extrusion_width = 0.42
first_layer_height = 0.2
first_layer_speed = 20
gap_fill_speed = 40
gcode_comments = 0
infill_acceleration = 800
infill_every_layers = 1
infill_extruder = 1
infill_extrusion_width = 0.45
infill_first = 0
infill_only_where_needed = 0
infill_overlap = 25%
interface_shells = 0
ironing = 0
ironing_flowrate = 15%
ironing_spacing = 0.1
ironing_speed = 15
ironing_type = top
max_print_speed = 200
max_volumetric_extrusion_rate_slope_negative = 0
max_volumetric_extrusion_rate_slope_positive = 0
max_volumetric_speed = 0
min_skirt_length = 4
notes =
overhangs = 1
only_retract_when_crossing_perimeters = 0
ooze_prevention = 0
output_filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gco
perimeters = 3
perimeter_acceleration = 800
perimeter_extruder = 1
perimeter_extrusion_width = 0.45
perimeter_speed = 45
post_process =
print_settings_id =
raft_layers = 0
resolution = 0
seam_position = nearest
single_extruder_multi_material_priming = 0
skirts = 2
skirt_distance = 5
skirt_height = 1
small_perimeter_speed = 25
solid_infill_below_area = 0
solid_infill_every_layers = 0
solid_infill_extruder = 1
solid_infill_extrusion_width = 0.45
spiral_vase = 0
standby_temperature_delta = -5
support_material = 1
support_material_auto = 0
support_material_extruder = 1
support_material_extrusion_width = 0.38
support_material_interface_extruder = 0
support_material_angle = 0
support_material_buildplate_only = 0
support_material_enforce_layers = 0
support_material_contact_distance = 0.2
support_material_interface_contact_loops = 0
support_material_interface_layers = 2
support_material_interface_spacing = 0.2
support_material_interface_speed = 100%
support_material_pattern = rectilinear
support_material_spacing = 2.5
support_material_speed = 60
support_material_synchronize_layers = 0
support_material_threshold = 45
support_material_with_sheath = 0
support_material_xy_spacing = 60%
thin_walls = 0
top_infill_extrusion_width = 0.4
top_solid_infill_speed = 40
top_solid_min_thickness = 0.6
travel_speed = 150
wipe_tower = 0
wipe_tower_bridging = 10
wipe_tower_rotation_angle = 0
wipe_tower_width = 60
wipe_tower_x = 170
wipe_tower_y = 140
xy_size_compensation = 0
## QQS
[print:*QQSP*]
bridge_acceleration = 1000
default_acceleration = 1500
first_layer_acceleration = 1000
infill_acceleration = 800
max_print_speed = 200
perimeter_acceleration = 800
## Q5
[print:*Q5*]
bridge_acceleration = 1000
default_acceleration = 800
first_layer_acceleration = 800
infill_acceleration = 1000
max_print_speed = 150
perimeter_acceleration = 800
# Print parameters common to a 0.6mm diameter nozzle.
[print:*0.6nozzleFLSUN*]
bridge_acceleration = 1000
bridge_flow_ratio = 0.95
bridge_speed = 25
default_acceleration = 1000
external_perimeter_extrusion_width = 0.65
extrusion_width = 0.65
first_layer_acceleration = 1000
first_layer_extrusion_width = 0.65
fill_density = 15%
fill_pattern = gyroid
infill_acceleration = 1000
infill_extrusion_width = 0.68
perimeter_acceleration = 800
perimeter_extrusion_width = 0.65
solid_infill_extrusion_width = 0.68
support_material_speed = 40
support_material_contact_distance = 0.15
support_material_extrusion_width = 0.55
support_material_xy_spacing = 80%
top_infill_extrusion_width = 0.6
travel_speed = 150
output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{filament_type[0]}_{print_time}.gco
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.08mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.08mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 10
bridge_flow_ratio = 0.7
layer_height = 0.08
support_material_contact_distance = 0.06
support_material_spacing = 1.5
top_solid_layers = 12
[print:0.08mm DETAIL @FLSUN]
inherits = *0.08mm_flsunq*; *QQSP*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
bridge_acceleration = 200
bridge_speed = 20
external_perimeter_speed = 70%
first_layer_acceleration = 500
first_layer_speed = 40%
gap_fill_speed = 20
infill_acceleration = 800
infill_speed = 40
max_print_speed = 80
perimeter_acceleration = 300
perimeter_speed = 30
small_perimeter_speed = 70%
solid_infill_speed = 95%
support_material_speed = 40
top_solid_infill_speed = 60%
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.15mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.15mm_vase_flsunq*]
inherits = *common_flsunq*
avoid_crossing_perimeters = 1
bottom_solid_min_thickness = 0.5
bridge_flow_ratio = 0.9
elefant_foot_compensation = 0.15
ensure_vertical_shell_thickness = 1
external_perimeter_extrusion_width = 0.9
extra_perimeters = 1
extrusion_width = 0.9
first_layer_acceleration = 1000
first_layer_height = 0.3
first_layer_extrusion_width = 0.9
first_layer_speed = 20
fill_density = 0%
infill_extrusion_width = 0.9
ironing = 0
layer_height = 0.15
min_skirt_length = 4
max_print_speed = 100
only_retract_when_crossing_perimeters = 0
perimeters = 1
perimeter_extrusion_width = 0.9
seam_position = aligned
slice_closing_radius = 0.049
solid_infill_extrusion_width = 0.6
spiral_vase = 1
support_material = 0
top_solid_infill_speed = 40%
top_solid_min_thickness = 0.6
thin_walls = 0
top_fill_pattern = rectilinear
top_solid_layers = 0
[print:0.15mm VASE @FLSUN]
inherits = *0.15mm_vase_flsunq*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
bottom_solid_layers = 5
external_perimeter_speed = 50%
gap_fill_speed = 40
infill_speed = 100
perimeter_speed = 80
small_perimeter_speed = 25%
solid_infill_speed = 33%
[print:0.15mm VASE SPEED @FLSUN]
inherits = *0.15mm_vase_flsunq*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
bridge_speed = 80
bottom_solid_layers = 3
external_perimeter_speed = 60%
gap_fill_speed = 30
infill_speed = 80
perimeter_speed = 90
small_perimeter_speed = 50%
solid_infill_speed = 80%
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.16mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.16mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 5
bridge_flow_ratio = 0.9
layer_height = 0.16
support_material_contact_distance = 0.12
top_solid_layers = 6
[print:0.16mm QUALITY @FLSUN]
inherits = *0.16mm_flsunq*; *QQSP*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50%
fill_density = 15%
fill_pattern = gyroid
infill_speed = 80
ironing = 0
perimeter_speed = 90
small_perimeter_speed = 25%
solid_infill_speed = 50%
top_solid_infill_speed = 30%
[print:0.16mm SPEED @FLSUN]
inherits = *0.16mm_flsunq*; *QQSP*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50%
infill_speed = 120
perimeter_speed = 60
small_perimeter_speed = 25%
solid_infill_speed = 85%
top_solid_infill_speed = 30%
[print:0.16mm DETAIL @0.6 nozzle FLSUN]
inherits = *0.16mm_flsunq*; *0.6nozzleFLSUN*
# alias = 0.16mm DETAIL
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_FLSun.*/ and printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 35
infill_speed = 70
max_print_speed = 80
perimeter_speed = 40
solid_infill_speed = 60
top_solid_infill_speed = 45
infill_extrusion_width = 0.65
solid_infill_extrusion_width = 0.65
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.20mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.20mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 4
bridge_flow_ratio = 0.95
layer_height = 0.20
support_material_contact_distance = 0.2
top_solid_layers = 5
[print:0.20mm QUALITY @FLSUN]
inherits = *0.20mm_flsunq*; *QQSP*
avoid_crossing_perimeters = 1
bridge_speed = 60
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50%
fill_density = 15%
gap_fill_speed = 30
infill_speed = 80
ironing = 0
ironing_speed = 20
perimeter_speed = 50
small_perimeter_speed = 85%
solid_infill_speed = 90%
thin_walls = 0
top_solid_infill_speed = 50%
[print:0.20mm DETAIL @0.6 nozzle FLSUN]
inherits = *0.20mm_flsunq*; *0.6nozzleFLSUN*
# alias = 0.20mm DETAIL
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_FLSun.*/ and printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 35
infill_speed = 70
max_print_speed = 80
perimeter_speed = 45
solid_infill_speed = 60
top_solid_infill_speed = 45
infill_extrusion_width = 0.65
solid_infill_extrusion_width = 0.65
[print:0.20mm SPEED @FLSUN]
inherits = *0.20mm_flsunq*; *QQSP*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50
extra_perimeters = 1
first_layer_speed = 35
infill_speed = 90
perimeter_speed = 60
small_perimeter_speed = 50%
solid_infill_speed = 85%
top_solid_infill_speed = 40%
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.24mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.24mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 4
bridge_flow_ratio = 0.95
layer_height = 0.24
support_material_contact_distance = 0.18
top_solid_layers = 4
[print:0.24mm DRAFT @FLSUN]
inherits = *0.24mm_flsunq*; *QQSP*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50%
first_layer_speed = 20%
infill_speed = 120
perimeter_speed = 60
small_perimeter_speed = 50%
solid_infill_speed = 95%
top_solid_infill_speed = 50%
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.30mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.30mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 3
bridge_flow_ratio = 0.95
external_perimeter_extrusion_width = 0.6
extrusion_width = 0.5
infill_extrusion_width = 0.5
layer_height = 0.30
perimeter_extrusion_width = 0.5
solid_infill_extrusion_width = 0.5
support_material_contact_distance = 0.22
top_infill_extrusion_width = 0.45
top_solid_layers = 4
[print:0.30mm QUALITY @0.6 nozzle FLSUN]
inherits = *0.30mm_flsunq*; *0.6nozzleFLSUN*
# alias = 0.30mm QUALITY
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_FLSun.*/ and printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 35
infill_speed = 90
max_print_speed = 100
perimeter_speed = 45
solid_infill_speed = 65
top_solid_infill_speed = 45
external_perimeter_extrusion_width = 0.68
perimeter_extrusion_width = 0.68
[print:0.30mm SPEED @FLSUN]
inherits = *0.30mm_flsunq*; *QQSP*
compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50%
first_layer_speed = 20%
infill_speed = 120
perimeter_speed = 80
small_perimeter_speed = 50%
solid_infill_speed = 85%
top_solid_infill_speed = 50%
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.35mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.35mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 3
external_perimeter_extrusion_width = 0.6
external_perimeter_speed = 40
first_layer_extrusion_width = 0.75
layer_height = 0.35
perimeter_extrusion_width = 0.65
solid_infill_extrusion_width = 0.65
solid_infill_speed = 60
top_solid_infill_speed = 50
top_solid_layers = 4
[print:0.35mm SPEED @0.6 nozzle FLSUN]
inherits = *0.35mm_flsunq*; *0.6nozzleFLSUN*
# alias = 0.35mm SPEED
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_FLSun.*/ and printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 45
infill_speed = 100
max_print_speed = 120
perimeter_speed = 65
solid_infill_speed = 60
top_solid_infill_speed = 45
external_perimeter_extrusion_width = 0.68
perimeter_extrusion_width = 0.68
# XXXXXXXXXXXXXXXXXXXX
# XXX--- 0.40mm ---XXX
# XXXXXXXXXXXXXXXXXXXX
[print:*0.40mm_flsunq*]
inherits = *common_flsunq*
bottom_solid_layers = 3
external_perimeter_extrusion_width = 0.6
external_perimeter_speed = 40
first_layer_extrusion_width = 0.65
infill_acceleration = 2000
infill_speed = 60
layer_height = 0.4
perimeter_acceleration = 800
perimeter_extrusion_width = 0.65
perimeter_speed = 50
solid_infill_extrusion_width = 0.65
solid_infill_speed = 60
top_solid_infill_speed = 40
top_solid_layers = 4
[print:0.40mm DRAFT @0.6 nozzle FLSUN]
inherits = *0.40mm_flsunq*; *0.6nozzleFLSUN*
# alias = 0.40mm DRAFT
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_FLSun.*/ and printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 60
infill_speed = 100
max_print_speed = 120
perimeter_speed = 60
solid_infill_speed = 60
top_solid_infill_speed = 60
external_perimeter_extrusion_width = 0.68
perimeter_extrusion_width = 0.68
infill_extrusion_width = 0.68
solid_infill_extrusion_width = 0.68
#########################################
########### end print presets ###########
#########################################
#########################################
######## begin filament presets #########
#########################################
# Common filament preset
[filament:*common_flsunq*]
cooling = 0
compatible_printers =
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_FLSun.*/ and printer_notes=~/.*PRINTER_MODEL_Q(QSP|5).*/
end_filament_gcode = "; Filament-specific end gcode"
extrusion_multiplier = 1
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_notes = ""
filament_settings_id = ""
filament_soluble = 0
min_fan_speed = 20
min_print_speed = 15
slowdown_below_layer_time = 15
start_filament_gcode = "; Filament gcode\n;M900 K{if nozzle_diameter[0]==0.6}0.12{else}0.22{endif} ; Linear Advance 1.5\n"
[filament:*PLA_flsunq*]
inherits = *common_flsunq*
bed_temperature = 60
bridge_fan_speed = 95
cooling = 1
disable_fan_first_layers = 1
fan_always_on = 1
fan_below_layer_time = 100
filament_colour = #FF3232
filament_density = 1.24
filament_deretract_speed = 30
filament_retract_length = 3
filament_retract_lift = nil
filament_retract_speed = 30
filament_max_volumetric_speed = 10
filament_type = PLA
filament_wipe = nil
first_layer_bed_temperature = 60
first_layer_temperature = 205
max_fan_speed = 90
min_fan_speed = 50
temperature = 200
[filament:*PLA_VASE_flsunq*]
inherits = *PLA_flsunq*
bridge_fan_speed = 100
disable_fan_first_layers = 3
fan_below_layer_time = 60
max_fan_speed = 100
min_fan_speed = 35
min_print_speed = 10
slowdown_below_layer_time = 5
[filament:*SPLA_flsunq*]
inherits = *common_flsunq*
bed_temperature = 80
bridge_fan_speed = 100
cooling = 1
disable_fan_first_layers = 1
fan_always_on = 1
fan_below_layer_time = 100
filament_colour = #008000
filament_density = 1.24
filament_deretract_speed = 70
filament_max_volumetric_speed = 8
filament_retract_length = 7.5
filament_retract_lift = nil
filament_retract_speed = 70
filament_type = PLA
filament_wipe = nil
first_layer_bed_temperature = 80
first_layer_temperature = 230
max_fan_speed = 70
min_fan_speed = 50
temperature = 215
[filament:*PET_flsunq*]
inherits = *common_flsunq*
bed_temperature = 80
bridge_fan_speed = 100
cooling = 1
disable_fan_first_layers = 3
fan_always_on = 1
fan_below_layer_time = 20
filament_colour = #FFFFFF
filament_density = 1.27
filament_deretract_speed = 25
filament_max_volumetric_speed = 8
filament_retract_length = 4
filament_retract_lift = 0.2
filament_retract_speed = 45
filament_type = PETG
filament_wipe = 1
first_layer_bed_temperature =80
first_layer_temperature = 240
max_fan_speed = 50
min_fan_speed = 20
temperature = 230
[filament:*FLEX_flsunq*]
inherits = *common_flsunq*
bed_temperature = 50
bridge_fan_speed = 80
compatible_printers_condition = nozzle_diameter[0]>0.35
cooling = 1
disable_fan_first_layers = 3
extrusion_multiplier = 1.15
fan_always_on = 0
fan_below_layer_time = 100
filament_colour = #0000FF
filament_density = 1.22
filament_deretract_speed = 25
filament_max_volumetric_speed = 1.35
filament_retract_length = 0.8
filament_retract_lift = nil
filament_retract_speed = nil
filament_type = FLEX
filament_wipe = 0
first_layer_bed_temperature = 50
first_layer_temperature = 240
slowdown_below_layer_time = 10
start_filament_gcode = "; Filament gcode\n;M900 K0; Disable Linear Advance 1.5\n"
temperature = 240
[filament:*ABS_flsunq*]
inherits = *common_flsunq*
bed_temperature = 90
bridge_fan_speed = 30
cooling = 0
disable_fan_first_layers = 3
fan_always_on = 0
fan_below_layer_time = 20
filament_colour = #FF8000
filament_density = 1.04
filament_deretract_speed = nil
filament_retract_length = 5
filament_retract_lift = nil
filament_retract_speed = 50
filament_max_volumetric_speed = 10
filament_type = ABS
filament_wipe = nil
first_layer_bed_temperature = 90
first_layer_temperature = 245
max_fan_speed = 0
min_fan_speed = 0
slowdown_below_layer_time = 20
temperature = 245
top_fan_speed = 0
[filament:Generic PLA @FLSUN]
inherits = *PLA_flsunq*
filament_vendor = Generic
[filament:Generic PLA VASE @FLSUN]
inherits = *PLA_VASE_flsunq*
filament_vendor = Generic
[filament:Generic PETG @FLSUN]
inherits = *PET_flsunq*
filament_vendor = Generic
[filament:Generic ABS @FLSUN]
inherits = *ABS_flsunq*
filament_vendor = Generic
[filament:Generic FLEX @FLSUN]
inherits = *FLEX_flsunq*
filament_vendor = Generic
[filament:Generic SPLA @FLSUN]
inherits = *SPLA_flsunq*
filament_vendor = Generic
#########################################
######### end filament presets ##########
#########################################
#########################################
######### begin printer presets #########
#########################################
# Common printer preset
[printer:*common_flsunq*]
printer_technology = FFF
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n
between_objects_gcode =
deretract_speed = 40
end_gcode =
extruder_colour = ""
extruder_offset = 0x0
gcode_flavor = marlin
layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
machine_min_extruding_rate = 0,0
machine_min_travel_rate = 0,0
max_layer_height = 0.32
min_layer_height = 0.08
nozzle_diameter = 0.4
printer_notes =
printer_settings_id =
remaining_times = 0
retract_before_travel = 2
retract_before_wipe = 70%
retract_layer_change = 0
retract_length = 0
retract_length_toolchange = 1
retract_lift = 0
retract_lift_above = 0
retract_lift_below = 0
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
silent_mode = 0
single_extruder_multi_material = 0
start_gcode =
toolchange_gcode =
use_firmware_retraction = 0
use_relative_e_distances = 1
variable_layer_height = 1
wipe = 1
z_offset = 0
default_print_profile = 0.20mm QUALITY @FLSUN
default_filament_profile = Generic PLA @FLSUN
[printer:FLSun QQS Pro]
inherits = *common_flsunq*
bed_shape = 129.505x11.3302,128.025x22.5743,125.57x33.6465,122.16x44.4626,117.82x54.9404,112.583x65,106.49x74.5649,99.5858x83.5624,91.9239x91.9239,83.5624x99.5858,74.5649x106.49,65x112.583,54.9404x117.82,44.4626x122.16,33.6465x125.57,22.5743x128.025,11.3302x129.505,7.9602e-15x130,-11.3302x129.505,-22.5743x128.025,-33.6465x125.57,-44.4626x122.16,-54.9404x117.82,-65x112.583,-74.5649x106.49,-83.5624x99.5858,-91.9239x91.9239,-99.5858x83.5624,-106.49x74.5649,-112.583x65,-117.82x54.9404,-122.16x44.4626,-125.57x33.6465,-128.025x22.5743,-129.505x11.3302,-130x1.59204e-14,-129.505x-11.3302,-128.025x-22.5743,-125.57x-33.6465,-122.16x-44.4626,-117.82x-54.9404,-112.583x-65,-106.49x-74.5649,-99.5858x-83.5624,-91.9239x-91.9239,-83.5624x-99.5858,-74.5649x-106.49,-65x-112.583,-54.9404x-117.82,-44.4626x-122.16,-33.6465x-125.57,-22.5743x-128.025,-11.3302x-129.505,-2.38806e-14x-130,11.3302x-129.505,22.5743x-128.025,33.6465x-125.57,44.4626x-122.16,54.9404x-117.82,65x-112.583,74.5649x-106.49,83.5624x-99.5858,91.9239x-91.9239,99.5858x-83.5624,106.49x-74.5649,112.583x-65,117.82x-54.9404,122.16x-44.4626,125.57x-33.6465,128.025x-22.5743,129.505x-11.3302,130x-3.18408e-14
end_gcode = ; printing object ENDGCODE\nG92 E0.0 ; prepare to retract\nG1 E-6 F3000; retract to avoid stringing\n; Anti-stringing end wiggle\n{if layer_z < max_print_height}G1 Z{min(layer_z+100, max_print_height)}{endif} F4000 ; Move print head up\nG1 X0 Y120 F3000 ; present print\n; Reset print setting overrides\nG92 E0\nM200 D0 ; disable volumetric e\nM220 S100 ; reset speed factor to 100%\nM221 S100 ; reset extruder factor to 100%\n;M900 K0 ; reset linear acceleration(Marlin)\n; Shut down printer\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM18 S180 ;disable motors after 180s\nM300 S40 P10 ; Bip\nM117 Print finish.
machine_max_acceleration_e = 3000,800
machine_max_acceleration_extruding = 1500,800
machine_max_acceleration_retracting = 2000,800
machine_max_acceleration_x = 1500,800
machine_max_acceleration_y = 1500,800
machine_max_acceleration_z = 1500,800
machine_max_feedrate_e = 60,30
machine_max_feedrate_x = 200,150
machine_max_feedrate_y = 200,150
machine_max_feedrate_z = 200,150
machine_max_jerk_e = 5,5
machine_max_jerk_x = 5,10
machine_max_jerk_y = 5,10
machine_max_jerk_z = 5,10
max_print_height = 360
nozzle_diameter = 0.4
printer_model = QQSP
printer_variant = 0.4
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_FLSun\nPRINTER_MODEL_QQSP\nPRINTER_HAS_BOWDEN\n
retract_length = 5
retract_speed = 30
retract_lift = 0.4
silent_mode = 1
start_gcode = ;STARTGCODE\nM117 Initializing\n; Set coordinate modes\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\n; Reset speed and extrusion rates\nM200 D0 ; disable volumetric E\nM220 S100 ; reset speed\n; Set initial warmup temps\nM117 Nozzle preheat\nM104 S100 ; preheat extruder to no ooze temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed final temp\nM300 S40 P10 ; Bip\n; Home\nM117 Homing\nG28 ; home all with default mesh bed level\n; For ABL users put G29 for a leveling request\n; Final warmup routine\nM117 Final warmup\nM104 S[first_layer_temperature] ; set extruder final temp\nM109 S[first_layer_temperature] ; wait for extruder final temp\nM190 S[first_layer_bed_temperature] ; wait for bed final temp\nM300 S440 P200 ; 1st beep for printer ready and allow some time to clean nozzle\nM300 S0 P250 ; wait between dual beep\nM300 S440 P200 ; 2nd beep for printer ready\nG4 S10 ; wait to clean the nozzle\nM300 S440 P200 ; 3rd beep for ready to start printing\n; Prime line routine\nM117 Printing prime line\n;M900 K0; Disable Linear Advance (Marlin) for prime line\nG92 E0.0; reset extrusion distance\nG1 X-54.672 Y-95.203 Z0.3 F4000; go outside print area\nG92 E0.0; reset extrusion distance\nG1 E2 F1000 ; de-retract and push ooze\nG3 X38.904 Y-102.668 I54.672 J95.105 E20.999\nG3 X54.671 Y-95.203 I-38.815 J102.373 E5.45800\nG92 E0.0\nG1 E-5 F3000 ; retract 5mm\nG1 X52.931 Y-96.185 F1000 ; wipe\nG1 X50.985 Y-97.231 F1000 ; wipe\nG1 X49.018 Y-98.238 F1000 ; wipe\nG1 X0 Y-109.798 F1000\nG1 E4.8 F1500; de-retract\nG92 E0.0 ; reset extrusion distance\n; Final print adjustments\nM117 Preparing to print\n;M82 ; extruder absolute mode\nM221 S{if layer_height<0.075}100{else}95{endif}\nM300 S40 P10 ; chirp\nM117 Print [input_filename]; Display: Printing started...
thumbnails = 16x16,260x260
use_relative_e_distances = 1
use_volumetric_e = 0
[printer:FLSun QQS Pro 0.6 nozzle]
inherits = FLSun QQS Pro
printer_variant = 0.6
nozzle_diameter = 0.6
max_layer_height = 0.40
min_layer_height = 0.15
default_print_profile = 0.30mm QUALITY @0.6 nozzle FLSUN
retract_length = 3.5
retract_lift = 0.4
retract_speed = 30
deretract_speed = 40
retract_before_wipe = 70%
retract_before_travel = 1
[printer:FLSun Q5]
inherits = *common_flsunq*
bed_shape = 99.6195x8.71557,98.4808x17.3648,96.5926x25.8819,93.9693x34.202,90.6308x42.2618,86.6025x50,81.9152x57.3576,76.6044x64.2788,70.7107x70.7107,64.2788x76.6044,57.3576x81.9152,50x86.6025,42.2618x90.6308,34.202x93.9693,25.8819x96.5926,17.3648x98.4808,8.71557x99.6195,6.12323e-15x100,-8.71557x99.6195,-17.3648x98.4808,-25.8819x96.5926,-34.202x93.9693,-42.2618x90.6308,-50x86.6025,-57.3576x81.9152,-64.2788x76.6044,-70.7107x70.7107,-76.6044x64.2788,-81.9152x57.3576,-86.6025x50,-90.6308x42.2618,-93.9693x34.202,-96.5926x25.8819,-98.4808x17.3648,-99.6195x8.71557,-100x1.22465e-14,-99.6195x-8.71557,-98.4808x-17.3648,-96.5926x-25.8819,-93.9693x-34.202,-90.6308x-42.2618,-86.6025x-50,-81.9152x-57.3576,-76.6044x-64.2788,-70.7107x-70.7107,-64.2788x-76.6044,-57.3576x-81.9152,-50x-86.6025,-42.2618x-90.6308,-34.202x-93.9693,-25.8819x-96.5926,-17.3648x-98.4808,-8.71557x-99.6195,-1.83697e-14x-100,8.71557x-99.6195,17.3648x-98.4808,25.8819x-96.5926,34.202x-93.9693,42.2618x-90.6308,50x-86.6025,57.3576x-81.9152,64.2788x-76.6044,70.7107x-70.7107,76.6044x-64.2788,81.9152x-57.3576,86.6025x-50,90.6308x-42.2618,93.9693x-34.202,96.5926x-25.8819,98.4808x-17.3648,99.6195x-8.71557,100x-2.44929e-14
end_gcode = M107\nM104 S0\nM140 S0\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\n;M84\nM18 S180 ;disable motors after 180s\n
machine_max_acceleration_e = 3000
machine_max_acceleration_extruding = 1500
machine_max_acceleration_retracting = 2000
machine_max_acceleration_x = 1500
machine_max_acceleration_y = 1500
machine_max_acceleration_z = 1500
machine_max_feedrate_e = 60
machine_max_feedrate_x = 200
machine_max_feedrate_y = 200
machine_max_feedrate_z = 200
machine_max_jerk_e = 5
machine_max_jerk_x = 5
machine_max_jerk_y = 5
machine_max_jerk_z = 5
max_print_height = 200
nozzle_diameter = 0.4
printer_model = Q5
printer_variant = 0.4
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_FLSun\nPRINTER_MODEL_Q5\nPRINTER_HAS_BOWDEN\n
retract_length = 3
retract_lift = 0.3
start_gcode = ;STARTGCODE\nM117 Initializing\n; G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM107\nG28 ;Home\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\n\nG92 E0\nG1 X-98 Y0 Z0.2 F4000 ; move to arc start\nG3 X0 Y-98 I98 Z0.2 E40 F400 ; lay arc stripe 90deg\nG0 Z1 \nG92 E0.0\n
thumbnails = 16x16,200x200
use_relative_e_distances = 1
use_volumetric_e = 0
[printer:FLSun Q5 0.6 nozzle]
inherits = FLSun Q5
printer_variant = 0.6
nozzle_diameter = 0.6
max_layer_height = 0.40
min_layer_height = 0.15
default_print_profile = 0.30mm QUALITY @0.6 nozzle FLSUN
retract_length = 3
retract_lift = 0.4
retract_speed = 50
deretract_speed = 40
retract_before_wipe = 0
retract_before_travel = 1
#########################################
####### end common print presets ########
#########################################

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,4 +1,6 @@
min_slic3r_version = 2.3.0-rc1
1.2.2 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles.
1.2.1 Updated FW version for MK2.5 family printers.
1.2.0 Added full_fan_speed_layer value for PETG. Increased support interface spacing for 0.6mm nozzle profiles. Updated firmware version.
min_slic3r_version = 2.3.0-beta2
1.2.0-beta1 Updated end g-code. Added full_fan_speed_layer values.
@ -8,6 +10,7 @@ min_slic3r_version = 2.3.0-alpha4
1.2.0-alpha1 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
1.2.0-alpha0 Added filament spool weights
min_slic3r_version = 2.2.0-alpha3
1.1.12 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles.
1.1.11 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
1.1.10 Updated firmware version.
1.1.9 Updated K values in filament profiles (linear advance). Added new filament profiles and SLA materials.

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
min_slic3r_version = 2.3.0-alpha3
0.0.6 Added material TPU 93A (SMARTFIL)
0.0.5 Removed obsolete host keys.
0.0.4 Added PLA, PETG profiles for 0.8 nozzle, update print materials
0.0.3 Added DeltiQ 2, DeltiQ 2 Plus printers, 0.10mm, 0.20mm FLEX print profiles, updated print materials, flexprint extension support

View File

@ -6,7 +6,7 @@
name = TriLAB
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.0.5
config_version = 0.0.6
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/TriLAB/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -22,7 +22,7 @@ technology = FFF
family = DeltiQ 2
bed_model = dq2_bed.stl
bed_texture = dq2_bed_texture.svg
default_materials = DeltiQ - PLA - Generic; DeltiQ - PETG - Generic; DeltiQ - ABS - Generic; DeltiQ - PLA - ExtraFill (Fillamentum); DeltiQ - PETG (Devil Design); DeltiQ - ABS - ExtraFill (Fillamentum); DeltiQ - ASA - ExtraFill (Fillamentum); DeltiQ - CPE - HG100 (Fillamentum); DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum); DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle
default_materials = DeltiQ - PLA - Generic; DeltiQ - PETG - Generic; DeltiQ - ABS - Generic; DeltiQ - PLA - ExtraFill (Fillamentum); DeltiQ - PETG (Devil Design); DeltiQ - ABS - ExtraFill (Fillamentum); DeltiQ - ASA - ExtraFill (Fillamentum); DeltiQ - CPE - HG100 (Fillamentum); DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 93A (SMARTFIL); DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle
[printer_model:DQ2P]
name = DeltiQ 2 Plus
@ -40,7 +40,7 @@ technology = FFF
family = DeltiQ 2
bed_model = dq2_bed.stl
bed_texture = dq2_bed_texture.svg
default_materials = DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum)
default_materials = DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 93A (SMARTFIL)
[printer_model:DQ2P+FP2]
name = DeltiQ 2 Plus + FlexPrint 2
@ -49,7 +49,7 @@ technology = FFF
family = DeltiQ 2
bed_model = dq2_bed.stl
bed_texture = dq2_bed_texture.svg
default_materials = DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum)
default_materials = DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 93A (SMARTFIL)
[printer_model:DQ2+FP]
name = DeltiQ 2 + FlexPrint
@ -376,7 +376,7 @@ temperature = 215
[filament:DeltiQ - PETG - Generic]
inherits = *DeltiQ common*
bed_temperature = 90
bed_temperature = 80
bridge_fan_speed = 50
cooling = 1
fan_always_on = 1
@ -394,7 +394,7 @@ filament_retract_lift = 0.2
filament_retract_speed = 45
filament_type = PET
filament_wipe = 1
first_layer_bed_temperature = 90
first_layer_bed_temperature = 80
first_layer_temperature = 240
max_fan_speed = 50
min_fan_speed = 30
@ -695,6 +695,37 @@ filament_retract_length = 2.5
filament_retract_speed = 20
filament_type = TPU98A
[filament:DeltiQ FP2 - TPU 93A (SMARTFIL)]
inherits = DeltiQ FP2 - FLEX - Generic
bed_temperature = 50
bridge_fan_speed = 80
cooling = 1
disable_fan_first_layers = 3
extrusion_multiplier = 1.00
fan_always_on = 1
fan_below_layer_time = 10
filament_vendor = Smartfil
filament_cost = 1209
filament_density = 1.21
filament_deretract_speed = nil
filament_max_volumetric_speed = 2.5
filament_retract_before_travel = 2
filament_retract_before_wipe = nil
filament_retract_layer_change = 0
filament_retract_length = 2.9
filament_retract_lift = 0.2
filament_retract_restart_extra = nil
filament_retract_speed = 35
filament_type = TPU93A
filament_wipe = 0
first_layer_bed_temperature = 50
first_layer_temperature = 235
max_fan_speed = 70
min_fan_speed = 30
min_print_speed = 10
slowdown_below_layer_time = 4
temperature = 235
# DeltiQ Printer #

View File

@ -28,6 +28,7 @@
#include <boost/nowide/cenv.hpp>
#include <boost/nowide/iostream.hpp>
#include <boost/nowide/integration/filesystem.hpp>
#include <boost/dll/runtime_symbol_info.hpp>
#include "unix/fhs.hpp" // Generated by CMake from ../platform/unix/fhs.hpp.in
@ -150,15 +151,11 @@ int CLI::run(int argc, char **argv)
}
// Read input file(s) if any.
for (const std::string& file : m_input_files) {
std::string ext = boost::filesystem::path(file).extension().string();
if (ext == ".gcode" || ext == ".g") {
if (boost::filesystem::exists(file)) {
for (const std::string& file : m_input_files)
if (is_gcode_file(file) && boost::filesystem::exists(file)) {
start_as_gcodeviewer = true;
break;
}
}
}
if (!start_as_gcodeviewer) {
for (const std::string& file : m_input_files) {
if (!boost::filesystem::exists(file)) {
@ -598,7 +595,9 @@ bool CLI::setup(int argc, char **argv)
}
}
boost::filesystem::path path_to_binary = boost::filesystem::system_complete(argv[0]);
// See Invoking prusa-slicer from $PATH environment variable crashes #5542
// boost::filesystem::path path_to_binary = boost::filesystem::system_complete(argv[0]);
boost::filesystem::path path_to_binary = boost::dll::program_location();
// Path from the Slic3r binary to its resources.
#ifdef __APPLE__

View File

@ -716,45 +716,33 @@ static void traverse_pt_noholes(const ClipperLib::PolyNodes &nodes, Polygons *ou
});
}
static void traverse_pt_old(ClipperLib::PolyNodes &nodes, Polygons* retval)
static void traverse_pt_outside_in(const ClipperLib::PolyNodes &nodes, Polygons *retval)
{
/* use a nearest neighbor search to order these children
TODO: supply start_near to chained_path() too? */
// collect ordering points
Points ordering_points;
ordering_points.reserve(nodes.size());
for (ClipperLib::PolyNodes::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
Point p((*it)->Contour.front().X, (*it)->Contour.front().Y);
ordering_points.push_back(p);
}
for (const ClipperLib::PolyNode *node : nodes)
ordering_points.emplace_back(node->Contour.front().X, node->Contour.front().Y);
// perform the ordering
ClipperLib::PolyNodes ordered_nodes = chain_clipper_polynodes(ordering_points, nodes);
// push results recursively
for (ClipperLib::PolyNodes::iterator it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it) {
// Perform the ordering, push results recursively.
//FIXME pass the last point to chain_clipper_polynodes?
for (const ClipperLib::PolyNode *node : chain_clipper_polynodes(ordering_points, nodes)) {
retval->emplace_back(ClipperPath_to_Slic3rPolygon(node->Contour));
if (node->IsHole())
// Orient a hole, which is clockwise oriented, to CCW.
retval->back().reverse();
// traverse the next depth
traverse_pt_old((*it)->Childs, retval);
retval->push_back(ClipperPath_to_Slic3rPolygon((*it)->Contour));
if ((*it)->IsHole()) retval->back().reverse(); // ccw
traverse_pt_outside_in(node->Childs, retval);
}
}
Polygons union_pt_chained(const Polygons &subject, bool safety_offset_)
Polygons union_pt_chained_outside_in(const Polygons &subject, bool safety_offset_)
{
ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
Polygons retval;
traverse_pt_old(polytree.Childs, &retval);
traverse_pt_outside_in(polytree.Childs, &retval);
return retval;
// TODO: This needs to be tested:
// ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
// Polygons retval;
// traverse_pt_noholes(polytree.Childs, &retval);
// return retval;
}
Polygons simplify_polygons(const Polygons &subject, bool preserve_collinear)

View File

@ -219,7 +219,7 @@ ClipperLib::PolyTree union_pt(const Slic3r::ExPolygons &subject, bool safety_off
ClipperLib::PolyTree union_pt(Slic3r::Polygons &&subject, bool safety_offset_ = false);
ClipperLib::PolyTree union_pt(Slic3r::ExPolygons &&subject, bool safety_offset_ = false);
Slic3r::Polygons union_pt_chained(const Slic3r::Polygons &subject, bool safety_offset_ = false);
Slic3r::Polygons union_pt_chained_outside_in(const Slic3r::Polygons &subject, bool safety_offset_ = false);
ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes);

View File

@ -589,7 +589,7 @@ void ConfigBase::setenv_() const
void ConfigBase::load(const std::string &file)
{
if (boost::iends_with(file, ".gcode") || boost::iends_with(file, ".g"))
if (is_gcode_file(file))
this->load_from_gcode_file(file);
else
this->load_from_ini(file);

View File

@ -66,7 +66,11 @@ protected:
const std::pair<float, Point> &direction,
ExPolygon expolygon,
Polylines &polylines_out) override;
bool no_sort() const override { return true; }
// Let the G-code export reoder the infill lines.
//FIXME letting the G-code exporter to reorder infill lines of Adaptive Cubic Infill
// may not be optimal as the internal infill lines may get extruded before the long infill
// lines to which the short infill lines are supposed to anchor.
bool no_sort() const override { return false; }
};
}; // namespace FillAdaptive

View File

@ -96,10 +96,10 @@ coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
assert(width >= 0);
assert(distance > 0);
// floor(width / distance)
coord_t number_of_intervals = (width - EPSILON) / distance;
const auto number_of_intervals = coord_t((width - EPSILON) / distance);
coord_t distance_new = (number_of_intervals == 0) ?
distance :
((width - EPSILON) / number_of_intervals);
coord_t((width - EPSILON) / number_of_intervals);
const coordf_t factor = coordf_t(distance_new) / coordf_t(distance);
assert(factor > 1. - 1e-5);
// How much could the extrusion width be increased? By 20%.
@ -143,7 +143,7 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
#ifdef SLIC3R_DEBUG
printf("Filling bridge with angle %f\n", surface->bridge_angle);
#endif /* SLIC3R_DEBUG */
out_angle = surface->bridge_angle;
out_angle = float(surface->bridge_angle);
} else if (this->layer_id != size_t(-1)) {
// alternate fill direction
out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers);
@ -161,15 +161,15 @@ struct ContourIntersectionPoint {
size_t contour_idx;
size_t point_idx;
// Eucleidean parameter of point_idx along its contour.
float param;
double param;
// Other intersection points along the same contour. If there is only a single T-joint on a contour
// with an intersection line, then the prev_on_contour and next_on_contour remain nulls.
ContourIntersectionPoint* prev_on_contour { nullptr };
ContourIntersectionPoint* next_on_contour { nullptr };
// Length of the contour not yet allocated to some extrusion path going back (clockwise), or masked out by some overlapping infill line.
float contour_not_taken_length_prev { std::numeric_limits<float>::max() };
double contour_not_taken_length_prev { std::numeric_limits<double>::max() };
// Length of the contour not yet allocated to some extrusion path going forward (counter-clockwise), or masked out by some overlapping infill line.
float contour_not_taken_length_next { std::numeric_limits<float>::max() };
double contour_not_taken_length_next { std::numeric_limits<double>::max() };
// End point is consumed if an infill line connected to this T-joint was already connected left or right along the contour,
// or if the infill line was processed, but it was not possible to connect it left or right along the contour.
bool consumed { false };
@ -180,13 +180,13 @@ struct ContourIntersectionPoint {
void consume_prev() { this->contour_not_taken_length_prev = 0.; this->prev_trimmed = true; this->consumed = true; }
void consume_next() { this->contour_not_taken_length_next = 0.; this->next_trimmed = true; this->consumed = true; }
void trim_prev(const float new_len) {
void trim_prev(const double new_len) {
if (new_len < this->contour_not_taken_length_prev) {
this->contour_not_taken_length_prev = new_len;
this->prev_trimmed = true;
}
}
void trim_next(const float new_len) {
void trim_next(const double new_len) {
if (new_len < this->contour_not_taken_length_next) {
this->contour_not_taken_length_next = new_len;
this->next_trimmed = true;
@ -207,24 +207,24 @@ struct ContourIntersectionPoint {
};
// Distance from param1 to param2 when going counter-clockwise.
static inline float closed_contour_distance_ccw(float param1, float param2, float contour_length)
static inline double closed_contour_distance_ccw(double param1, double param2, double contour_length)
{
assert(param1 >= 0.f && param1 <= contour_length);
assert(param2 >= 0.f && param2 <= contour_length);
float d = param2 - param1;
if (d < 0.f)
assert(param1 >= 0. && param1 <= contour_length);
assert(param2 >= 0. && param2 <= contour_length);
double d = param2 - param1;
if (d < 0.)
d += contour_length;
return d;
}
// Distance from param1 to param2 when going clockwise.
static inline float closed_contour_distance_cw(float param1, float param2, float contour_length)
static inline double closed_contour_distance_cw(double param1, double param2, double contour_length)
{
return closed_contour_distance_ccw(param2, param1, contour_length);
}
// Length along the contour from cp1 to cp2 going counter-clockwise.
float path_length_along_contour_ccw(const ContourIntersectionPoint *cp1, const ContourIntersectionPoint *cp2, float contour_length)
double path_length_along_contour_ccw(const ContourIntersectionPoint *cp1, const ContourIntersectionPoint *cp2, double contour_length)
{
assert(cp1 != nullptr);
assert(cp2 != nullptr);
@ -234,13 +234,13 @@ float path_length_along_contour_ccw(const ContourIntersectionPoint *cp1, const C
}
// Lengths along the contour from cp1 to cp2 going CCW and going CW.
std::pair<float, float> path_lengths_along_contour(const ContourIntersectionPoint *cp1, const ContourIntersectionPoint *cp2, float contour_length)
std::pair<double, double> path_lengths_along_contour(const ContourIntersectionPoint *cp1, const ContourIntersectionPoint *cp2, double contour_length)
{
// Zero'th param is the length of the contour.
float param_lo = cp1->param;
float param_hi = cp2->param;
assert(param_lo >= 0.f && param_lo <= contour_length);
assert(param_hi >= 0.f && param_hi <= contour_length);
double param_lo = cp1->param;
double param_hi = cp2->param;
assert(param_lo >= 0. && param_lo <= contour_length);
assert(param_hi >= 0. && param_hi <= contour_length);
bool reversed = false;
if (param_lo > param_hi) {
std::swap(param_lo, param_hi);
@ -267,25 +267,25 @@ static inline void take_cw_full(Polyline &pl, const Points& contour, size_t idx_
}
// Add contour points from interval (idx_start, idx_end> to polyline, limited by the Eucleidean length taken.
static inline float take_cw_limited(Polyline &pl, const Points &contour, const std::vector<float> &params, size_t idx_start, size_t idx_end, float length_to_take)
static inline double take_cw_limited(Polyline &pl, const Points &contour, const std::vector<double> &params, size_t idx_start, size_t idx_end, double length_to_take)
{
// If appending to an infill line, then the start point of a perimeter line shall match the end point of an infill line.
assert(pl.empty() || pl.points.back() == contour[idx_start]);
assert(contour.size() + 1 == params.size());
assert(length_to_take > SCALED_EPSILON);
// Length of the contour.
float length = params.back();
double length = params.back();
// Parameter (length from contour.front()) for the first point.
float p0 = params[idx_start];
double p0 = params[idx_start];
// Current (2nd) point of the contour.
size_t i = (idx_start == 0) ? contour.size() - 1 : idx_start - 1;
// Previous point of the contour.
size_t iprev = idx_start;
// Length of the contour curve taken for iprev.
float lprev = 0.f;
double lprev = 0.;
for (;;) {
float l = closed_contour_distance_cw(p0, params[i], length);
double l = closed_contour_distance_cw(p0, params[i], length);
if (l >= length_to_take) {
// Trim the last segment.
double t = double(length_to_take - lprev) / (l - lprev);
@ -323,16 +323,16 @@ static inline void take_ccw_full(Polyline &pl, const Points &contour, size_t idx
// Add contour points from interval (idx_start, idx_end> to polyline, limited by the Eucleidean length taken.
// Returns length of the contour taken.
static inline float take_ccw_limited(Polyline &pl, const Points &contour, const std::vector<float> &params, size_t idx_start, size_t idx_end, float length_to_take)
static inline double take_ccw_limited(Polyline &pl, const Points &contour, const std::vector<double> &params, size_t idx_start, size_t idx_end, double length_to_take)
{
// If appending to an infill line, then the start point of a perimeter line shall match the end point of an infill line.
assert(pl.empty() || pl.points.back() == contour[idx_start]);
assert(contour.size() + 1 == params.size());
assert(length_to_take > SCALED_EPSILON);
// Length of the contour.
float length = params.back();
double length = params.back();
// Parameter (length from contour.front()) for the first point.
float p0 = params[idx_start];
double p0 = params[idx_start];
// Current (2nd) point of the contour.
size_t i = idx_start;
if (++ i == contour.size())
@ -340,9 +340,9 @@ static inline float take_ccw_limited(Polyline &pl, const Points &contour, const
// Previous point of the contour.
size_t iprev = idx_start;
// Length of the contour curve taken at iprev.
float lprev = 0.f;
double lprev = 0;
for (;;) {
float l = closed_contour_distance_ccw(p0, params[i], length);
double l = closed_contour_distance_ccw(p0, params[i], length);
if (l >= length_to_take) {
// Trim the last segment.
double t = double(length_to_take - lprev) / (l - lprev);
@ -411,8 +411,8 @@ static void take(Polyline &pl1, const Polyline &pl2, const Points &contour, Cont
}
static void take_limited(
Polyline &pl1, const Points &contour, const std::vector<float> &params,
ContourIntersectionPoint *cp_start, ContourIntersectionPoint *cp_end, bool clockwise, float take_max_length, float line_half_width)
Polyline &pl1, const Points &contour, const std::vector<double> &params,
ContourIntersectionPoint *cp_start, ContourIntersectionPoint *cp_end, bool clockwise, double take_max_length, double line_half_width)
{
#ifndef NDEBUG
// This is a valid case, where a single infill line connect to two different contours (outer contour + hole or two holes).
@ -445,11 +445,11 @@ static void take_limited(
pl1.points.reserve(pl1.points.size() + pl_tmp.size() + size_t(new_points));
}
float length = params.back();
float length_to_go = take_max_length;
double length = params.back();
double length_to_go = take_max_length;
cp_start->consumed = true;
if (cp_start == cp_end) {
length_to_go = std::max(0.f, std::min(length_to_go, length - line_half_width));
length_to_go = std::max(0., std::min(length_to_go, length - line_half_width));
length_to_go = std::min(length_to_go, clockwise ? cp_start->contour_not_taken_length_prev : cp_start->contour_not_taken_length_next);
cp_start->consume_prev();
cp_start->consume_next();
@ -462,11 +462,11 @@ static void take_limited(
assert(cp_start != cp_end);
for (ContourIntersectionPoint *cp = cp_start; cp != cp_end; cp = cp->prev_on_contour) {
// Length of the segment from cp to cp->prev_on_contour.
float l = closed_contour_distance_cw(cp->param, cp->prev_on_contour->param, length);
double l = closed_contour_distance_cw(cp->param, cp->prev_on_contour->param, length);
length_to_go = std::min(length_to_go, cp->contour_not_taken_length_prev);
//if (cp->prev_on_contour->consumed)
// Don't overlap with an already extruded infill line.
length_to_go = std::max(0.f, std::min(length_to_go, l - line_half_width));
length_to_go = std::max(0., std::min(length_to_go, l - line_half_width));
cp->consume_prev();
if (l >= length_to_go) {
if (length_to_go > SCALED_EPSILON) {
@ -475,7 +475,7 @@ static void take_limited(
}
break;
} else {
cp->prev_on_contour->trim_next(0.f);
cp->prev_on_contour->trim_next(0.);
take_cw_full(pl1, contour, cp->point_idx, cp->prev_on_contour->point_idx);
length_to_go -= l;
}
@ -483,11 +483,11 @@ static void take_limited(
} else {
assert(cp_start != cp_end);
for (ContourIntersectionPoint *cp = cp_start; cp != cp_end; cp = cp->next_on_contour) {
float l = closed_contour_distance_ccw(cp->param, cp->next_on_contour->param, length);
double l = closed_contour_distance_ccw(cp->param, cp->next_on_contour->param, length);
length_to_go = std::min(length_to_go, cp->contour_not_taken_length_next);
//if (cp->next_on_contour->consumed)
// Don't overlap with an already extruded infill line.
length_to_go = std::max(0.f, std::min(length_to_go, l - line_half_width));
length_to_go = std::max(0., std::min(length_to_go, l - line_half_width));
cp->consume_next();
if (l >= length_to_go) {
if (length_to_go > SCALED_EPSILON) {
@ -496,7 +496,7 @@ static void take_limited(
}
break;
} else {
cp->next_on_contour->trim_prev(0.f);
cp->next_on_contour->trim_prev(0.);
take_ccw_full(pl1, contour, cp->point_idx, cp->next_on_contour->point_idx);
length_to_go -= l;
}
@ -678,19 +678,19 @@ static inline bool line_rounded_thick_segment_collision(
return intersects;
}
static inline bool inside_interval(float low, float high, float p)
static inline bool inside_interval(double low, double high, double p)
{
return p >= low && p <= high;
}
static inline bool interval_inside_interval(float outer_low, float outer_high, float inner_low, float inner_high, float epsilon)
static inline bool interval_inside_interval(double outer_low, double outer_high, double inner_low, double inner_high, double epsilon)
{
outer_low -= epsilon;
outer_high += epsilon;
return inside_interval(outer_low, outer_high, inner_low) && inside_interval(outer_low, outer_high, inner_high);
}
static inline bool cyclic_interval_inside_interval(float outer_low, float outer_high, float inner_low, float inner_high, float length)
static inline bool cyclic_interval_inside_interval(double outer_low, double outer_high, double inner_low, double inner_high, double length)
{
if (outer_low > outer_high)
outer_high += length;
@ -700,7 +700,7 @@ static inline bool cyclic_interval_inside_interval(float outer_low, float outer_
inner_low += length;
inner_high += length;
}
return interval_inside_interval(outer_low, outer_high, inner_low, inner_high, float(SCALED_EPSILON));
return interval_inside_interval(outer_low, outer_high, inner_low, inner_high, double(SCALED_EPSILON));
}
// #define INFILL_DEBUG_OUTPUT
@ -710,7 +710,7 @@ static void export_infill_to_svg(
// Boundary contour, along which the perimeter extrusions will be drawn.
const std::vector<Points> &boundary,
// Parametrization of boundary with Euclidian length.
const std::vector<std::vector<float>> &boundary_parameters,
const std::vector<std::vector<double>> &boundary_parameters,
// Intersections (T-joints) of the infill lines with the boundary.
std::vector<std::vector<ContourIntersectionPoint*>> &boundary_intersections,
// Infill lines, either completely inside the boundary, or touching the boundary.
@ -739,7 +739,7 @@ static void export_infill_to_svg(
for (const std::vector<ContourIntersectionPoint*> &intersections : boundary_intersections) {
const size_t boundary_idx = &intersections - boundary_intersections.data();
const Points &contour = boundary[boundary_idx];
const std::vector<float> &contour_param = boundary_parameters[boundary_idx];
const std::vector<double> &contour_param = boundary_parameters[boundary_idx];
for (const ContourIntersectionPoint *ip : intersections) {
assert(ip->next_trimmed == ip->next_on_contour->prev_trimmed);
assert(ip->prev_trimmed == ip->prev_on_contour->next_trimmed);
@ -834,7 +834,7 @@ void mark_boundary_segments_touching_infill(
// Boundary contour, along which the perimeter extrusions will be drawn.
const std::vector<Points> &boundary,
// Parametrization of boundary with Euclidian length.
const std::vector<std::vector<float>> &boundary_parameters,
const std::vector<std::vector<double>> &boundary_parameters,
// Intersections (T-joints) of the infill lines with the boundary.
std::vector<std::vector<ContourIntersectionPoint*>> &boundary_intersections,
// Bounding box around the boundary.
@ -865,12 +865,12 @@ void mark_boundary_segments_touching_infill(
// Make sure that the the grid is big enough for queries against the thick segment.
grid.set_bbox(boundary_bbox.inflated(distance_colliding * 1.43));
// Inflate the bounding box by a thick line width.
grid.create(boundary, std::max(clip_distance, distance_colliding) + scale_(10.));
grid.create(boundary, coord_t(std::max(clip_distance, distance_colliding) + scale_(10.)));
// Visitor for the EdgeGrid to trim boundary_intersections with existing infill lines.
struct Visitor {
Visitor(const EdgeGrid::Grid &grid,
const std::vector<Points> &boundary, const std::vector<std::vector<float>> &boundary_parameters, std::vector<std::vector<ContourIntersectionPoint*>> &boundary_intersections,
const std::vector<Points> &boundary, const std::vector<std::vector<double>> &boundary_parameters, std::vector<std::vector<ContourIntersectionPoint*>> &boundary_intersections,
const double radius) :
grid(grid), boundary(boundary), boundary_parameters(boundary_parameters), boundary_intersections(boundary_intersections), radius(radius), trim_l_threshold(0.5 * radius) {}
@ -907,10 +907,10 @@ void mark_boundary_segments_touching_infill(
// The boundary segment intersects with the infill segment thickened by radius.
// Interval is specified in Euclidian length from seg_pt1 to seg_pt2.
// 1) Find the Euclidian parameters of seg_pt1 and seg_pt2 on its boundary contour.
const std::vector<float> &contour_parameters = boundary_parameters[it_contour_and_segment->first];
const float contour_length = contour_parameters.back();
const float param_seg_pt1 = contour_parameters[it_contour_and_segment->second];
const float param_seg_pt2 = contour_parameters[it_contour_and_segment->second + 1];
const std::vector<double> &contour_parameters = boundary_parameters[it_contour_and_segment->first];
const double contour_length = contour_parameters.back();
const double param_seg_pt1 = contour_parameters[it_contour_and_segment->second];
const double param_seg_pt2 = contour_parameters[it_contour_and_segment->second + 1];
#ifdef INFILL_DEBUG_OUTPUT
this->perimeter_overlaps.push_back({ Point((seg_pt1 + (seg_pt2 - seg_pt1).normalized() * interval.first).cast<coord_t>()),
Point((seg_pt1 + (seg_pt2 - seg_pt1).normalized() * interval.second).cast<coord_t>()) });
@ -918,8 +918,8 @@ void mark_boundary_segments_touching_infill(
assert(interval.first >= 0.);
assert(interval.second >= 0.);
assert(interval.first <= interval.second);
const auto param_overlap1 = std::min(param_seg_pt2, float(param_seg_pt1 + interval.first));
const auto param_overlap2 = std::min(param_seg_pt2, float(param_seg_pt1 + interval.second));
const auto param_overlap1 = std::min(param_seg_pt2, param_seg_pt1 + interval.first);
const auto param_overlap2 = std::min(param_seg_pt2, param_seg_pt1 + interval.second);
// 2) Find the ContourIntersectionPoints before param_overlap1 and after param_overlap2.
// Find the span of ContourIntersectionPoints, that is trimmed by the interval (param_overlap1, param_overlap2).
ContourIntersectionPoint *ip_low, *ip_high;
@ -946,7 +946,7 @@ void mark_boundary_segments_touching_infill(
ip->consume_next();
}
// Subtract the interval from the first and last segments.
float trim_l = closed_contour_distance_ccw(ip_low->param, param_overlap1, contour_length);
double trim_l = closed_contour_distance_ccw(ip_low->param, param_overlap1, contour_length);
//if (trim_l > trim_l_threshold)
ip_low->trim_next(trim_l);
trim_l = closed_contour_distance_ccw(param_overlap2, ip_high->param, contour_length);
@ -978,12 +978,12 @@ void mark_boundary_segments_touching_infill(
const EdgeGrid::Grid &grid;
const std::vector<Points> &boundary;
const std::vector<std::vector<float>> &boundary_parameters;
const std::vector<std::vector<double>> &boundary_parameters;
std::vector<std::vector<ContourIntersectionPoint*>> &boundary_intersections;
// Maximum distance between the boundary and the infill line allowed to consider the boundary not touching the infill line.
const double radius;
// Region around the contour / infill line intersection point, where the intersections are ignored.
const float trim_l_threshold;
const double trim_l_threshold;
const Vec2d *infill_pt1;
const Vec2d *infill_pt2;
@ -1100,11 +1100,11 @@ void Fill::connect_infill(Polylines &&infill_ordered, const Polygons &boundary_s
void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams &params)
{
assert(! infill_ordered.empty());
assert(params.anchor_length >= 0.f);
assert(params.anchor_length >= 0.);
assert(params.anchor_length_max >= 0.01f);
assert(params.anchor_length_max >= params.anchor_length);
const auto anchor_length = float(scale_(params.anchor_length));
const auto anchor_length_max = float(scale_(params.anchor_length_max));
const double anchor_length = scale_(params.anchor_length);
const double anchor_length_max = scale_(params.anchor_length_max);
#if 0
append(polylines_out, infill_ordered);
@ -1113,9 +1113,9 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
// 1) Add the end points of infill_ordered to boundary_src.
std::vector<Points> boundary;
std::vector<std::vector<float>> boundary_params;
std::vector<std::vector<double>> boundary_params;
boundary.assign(boundary_src.size(), Points());
boundary_params.assign(boundary_src.size(), std::vector<float>());
boundary_params.assign(boundary_src.size(), std::vector<double>());
// Mapping the infill_ordered end point to a (contour, point) of boundary.
static constexpr auto boundary_idx_unconnected = std::numeric_limits<size_t>::max();
std::vector<ContourIntersectionPoint> map_infill_end_point_to_boundary(infill_ordered.size() * 2, ContourIntersectionPoint{ boundary_idx_unconnected, boundary_idx_unconnected });
@ -1125,11 +1125,11 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
{
EdgeGrid::Grid grid;
grid.set_bbox(bbox.inflated(SCALED_EPSILON));
grid.create(boundary_src, scale_(10.));
grid.create(boundary_src, coord_t(scale_(10.)));
intersection_points.reserve(infill_ordered.size() * 2);
for (const Polyline &pl : infill_ordered)
for (const Point *pt : { &pl.points.front(), &pl.points.back() }) {
EdgeGrid::Grid::ClosestPointResult cp = grid.closest_point(*pt, SCALED_EPSILON);
EdgeGrid::Grid::ClosestPointResult cp = grid.closest_point(*pt, coord_t(SCALED_EPSILON));
if (cp.valid()) {
// The infill end point shall lie on the contour.
assert(cp.distance <= 3.);
@ -1163,21 +1163,29 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
contour_intersection_points.reserve(n_intersection_points);
}
for (size_t idx_point = 0; idx_point < contour_src.points.size(); ++ idx_point) {
contour_dst.emplace_back(contour_src.points[idx_point]);
const Point &ipt = contour_src.points[idx_point];
if (contour_dst.empty() || contour_dst.back() != ipt)
contour_dst.emplace_back(ipt);
for (; it != it_end && it->first.contour_idx == idx_contour && it->first.start_point_idx == idx_point; ++ it) {
// Add these points to the destination contour.
const Polyline &infill_line = infill_ordered[it->second / 2];
const Point &pt = (it->second & 1) ? infill_line.points.back() : infill_line.points.front();
#ifndef NDEBUG
{
const Vec2d pt1 = contour_src[idx_point].cast<double>();
const Vec2d pt1 = ipt.cast<double>();
const Vec2d pt2 = (idx_point + 1 == contour_src.size() ? contour_src.points.front() : contour_src.points[idx_point + 1]).cast<double>();
const Vec2d ptx = lerp(pt1, pt2, it->first.t);
assert(std::abs(pt.x() - pt.x()) < SCALED_EPSILON);
assert(std::abs(pt.y() - pt.y()) < SCALED_EPSILON);
}
#endif // NDEBUG
map_infill_end_point_to_boundary[it->second] = ContourIntersectionPoint{ idx_contour, contour_dst.size() };
size_t idx_tjoint_pt = 0;
if (idx_point + 1 < contour_src.size() || pt != contour_dst.front()) {
if (pt != contour_dst.back())
contour_dst.emplace_back(pt);
idx_tjoint_pt = contour_dst.size() - 1;
}
map_infill_end_point_to_boundary[it->second] = ContourIntersectionPoint{ idx_contour, idx_tjoint_pt };
ContourIntersectionPoint *pthis = &map_infill_end_point_to_boundary[it->second];
if (pprev) {
pprev->next_on_contour = pthis;
@ -1186,8 +1194,6 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
pfirst = pthis;
contour_intersection_points.emplace_back(pthis);
pprev = pthis;
//add new point here
contour_dst.emplace_back(pt);
}
if (pfirst) {
pprev->next_on_contour = pfirst;
@ -1195,16 +1201,19 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
}
}
// Parametrize the new boundary with the intersection points inserted.
std::vector<float> &contour_params = boundary_params[idx_contour];
contour_params.assign(contour_dst.size() + 1, 0.f);
for (size_t i = 1; i < contour_dst.size(); ++ i)
contour_params[i] = contour_params[i - 1] + (contour_dst[i].cast<float>() - contour_dst[i - 1].cast<float>()).norm();
contour_params.back() = contour_params[contour_params.size() - 2] + (contour_dst.back().cast<float>() - contour_dst.front().cast<float>()).norm();
std::vector<double> &contour_params = boundary_params[idx_contour];
contour_params.assign(contour_dst.size() + 1, 0.);
for (size_t i = 1; i < contour_dst.size(); ++i) {
contour_params[i] = contour_params[i - 1] + (contour_dst[i].cast<double>() - contour_dst[i - 1].cast<double>()).norm();
assert(contour_params[i] > contour_params[i - 1]);
}
contour_params.back() = contour_params[contour_params.size() - 2] + (contour_dst.back().cast<double>() - contour_dst.front().cast<double>()).norm();
assert(contour_params.back() > contour_params[contour_params.size() - 2]);
// Map parameters from contour_params to boundary_intersection_points.
for (ContourIntersectionPoint *ip : contour_intersection_points)
ip->param = contour_params[ip->point_idx];
// and measure distance to the previous and next intersection point.
const float contour_length = contour_params.back();
const double contour_length = contour_params.back();
for (ContourIntersectionPoint *ip : contour_intersection_points)
if (ip->next_on_contour == ip) {
assert(ip->prev_on_contour == ip);
@ -1238,9 +1247,9 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
}
// Connection from end of one infill line to the start of another infill line.
//const float length_max = scale_(spacing);
// const auto length_max = float(scale_((2. / params.density) * spacing));
const auto length_max = float(scale_((1000. / params.density) * spacing));
//const double length_max = scale_(spacing);
// const auto length_max = double(scale_((2. / params.density) * spacing));
const auto length_max = double(scale_((1000. / params.density) * spacing));
std::vector<size_t> merged_with(infill_ordered.size());
std::iota(merged_with.begin(), merged_with.end(), 0);
struct ConnectionCost {
@ -1258,7 +1267,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
const ContourIntersectionPoint *cp2 = &map_infill_end_point_to_boundary[idx_chain * 2];
if (cp1->contour_idx != boundary_idx_unconnected && cp1->contour_idx == cp2->contour_idx) {
// End points on the same contour. Try to connect them.
std::pair<float, float> len = path_lengths_along_contour(cp1, cp2, boundary_params[cp1->contour_idx].back());
std::pair<double, double> len = path_lengths_along_contour(cp1, cp2, boundary_params[cp1->contour_idx].back());
if (len.first < length_max)
connections_sorted.emplace_back(idx_chain - 1, len.first, false);
if (len.second < length_max)
@ -1281,7 +1290,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
return std::numeric_limits<size_t>::max();
};
const float line_half_width = 0.5f * scale_(spacing);
const double line_half_width = 0.5 * scale_(spacing);
#if 0
for (ConnectionCost &connection_cost : connections_sorted) {
@ -1291,7 +1300,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
assert(cp1->contour_idx == cp2->contour_idx && cp1->contour_idx != boundary_idx_unconnected);
if (cp1->consumed || cp2->consumed)
continue;
const float length = connection_cost.cost;
const double length = connection_cost.cost;
bool could_connect;
{
// cp1, cp2 sorted CCW.
@ -1334,7 +1343,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
struct Arc {
ContourIntersectionPoint *intersection;
float arc_length;
double arc_length;
};
std::vector<Arc> arches;
arches.reserve(map_infill_end_point_to_boundary.size());
@ -1352,7 +1361,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
size_t polyline_idx1 = get_and_update_merged_with(((cp1 - map_infill_end_point_to_boundary.data()) / 2));
size_t polyline_idx2 = get_and_update_merged_with(((cp2 - map_infill_end_point_to_boundary.data()) / 2));
const Points &contour = boundary[cp1->contour_idx];
const std::vector<float> &contour_params = boundary_params[cp1->contour_idx];
const std::vector<double> &contour_params = boundary_params[cp1->contour_idx];
if (polyline_idx1 != polyline_idx2) {
Polyline &polyline1 = infill_ordered[polyline_idx1];
Polyline &polyline2 = infill_ordered[polyline_idx2];
@ -1386,22 +1395,22 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
for (ContourIntersectionPoint &contour_point : map_infill_end_point_to_boundary)
if (! contour_point.consumed && contour_point.contour_idx != boundary_idx_unconnected) {
const Points &contour = boundary[contour_point.contour_idx];
const std::vector<float> &contour_params = boundary_params[contour_point.contour_idx];
const std::vector<double> &contour_params = boundary_params[contour_point.contour_idx];
const size_t contour_pt_idx = contour_point.point_idx;
float lprev = contour_point.could_connect_prev() ?
double lprev = contour_point.could_connect_prev() ?
path_length_along_contour_ccw(contour_point.prev_on_contour, &contour_point, contour_params.back()) :
std::numeric_limits<float>::max();
float lnext = contour_point.could_connect_next() ?
std::numeric_limits<double>::max();
double lnext = contour_point.could_connect_next() ?
path_length_along_contour_ccw(&contour_point, contour_point.next_on_contour, contour_params.back()) :
std::numeric_limits<float>::max();
std::numeric_limits<double>::max();
size_t polyline_idx = get_and_update_merged_with(((&contour_point - map_infill_end_point_to_boundary.data()) / 2));
Polyline &polyline = infill_ordered[polyline_idx];
assert(! polyline.empty());
assert(contour[contour_point.point_idx] == polyline.points.front() || contour[contour_point.point_idx] == polyline.points.back());
bool connected = false;
for (float l : { std::min(lprev, lnext), std::max(lprev, lnext) }) {
if (l == std::numeric_limits<float>::max() || l > anchor_length_max)
for (double l : { std::min(lprev, lnext), std::max(lprev, lnext) }) {
if (l == std::numeric_limits<double>::max() || l > anchor_length_max)
break;
// Take the complete contour.
bool reversed = l == lprev;
@ -1439,7 +1448,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
// 2) Hook length
// ...
// Let's take the longer now, as this improves the chance of another hook to be placed on the other side of this contour point.
float l = std::max(contour_point.contour_not_taken_length_prev, contour_point.contour_not_taken_length_next);
double l = std::max(contour_point.contour_not_taken_length_prev, contour_point.contour_not_taken_length_next);
if (l > SCALED_EPSILON) {
if (contour_point.contour_not_taken_length_prev > contour_point.contour_not_taken_length_next)
take_limited(polyline, contour, contour_params, &contour_point, contour_point.prev_on_contour, true, anchor_length, line_half_width);

View File

@ -24,22 +24,22 @@ void FillConcentric::_fill_surface_single(
this->spacing = unscale<double>(distance);
}
Polygons loops = (Polygons)expolygon;
Polygons loops = to_polygons(std::move(expolygon));
Polygons last = loops;
while (! last.empty()) {
last = offset2(last, -(distance + min_spacing/2), +min_spacing/2);
loops.insert(loops.end(), last.begin(), last.end());
append(loops, last);
}
// generate paths from the outermost to the innermost, to avoid
// adhesion problems of the first central tiny loops
loops = union_pt_chained(loops, false);
loops = union_pt_chained_outside_in(loops, false);
// split paths using a nearest neighbor search
size_t iPathFirst = polylines_out.size();
Point last_pos(0, 0);
for (const Polygon &loop : loops) {
polylines_out.push_back(loop.split_at_index(last_pos.nearest_point_index(loop.points)));
polylines_out.emplace_back(loop.split_at_index(last_pos.nearest_point_index(loop.points)));
last_pos = polylines_out.back().last_point();
}

View File

@ -8,7 +8,7 @@ namespace Slic3r {
class FillConcentric : public Fill
{
public:
~FillConcentric() override {}
~FillConcentric() override = default;
protected:
Fill* clone() const override { return new FillConcentric(*this); };

View File

@ -37,7 +37,7 @@ protected:
bool _can_connect(coord_t dist_X, coord_t dist_Y)
{
coord_t TOLERANCE = 10 * SCALED_EPSILON;
const auto TOLERANCE = coord_t(10 * SCALED_EPSILON);
return (dist_X >= (this->_line_spacing - this->_line_oscillation) - TOLERANCE)
&& (dist_X <= (this->_line_spacing + this->_line_oscillation) + TOLERANCE)
&& (dist_Y <= this->_diagonal_distance);

View File

@ -56,59 +56,59 @@ const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_poin
const std::string SLA_DRAIN_HOLES_FILE = "Metadata/Slic3r_PE_sla_drain_holes.txt";
const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml";
static constexpr char* MODEL_TAG = "model";
static constexpr char* RESOURCES_TAG = "resources";
static constexpr char* OBJECT_TAG = "object";
static constexpr char* MESH_TAG = "mesh";
static constexpr char* VERTICES_TAG = "vertices";
static constexpr char* VERTEX_TAG = "vertex";
static constexpr char* TRIANGLES_TAG = "triangles";
static constexpr char* TRIANGLE_TAG = "triangle";
static constexpr char* COMPONENTS_TAG = "components";
static constexpr char* COMPONENT_TAG = "component";
static constexpr char* BUILD_TAG = "build";
static constexpr char* ITEM_TAG = "item";
static constexpr char* METADATA_TAG = "metadata";
static constexpr const char* MODEL_TAG = "model";
static constexpr const char* RESOURCES_TAG = "resources";
static constexpr const char* OBJECT_TAG = "object";
static constexpr const char* MESH_TAG = "mesh";
static constexpr const char* VERTICES_TAG = "vertices";
static constexpr const char* VERTEX_TAG = "vertex";
static constexpr const char* TRIANGLES_TAG = "triangles";
static constexpr const char* TRIANGLE_TAG = "triangle";
static constexpr const char* COMPONENTS_TAG = "components";
static constexpr const char* COMPONENT_TAG = "component";
static constexpr const char* BUILD_TAG = "build";
static constexpr const char* ITEM_TAG = "item";
static constexpr const char* METADATA_TAG = "metadata";
static constexpr char* CONFIG_TAG = "config";
static constexpr char* VOLUME_TAG = "volume";
static constexpr const char* CONFIG_TAG = "config";
static constexpr const char* VOLUME_TAG = "volume";
static constexpr char* UNIT_ATTR = "unit";
static constexpr char* NAME_ATTR = "name";
static constexpr char* TYPE_ATTR = "type";
static constexpr char* ID_ATTR = "id";
static constexpr char* X_ATTR = "x";
static constexpr char* Y_ATTR = "y";
static constexpr char* Z_ATTR = "z";
static constexpr char* V1_ATTR = "v1";
static constexpr char* V2_ATTR = "v2";
static constexpr char* V3_ATTR = "v3";
static constexpr char* OBJECTID_ATTR = "objectid";
static constexpr char* TRANSFORM_ATTR = "transform";
static constexpr char* PRINTABLE_ATTR = "printable";
static constexpr char* INSTANCESCOUNT_ATTR = "instances_count";
static constexpr char* CUSTOM_SUPPORTS_ATTR = "slic3rpe:custom_supports";
static constexpr char* CUSTOM_SEAM_ATTR = "slic3rpe:custom_seam";
static constexpr const char* UNIT_ATTR = "unit";
static constexpr const char* NAME_ATTR = "name";
static constexpr const char* TYPE_ATTR = "type";
static constexpr const char* ID_ATTR = "id";
static constexpr const char* X_ATTR = "x";
static constexpr const char* Y_ATTR = "y";
static constexpr const char* Z_ATTR = "z";
static constexpr const char* V1_ATTR = "v1";
static constexpr const char* V2_ATTR = "v2";
static constexpr const char* V3_ATTR = "v3";
static constexpr const char* OBJECTID_ATTR = "objectid";
static constexpr const char* TRANSFORM_ATTR = "transform";
static constexpr const char* PRINTABLE_ATTR = "printable";
static constexpr const char* INSTANCESCOUNT_ATTR = "instances_count";
static constexpr const char* CUSTOM_SUPPORTS_ATTR = "slic3rpe:custom_supports";
static constexpr const char* CUSTOM_SEAM_ATTR = "slic3rpe:custom_seam";
static constexpr char* KEY_ATTR = "key";
static constexpr char* VALUE_ATTR = "value";
static constexpr char* FIRST_TRIANGLE_ID_ATTR = "firstid";
static constexpr char* LAST_TRIANGLE_ID_ATTR = "lastid";
static constexpr const char* KEY_ATTR = "key";
static constexpr const char* VALUE_ATTR = "value";
static constexpr const char* FIRST_TRIANGLE_ID_ATTR = "firstid";
static constexpr const char* LAST_TRIANGLE_ID_ATTR = "lastid";
static constexpr char* OBJECT_TYPE = "object";
static constexpr char* VOLUME_TYPE = "volume";
static constexpr const char* OBJECT_TYPE = "object";
static constexpr const char* VOLUME_TYPE = "volume";
static constexpr char* NAME_KEY = "name";
static constexpr char* MODIFIER_KEY = "modifier";
static constexpr char* VOLUME_TYPE_KEY = "volume_type";
static constexpr char* MATRIX_KEY = "matrix";
static constexpr char* SOURCE_FILE_KEY = "source_file";
static constexpr char* SOURCE_OBJECT_ID_KEY = "source_object_id";
static constexpr char* SOURCE_VOLUME_ID_KEY = "source_volume_id";
static constexpr char* SOURCE_OFFSET_X_KEY = "source_offset_x";
static constexpr char* SOURCE_OFFSET_Y_KEY = "source_offset_y";
static constexpr char* SOURCE_OFFSET_Z_KEY = "source_offset_z";
static constexpr char* SOURCE_IN_INCHES = "source_in_inches";
static constexpr const char* NAME_KEY = "name";
static constexpr const char* MODIFIER_KEY = "modifier";
static constexpr const char* VOLUME_TYPE_KEY = "volume_type";
static constexpr const char* MATRIX_KEY = "matrix";
static constexpr const char* SOURCE_FILE_KEY = "source_file";
static constexpr const char* SOURCE_OBJECT_ID_KEY = "source_object_id";
static constexpr const char* SOURCE_VOLUME_ID_KEY = "source_volume_id";
static constexpr const char* SOURCE_OFFSET_X_KEY = "source_offset_x";
static constexpr const char* SOURCE_OFFSET_Y_KEY = "source_offset_y";
static constexpr const char* SOURCE_OFFSET_Z_KEY = "source_offset_z";
static constexpr const char* SOURCE_IN_INCHES = "source_in_inches";
const unsigned int VALID_OBJECT_TYPES_COUNT = 1;
const char* VALID_OBJECT_TYPES[] =
@ -2251,7 +2251,7 @@ namespace Slic3r {
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\" xmlns:slic3rpe=\"http://schemas.slic3r.org/3mf/2017/06\">\n";
stream << " <" << METADATA_TAG << " name=\"" << SLIC3RPE_3MF_VERSION << "\">" << VERSION_3MF << "</" << METADATA_TAG << ">\n";
std::string name = boost::filesystem::path(filename).stem().string();
std::string name = xml_escape(boost::filesystem::path(filename).stem().string());
stream << " <" << METADATA_TAG << " name=\"Title\">" << name << "</" << METADATA_TAG << ">\n";
stream << " <" << METADATA_TAG << " name=\"Designer\">" << "</" << METADATA_TAG << ">\n";
stream << " <" << METADATA_TAG << " name=\"Description\">" << name << "</" << METADATA_TAG << ">\n";

View File

@ -715,7 +715,20 @@ namespace DoExport {
region->config().get_abs_value("solid_infill_speed") == 0 ||
region->config().get_abs_value("top_solid_infill_speed") == 0 ||
region->config().get_abs_value("bridge_speed") == 0)
mm3_per_mm.push_back(layerm->fills.min_mm3_per_mm());
{
// Minimal volumetric flow should not be calculated over ironing extrusions.
// Use following lambda instead of the built-it method.
// https://github.com/prusa3d/PrusaSlicer/issues/5082
auto min_mm3_per_mm_no_ironing = [](const ExtrusionEntityCollection& eec) -> double {
double min = std::numeric_limits<double>::max();
for (const ExtrusionEntity* ee : eec.entities)
if (ee->role() != erIroning)
min = std::min(min, ee->min_mm3_per_mm());
return min;
};
mm3_per_mm.push_back(min_mm3_per_mm_no_ironing(layerm->fills));
}
}
}
if (object->config().get_abs_value("support_material_speed") == 0 ||
@ -1709,7 +1722,9 @@ namespace Skirt {
//FIXME infinite or high skirt does not make sense for sequential print!
(skirt_done.size() < (size_t)print.config().skirt_height.value || print.has_infinite_skirt()) &&
// This print_z has not been extruded yet (sequential print)
skirt_done.back() < layer_tools.print_z - EPSILON &&
// FIXME: The skirt_done should not be empty at this point. The check is a workaround
// of https://github.com/prusa3d/PrusaSlicer/issues/5652, but it deserves a real fix.
(! skirt_done.empty() && skirt_done.back() < layer_tools.print_z - EPSILON) &&
// and this layer is an object layer, or it is a raft layer.
(layer_tools.has_object || support_layer->id() < (size_t)support_layer->object()->config().raft_layers.value)) {
#if 0
@ -2096,6 +2111,8 @@ void GCode::process_layer(
instance_to_print.object_by_extruder.support->chained_path_from(m_last_pos, instance_to_print.object_by_extruder.support_extrusion_role));
m_layer = layers[instance_to_print.layer_id].layer();
}
//FIXME order islands?
// Sequential tool path ordering of multiple parts within the same object, aka. perimeter tracking (#5511)
for (ObjectByExtruder::Island &island : instance_to_print.object_by_extruder.islands) {
const auto& by_region_specific = is_anything_overridden ? island.by_region_per_copy(by_region_per_copy_cache, static_cast<unsigned int>(instance_to_print.instance_id), extruder_id, print_wipe_extrusions != 0) : island.by_region;
//FIXME the following code prints regions in the order they are defined, the path is not optimized in any way.

View File

@ -2345,6 +2345,8 @@ void GCodeProcessor::process_T(const std::string_view command)
if (command.length() > 1) {
int eid;
if (! parse_number(command.substr(1), eid) || eid < 0 || eid > 255) {
// T-1 is a valid gcode line for RepRap Firmwares (used to deselects all tools) see https://github.com/prusa3d/PrusaSlicer/issues/5677
if ((m_flavor != gcfRepRapFirmware && m_flavor != gcfRepRapSprinter) || eid != -1)
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << command << ").";
} else {
unsigned char id = static_cast<unsigned char>(eid);

View File

@ -134,7 +134,7 @@ GCodeSender::set_baud_rate(unsigned int baud_rate)
speed_t newSpeed = baud_rate;
ioctl(handle, IOSSIOSPEED, &newSpeed);
::tcsetattr(handle, TCSANOW, &ios);
#elif __linux
#elif __linux__
termios2 ios;
if (ioctl(handle, TCGETS2, &ios))
printf("Error in TCGETS2: %s\n", strerror(errno));

View File

@ -1152,11 +1152,14 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt)
{
if (opt_key == "bed_shape" || opt_key == "thumbnails" || opt_key == "compatible_prints" || opt_key == "compatible_printers") {
// Scalar variable, or a vector variable, which is independent from number of extruders,
// thus the vector is presented to the user as a single input.
diff.emplace_back(opt_key);
continue;
}
switch (other_opt->type())
{
} else if (opt_key == "default_filament_profile") {
// Ignore this field, it is not presented to the user, therefore showing a "modified" flag for this parameter does not help.
// Also the length of this field may differ, which may lead to a crash if the block below is used.
} else {
switch (other_opt->type()) {
case coInts: add_correct_opts_to_diff<ConfigOptionInts >(opt_key, diff, config_other, config_this); break;
case coBools: add_correct_opts_to_diff<ConfigOptionBools >(opt_key, diff, config_other, config_this); break;
case coFloats: add_correct_opts_to_diff<ConfigOptionFloats >(opt_key, diff, config_other, config_this); break;
@ -1167,6 +1170,7 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
}
}
}
}
return diff;
}

View File

@ -86,9 +86,8 @@ PresetBundle::PresetBundle() :
preset.config.optptr(key, true);
if (i == 0) {
preset.config.optptr("default_print_profile", true);
preset.config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
}
else {
preset.config.option<ConfigOptionStrings>("default_filament_profile", true);
} else {
preset.config.optptr("default_sla_print_profile", true);
preset.config.optptr("default_sla_material_profile", true);
}
@ -668,7 +667,7 @@ DynamicPrintConfig PresetBundle::full_sla_config() const
// If the file is loaded successfully, its print / filament / printer profiles will be activated.
void PresetBundle::load_config_file(const std::string &path)
{
if (boost::iends_with(path, ".gcode") || boost::iends_with(path, ".g")) {
if (is_gcode_file(path)) {
DynamicPrintConfig config;
config.apply(FullPrintConfig::defaults());
config.load_from_gcode_file(path);
@ -752,7 +751,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
switch (printer_technology) {
case ptFFF:
config.option<ConfigOptionString>("default_print_profile", true);
config.option<ConfigOptionStrings>("default_filament_profile", true)->values.resize(num_extruders, std::string());
config.option<ConfigOptionStrings>("default_filament_profile", true);
break;
case ptSLA:
config.option<ConfigOptionString>("default_sla_print_profile", true);

View File

@ -1851,10 +1851,7 @@ void Print::_make_brim()
}
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
}
loops = union_pt_chained(loops, false);
// The function above produces ordering well suited for concentric infill (from outside to inside).
// For Brim, the ordering should be reversed (from inside to outside).
std::reverse(loops.begin(), loops.end());
loops = union_pt_chained_outside_in(loops, false);
// If there is a possibility that brim intersects skirt, go through loops and split those extrusions
// The result is either the original Polygon or a list of Polylines

View File

@ -3378,6 +3378,8 @@ void DynamicPrintConfig::set_num_extruders(unsigned int num_extruders)
const auto &defaults = FullPrintConfig::defaults();
for (const std::string &key : print_config_def.extruder_option_keys()) {
if (key == "default_filament_profile")
// Don't resize this field, as it is presented to the user at the "Dependencies" page of the Printer profile and we don't want to present
// empty fields there, if not defined by the system profile.
continue;
auto *opt = this->option(key, false);
assert(opt != nullptr);

View File

@ -2004,10 +2004,9 @@ end:
layer->make_slices();
}
});
if (elephant_foot_compensation_scaled > 0.f) {
if (elephant_foot_compensation_scaled > 0.f && ! m_layers.empty()) {
// The Elephant foot has been compensated, therefore the 1st layer's lslices are shrank with the Elephant foot compensation value.
// Store the uncompensated value there.
assert(! m_layers.empty());
assert(m_layers.front()->id() == 0);
m_layers.front()->lslices = std::move(lslices_1st_layer);
}

View File

@ -12,7 +12,7 @@
// Renders a small sphere in the center of the bounding box of the current selection when no gizmo is active
#define ENABLE_RENDER_SELECTION_CENTER 0
// Shows an imgui dialog with render related data
#define ENABLE_RENDER_STATISTICS 1
#define ENABLE_RENDER_STATISTICS 0
// Shows an imgui dialog with camera related data
#define ENABLE_CAMERA_STATISTICS 0
// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering)

View File

@ -11,9 +11,9 @@
#include <mutex>
#include <tbb/parallel_for.h>
#include <tbb/tbb_thread.h>
#include <tbb/task_arena.h>
#include <tbb/task_scheduler_init.h>
#include "Thread.hpp"
namespace Slic3r {
@ -195,7 +195,10 @@ void name_tbb_thread_pool_threads()
return;
initialized = true;
const size_t nthreads_hw = std::thread::hardware_concurrency();
// see GH issue #5661 PrusaSlicer hangs on Linux when run with non standard task affinity
// TBB will respect the task affinity mask on Linux and spawn less threads than std::thread::hardware_concurrency().
// const size_t nthreads_hw = std::thread::hardware_concurrency();
const size_t nthreads_hw = tbb::this_task_arena::max_concurrency();
size_t nthreads = nthreads_hw;
#ifdef SLIC3R_PROFILE

View File

@ -45,9 +45,11 @@ void TriangleSelector::select_patch(const Vec3f& hit, int facet_start,
m_cursor = Cursor(hit, source, radius, cursor_type, trafo);
// In case user changed cursor size since last time, update triangle edge limit.
if (m_old_cursor_radius != radius) {
set_edge_limit(radius / 5.f);
m_old_cursor_radius = radius;
// It is necessary to compare the internal radius in m_cursor! radius is in
// world coords and does not change after scaling.
if (m_old_cursor_radius_sqr != m_cursor.radius_sqr) {
set_edge_limit(std::sqrt(m_cursor.radius_sqr) / 5.f);
m_old_cursor_radius_sqr = m_cursor.radius_sqr;
}
// Now start with the facet the pointer points to and check all adjacent facets.

View File

@ -146,7 +146,7 @@ protected:
};
Cursor m_cursor;
float m_old_cursor_radius;
float m_old_cursor_radius_sqr;
// Private functions:
bool select_triangle(int facet_idx, EnforcerBlockerType type,

View File

@ -90,6 +90,7 @@ extern CopyFileResult check_copy(const std::string& origin, const std::string& c
extern bool is_plain_file(const boost::filesystem::directory_entry &path);
extern bool is_ini_file(const boost::filesystem::directory_entry &path);
extern bool is_idx_file(const boost::filesystem::directory_entry &path);
extern bool is_gcode_file(const std::string &path);
// File path / name / extension splitting utilities, working with UTF-8,
// to be published to Perl.
@ -353,8 +354,12 @@ inline std::string get_time_dhm(float time_in_secs)
#if WIN32
#define SLIC3R_STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
//FIXME this is an inprecise hack. Add the hash table size and possibly some estimate of the linked list at each of the used bin.
#define SLIC3R_STDUNORDEREDSET_MEMSIZE(NAME, TYPE) NAME.size() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
#else
#define SLIC3R_STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
//FIXME this is an inprecise hack. Add the hash table size and possibly some estimate of the linked list at each of the used bin.
#define SLIC3R_STDUNORDEREDSET_MEMSIZE(NAME, TYPE) NAME.size() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
#endif
#endif // slic3r_Utils_hpp_

View File

@ -39,9 +39,9 @@
#include <tbb/task_scheduler_init.h>
#if defined(__linux) || defined(__GNUC__ )
#if defined(__linux__) || defined(__GNUC__ )
#include <strings.h>
#endif /* __linux */
#endif /* __linux__ */
#ifdef _MSC_VER
#define strcasecmp _stricmp
@ -522,6 +522,12 @@ bool is_idx_file(const boost::filesystem::directory_entry &dir_entry)
return is_plain_file(dir_entry) && strcasecmp(dir_entry.path().extension().string().c_str(), ".idx") == 0;
}
bool is_gcode_file(const std::string &path)
{
return boost::iends_with(path, ".gcode") || boost::iends_with(path, ".gco") ||
boost::iends_with(path, ".g") || boost::iends_with(path, ".ngc");
}
} // namespace Slic3r
#ifdef WIN32

View File

@ -255,3 +255,12 @@ endif ()
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
endif ()
# We need to implement some hacks for wxWidgets and touch the underlying GTK
# layer and sub-libraries. This forces us to use the include locations and
# link these libraries.
if (UNIX AND NOT APPLE)
find_package(GTK${SLIC3R_GTK} REQUIRED)
target_include_directories(libslic3r_gui PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS})
target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES})
endif ()

View File

@ -611,7 +611,7 @@ struct _3DScene
static void point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume);
};
static constexpr float BedEpsilon = float(EPSILON);
static constexpr float BedEpsilon = 3.f * float(EPSILON);
}

View File

@ -147,9 +147,9 @@ void GCodeViewer::TBuffer::reset()
}
// release cpu memory
indices = std::vector<IBuffer>();
paths = std::vector<Path>();
render_paths = std::vector<RenderPath>();
indices.clear();
paths.clear();
render_paths.clear();
}
void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id)
@ -781,9 +781,9 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
unsigned int start_vertex_offset = buffer.start_segment_vertex_offset();
unsigned int end_vertex_offset = buffer.end_segment_vertex_offset();
for (size_t i = 0; i < buffer.render_paths.size(); ++i) {
size_t i = 0;
for (const RenderPath& render_path : buffer.render_paths) {
// get paths segments from buffer paths
const RenderPath& render_path = buffer.render_paths[i];
const IndexBuffer& ibuffer = indices[render_path.index_buffer_id];
const Path& path = buffer.paths[render_path.path_id];
float half_width = 0.5f * path.width;
@ -948,6 +948,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
for (const Triangle& t : out_triangles) {
fprintf(fp, "f %zu//%zu %zu//%zu %zu//%zu\n", t[0], t[0], t[1], t[1], t[2], t[2]);
}
++ i;
}
fclose(fp);
@ -1900,6 +1902,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
}
// second pass: filter paths by sequential data and collect them by color
RenderPath *render_path = nullptr;
for (const auto& [buffer, index_buffer_id, path_id] : paths) {
const Path& path = buffer->paths[path_id];
if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first)
@ -1930,16 +1933,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
default: { color = { 0.0f, 0.0f, 0.0f }; break; }
}
unsigned int ibuffer_id = index_buffer_id;
auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(),
[color, ibuffer_id](const RenderPath& path) { return path.index_buffer_id == ibuffer_id && path.color == color; });
if (it == buffer->render_paths.end()) {
it = buffer->render_paths.insert(buffer->render_paths.end(), RenderPath());
it->color = color;
it->path_id = path_id;
it->index_buffer_id = index_buffer_id;
}
RenderPath key{ color, static_cast<unsigned int>(index_buffer_id), path_id };
if (render_path == nullptr || ! RenderPathPropertyEqual()(*render_path, key))
render_path = const_cast<RenderPath*>(&(*buffer->render_paths.emplace(key).first));
unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1;
unsigned int size_in_indices = 0;
switch (buffer->render_primitive_type)
@ -1948,7 +1944,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
case TBuffer::ERenderPrimitiveType::Line:
case TBuffer::ERenderPrimitiveType::Triangle: { size_in_indices = buffer->indices_per_segment() * (segments_count - 1); break; }
}
it->sizes.push_back(size_in_indices);
render_path->sizes.push_back(size_in_indices);
unsigned int delta_1st = 0;
if (path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= path.last.s_id)
@ -1957,7 +1953,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
if (buffer->render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle)
delta_1st *= buffer->indices_per_segment();
it->offsets.push_back(static_cast<size_t>((path.first.i_id + delta_1st) * sizeof(unsigned int)));
render_path->offsets.push_back(static_cast<size_t>((path.first.i_id + delta_1st) * sizeof(unsigned int)));
}
// set sequential data to their final value
@ -2943,7 +2939,7 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional)
int64_t render_paths_size = 0;
for (const TBuffer& buffer : m_buffers) {
paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path);
render_paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.render_paths, RenderPath);
render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath);
for (const RenderPath& path : buffer.render_paths) {
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int);
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t);

View File

@ -7,6 +7,8 @@
#include <cstdint>
#include <float.h>
#include <set>
#include <unordered_set>
namespace Slic3r {
@ -146,12 +148,36 @@ class GCodeViewer
// Used to batch the indices needed to render paths
struct RenderPath
{
// Render path property
Color color;
unsigned int path_id;
unsigned int index_buffer_id;
// Render path content
unsigned int path_id;
std::vector<unsigned int> sizes;
std::vector<size_t> offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements())
};
struct RenderPathPropertyHash {
size_t operator() (const RenderPath &p) const {
// Conver the RGB value to an integer hash.
// return (size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) * 7919) ^ size_t(p.index_buffer_id);
return size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) ^ size_t(p.index_buffer_id);
}
};
struct RenderPathPropertyLower {
bool operator() (const RenderPath &l, const RenderPath &r) const {
for (int i = 0; i < 3; ++ i)
if (l.color[i] < r.color[i])
return true;
else if (l.color[i] > r.color[i])
return false;
return l.index_buffer_id < r.index_buffer_id;
}
};
struct RenderPathPropertyEqual {
bool operator() (const RenderPath &l, const RenderPath &r) const {
return l.color == r.color && l.index_buffer_id == r.index_buffer_id;
}
};
// buffer containing data for rendering a specific toolpath type
struct TBuffer
@ -169,7 +195,9 @@ class GCodeViewer
std::string shader;
std::vector<Path> paths;
std::vector<RenderPath> render_paths;
// std::set seems to perform singificantly better, at least on Windows.
// std::unordered_set<RenderPath, RenderPathPropertyHash, RenderPathPropertyEqual> render_paths;
std::set<RenderPath, RenderPathPropertyLower> render_paths;
bool visible{ false };
void reset();

View File

@ -2996,6 +2996,7 @@ void GLCanvas3D::on_render_timer(wxTimerEvent& evt)
}
//render();
m_dirty = true;
wxWakeUpIdle();
}
void GLCanvas3D::request_extra_frame_delayed(int miliseconds)
@ -4151,9 +4152,13 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool
shader->start_using();
shader->set_uniform("print_box.volume_detection", 0);
for (const GLVolume* vol : visible_volumes) {
for (GLVolume* vol : visible_volumes) {
shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray);
// the volume may have been deactivated by an active gizmo
bool is_active = vol->is_active;
vol->is_active = true;
vol->render();
vol->is_active = is_active;
}
shader->stop_using();

View File

@ -652,7 +652,6 @@ public:
void set_toolpath_view_type(GCodeViewer::EViewType type);
void set_volumes_z_range(const std::array<double, 2>& range);
void set_toolpaths_z_range(const std::array<unsigned int, 2>& range);
void set_toolpaths_range(double low, double high);
std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
std::vector<int> load_object(const Model& model, int obj_idx);

View File

@ -131,7 +131,7 @@ public:
memDC.SetFont(m_action_font);
memDC.SetTextForeground(wxColour(237, 107, 33));
memDC.DrawText(text, int(m_scale * 60), int(m_scale * 275));
memDC.DrawText(text, int(m_scale * 60), m_action_line_y_position);
memDC.SelectObject(wxNullBitmap);
set_bitmap(bitmap);
@ -206,14 +206,22 @@ public:
memDc.SetFont(m_constant_text.version_font);
memDc.DrawLabel(m_constant_text.version, banner_rect, wxALIGN_TOP | wxALIGN_LEFT);
int version_height = memDc.GetTextExtent(m_constant_text.version).GetY();
memDc.SetFont(m_constant_text.credits_font);
memDc.DrawLabel(m_constant_text.credits, banner_rect, wxALIGN_BOTTOM | wxALIGN_LEFT);
int credits_height = memDc.GetMultiLineTextExtent(m_constant_text.credits).GetY();
int text_height = memDc.GetTextExtent("text").GetY();
// calculate position for the dynamic text
int logo_and_header_height = margin + logo_size + title_height + version_height;
m_action_line_y_position = logo_and_header_height + 0.5 * (bmp.GetHeight() - margin - credits_height - logo_and_header_height - text_height);
}
private:
wxBitmap m_main_bitmap;
wxFont m_action_font;
int m_action_line_y_position;
float m_scale {1.0};
struct ConstantText
@ -258,7 +266,8 @@ private:
float title_font_scale = (float)text_banner_width / GetTextExtent(m_constant_text.title).GetX();
scale_font(m_constant_text.title_font, title_font_scale > 3.5f ? 3.5f : title_font_scale);
scale_font(m_constant_text.version_font, 2.f);
float version_font_scale = (float)text_banner_width / GetTextExtent(m_constant_text.version).GetX();
scale_font(m_constant_text.version_font, version_font_scale > 2.f ? 2.f : version_font_scale);
// The width of the credits information string doesn't respect to the banner width some times.
// So, scale credits_font in the respect to the longest string width
@ -753,7 +762,7 @@ bool GUI_App::on_init_inner()
#ifdef __linux__
if (! check_old_linux_datadir(GetAppName())) {
std::cerr << "Quitting, user chose to move his data to new location." << std::endl;
std::cerr << "Quitting, user chose to move their data to new location." << std::endl;
return false;
}
#endif
@ -1879,11 +1888,9 @@ bool GUI_App::OnExceptionInMainLoop()
void GUI_App::OSXStoreOpenFiles(const wxArrayString &fileNames)
{
size_t num_gcodes = 0;
for (const wxString &filename : fileNames) {
wxString fn = filename.Upper();
if (fn.EndsWith(".G") || fn.EndsWith(".GCODE"))
for (const wxString &filename : fileNames)
if (is_gcode_file(into_u8(filename)))
++ num_gcodes;
}
if (fileNames.size() == num_gcodes) {
// Opening PrusaSlicer by drag & dropping a G-Code onto PrusaSlicer icon in Finder,
// just G-codes were passed. Switch to G-code viewer mode.
@ -1903,8 +1910,7 @@ void GUI_App::MacOpenFiles(const wxArrayString &fileNames)
std::vector<wxString> gcode_files;
std::vector<wxString> non_gcode_files;
for (const auto& filename : fileNames) {
wxString fn = filename.Upper();
if (fn.EndsWith(".G") || fn.EndsWith(".GCODE"))
if (is_gcode_file(into_u8(filename)))
gcode_files.emplace_back(filename);
else {
files.emplace_back(into_u8(filename));

View File

@ -16,11 +16,26 @@
#include <boost/nowide/iostream.hpp>
#include <boost/nowide/convert.hpp>
#if __APPLE__
#include <signal.h>
#endif // __APPLE__
namespace Slic3r {
namespace GUI {
int GUI_Run(GUI_InitParams &params)
{
#if __APPLE__
// On OSX, we use boost::process::spawn() to launch new instances of PrusaSlicer from another PrusaSlicer.
// boost::process::spawn() sets SIGCHLD to SIGIGN for the child process, thus if a child PrusaSlicer spawns another
// subprocess and the subrocess dies, the child PrusaSlicer will not receive information on end of subprocess
// (posix waitpid() call will always fail).
// https://jmmv.dev/2008/10/boostprocess-and-sigchld.html
// The child instance of PrusaSlicer has to reset SIGCHLD to its default, so that posix waitpid() and similar continue to work.
// See GH issue #5507
signal(SIGCHLD, SIG_DFL);
#endif // __APPLE__
try {
GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {

View File

@ -1211,7 +1211,7 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
**/
m_prevent_list_events = true;//it's needed for GTK
/* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid value,
/* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid vaSome textlue,
* so set some nonempty string
*/
wxTextDataObject* obj = new wxTextDataObject;
@ -1243,8 +1243,10 @@ void ObjectList::OnDropPossible(wxDataViewEvent &event)
{
const wxDataViewItem& item = event.GetItem();
if (!can_drop(item))
if (!can_drop(item)) {
event.Veto();
m_prevent_list_events = false;
}
}
void ObjectList::OnDrop(wxDataViewEvent &event)
@ -1269,7 +1271,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
// It looks like a fixed in current version of the wxWidgets
// #ifdef __WXGTK__
// /* Under GTK, DnD moves an item between another two items.
// * And event.GetItem() return item, which is under "insertion line"
// * And event.GetItem() return item, which is under "insertion line"Some text
// * So, if we move item down we should to decrease the to_volume_id value
// **/
// if (to_volume_id > from_volume_id) to_volume_id--;
@ -2407,6 +2409,8 @@ void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item)
m_config->set_key_value("extruder", new ConfigOptionInt(extruder));
if (is_layer_settings)
m_config->set_key_value("layer_height", new ConfigOptionFloat(layer_height));
changed_object();
}
void ObjectList::del_instances_from_object(const int obj_idx)

View File

@ -252,14 +252,31 @@ namespace instance_check_internal
bool instance_check(int argc, char** argv, bool app_config_single_instance)
{
#ifndef _WIN32
boost::system::error_code ec;
#endif
std::size_t hashed_path =
std::size_t hashed_path;
#ifdef _WIN32
std::hash<std::string>{}(boost::filesystem::system_complete(argv[0]).string());
hashed_path = std::hash<std::string>{}(boost::filesystem::system_complete(argv[0]).string());
#else
std::hash<std::string>{}(boost::filesystem::canonical(boost::filesystem::system_complete(argv[0]), ec).string());
boost::system::error_code ec;
#ifdef __linux__
// If executed by an AppImage, start the AppImage, not the main process.
// see https://docs.appimage.org/packaging-guide/environment-variables.html#id2
const char *appimage_env = std::getenv("APPIMAGE");
bool appimage_env_valid = false;
if (appimage_env) {
try {
auto appimage_path = boost::filesystem::canonical(boost::filesystem::path(appimage_env));
if (boost::filesystem::exists(appimage_path)) {
hashed_path = std::hash<std::string>{}(appimage_path.string());
appimage_env_valid = true;
}
} catch (std::exception &) {
}
if (! appimage_env_valid)
BOOST_LOG_TRIVIAL(error) << "APPIMAGE environment variable was set, but it does not point to a valid file: " << appimage_env;
}
if (! appimage_env_valid)
#endif // __linux__
hashed_path = std::hash<std::string>{}(boost::filesystem::canonical(boost::filesystem::system_complete(argv[0]), ec).string());
if (ec.value() > 0) { // canonical was not able to find the executable (can happen with appimage on some systems. Does it fail on Fuse file systems?)
ec.clear();
// Compose path with boost canonical of folder and filename
@ -269,7 +286,7 @@ bool instance_check(int argc, char** argv, bool app_config_single_instance)
hashed_path = std::hash<std::string>{}(boost::filesystem::system_complete(argv[0]).string());
}
}
#endif // win32
#endif // _WIN32
std::string lock_name = std::to_string(hashed_path);
GUI::wxGetApp().set_instance_hash(hashed_path);

View File

@ -73,9 +73,14 @@ void FillBedJob::prepare()
// This is the maximum number of items, the real number will always be close but less.
int needed_items = (bed_area - fixed_area) / poly_area;
ModelInstance *mi = model_object->instances[0];
int sel_id = m_plater->get_selection().get_instance_idx();
// if the selection is not a single instance, choose the first as template
sel_id = std::max(sel_id, 0);
ModelInstance *mi = model_object->instances[sel_id];
ArrangePolygon template_ap = get_arrange_poly(PtrWrapper{mi}, m_plater);
for (int i = 0; i < needed_items; ++i) {
ArrangePolygon ap;
ArrangePolygon ap = template_ap;
ap.poly = m_selected.front().poly;
ap.bed_idx = arrangement::UNARRANGED;
ap.setter = [this, mi](const ArrangePolygon &p) {

View File

@ -77,7 +77,7 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_
{
html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), monospaced_font ? 30 * wxGetApp().em_unit() : -1));
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxFont monospace = wxSystemSettings::GetFont(wxSYS_ANSI_FIXED_FONT);
wxFont monospace = wxGetApp().code_font();
wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());

View File

@ -1233,11 +1233,11 @@ bool NotificationManager::push_notification_data(std::unique_ptr<NotificationMan
if (this->activate_existing(notification.get())) {
m_pop_notifications.back()->update(notification->get_data());
canvas.request_extra_frame();
canvas.request_extra_frame_delayed(33);
return false;
} else {
m_pop_notifications.emplace_back(std::move(notification));
canvas.request_extra_frame();
canvas.request_extra_frame_delayed(33);
return true;
}
}
@ -1387,15 +1387,19 @@ void NotificationManager::update_notifications()
if (!top_level_wnd->IsActive())
return;
static size_t last_size = m_pop_notifications.size();
//static size_t last_size = m_pop_notifications.size();
//request frames
int64_t next_render = std::numeric_limits<int64_t>::max();
for (auto it = m_pop_notifications.begin(); it != m_pop_notifications.end();) {
std::unique_ptr<PopNotification>& notification = *it;
notification->set_paused(m_hovered);
notification->update_state();
next_render = std::min<int64_t>(next_render, notification->next_render());
if (notification->get_state() == PopNotification::EState::Finished)
it = m_pop_notifications.erase(it);
else {
notification->set_paused(m_hovered);
notification->update_state();
++it;
}
}
@ -1436,16 +1440,11 @@ void NotificationManager::update_notifications()
if (m_requires_render)
m_requires_update = true;
*/
//request frames
int64_t next_render = std::numeric_limits<int64_t>::max();
const int64_t max = std::numeric_limits<int64_t>::max();
for (const std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
next_render = std::min<int64_t>(next_render, notification->next_render());
}
if (next_render == 0)
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame();
else if (next_render < max)
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame_delayed(33); //few milliseconds to get from GLCanvas::render
else if (next_render < std::numeric_limits<int64_t>::max())
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame_delayed(int(next_render));
/*

View File

@ -544,7 +544,7 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
return;
}
if (printer_name == m_default_name) {
warning_catcher(this, _L("You should to change a name of your printer device. It can't be saved."));
warning_catcher(this, _L("You should change the name of your printer device."));
return;
}

View File

@ -3566,6 +3566,14 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
*/
wxGetApp().obj_list()->update_object_list_by_printer_technology();
}
#ifdef __WXMSW__
// From the Win 2004 preset combobox lose a focus after change the preset selection
// and that is why the up/down arrow doesn't work properly
// (see https://github.com/prusa3d/PrusaSlicer/issues/5531 ).
// So, set the focus to the combobox explicitly
combo->SetFocus();
#endif
}
void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
@ -4847,9 +4855,7 @@ void Plater::load_gcode()
void Plater::load_gcode(const wxString& filename)
{
if (filename.empty() ||
(!filename.Lower().EndsWith(".gcode") && !filename.Lower().EndsWith(".g")) ||
m_last_loaded_gcode == filename)
if (! is_gcode_file(into_u8(filename)) || m_last_loaded_gcode == filename)
return;
m_last_loaded_gcode = filename;

View File

@ -32,6 +32,14 @@
#include "PhysicalPrinterDialog.hpp"
#include "SavePresetDialog.hpp"
// A workaround for a set of issues related to text fitting into gtk widgets:
// See e.g.: https://github.com/prusa3d/PrusaSlicer/issues/4584
#if defined(__WXGTK20__) || defined(__WXGTK3__)
#include <glib-2.0/glib-object.h>
#include <pango-1.0/pango/pango-layout.h>
#include <gtk/gtk.h>
#endif
using Slic3r::GUI::format_wxstr;
namespace Slic3r {
@ -179,6 +187,25 @@ void PresetComboBox::update_selection()
SetSelection(m_last_selected);
SetToolTip(GetString(m_last_selected));
// A workaround for a set of issues related to text fitting into gtk widgets:
// See e.g.: https://github.com/prusa3d/PrusaSlicer/issues/4584
#if defined(__WXGTK20__) || defined(__WXGTK3__)
GList* cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(m_widget));
// 'cells' contains the GtkCellRendererPixBuf for the icon,
// 'cells->next' contains GtkCellRendererText for the text we need to ellipsize
if (!cells || !cells->next) return;
auto cell = static_cast<GtkCellRendererText *>(cells->next->data);
if (!cell) return;
g_object_set(G_OBJECT(cell), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
// Only the list of cells must be freed, the renderer isn't ours to free
g_list_free(cells);
#endif
}
void PresetComboBox::update(std::string select_preset_name)
@ -860,9 +887,13 @@ void PlaterPresetComboBox::update()
if (!tooltip.IsEmpty())
SetToolTip(tooltip);
#ifdef __WXMSW__
// Use this part of code just on Windows to avoid of some layout issues on Linux
// see https://github.com/prusa3d/PrusaSlicer/issues/5163 and https://github.com/prusa3d/PrusaSlicer/issues/5505
// Update control min size after rescale (changed Display DPI under MSW)
if (GetMinWidth() != 20 * m_em_unit)
SetMinSize(wxSize(20 * m_em_unit, GetSize().GetHeight()));
#endif //__WXMSW__
}
void PlaterPresetComboBox::msw_rescale()
@ -905,6 +936,13 @@ TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type)
}
evt.StopPropagation();
#ifdef __WXMSW__
// From the Win 2004 preset combobox lose a focus after change the preset selection
// and that is why the up/down arrow doesn't work properly
// (see https://github.com/prusa3d/PrusaSlicer/issues/5531 ).
// So, set the focus to the combobox explicitly
this->SetFocus();
#endif
});
}

View File

@ -80,6 +80,17 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
Fit();
CenterOnParent();
#ifdef __linux__
// On Linux with GTK2 when text control lose the focus then selection (colored background) disappears but text color stay white
// and as a result the text is invisible with light mode
// see https://github.com/prusa3d/PrusaSlicer/issues/4532
// Workaround: Unselect text selection explicitly on kill focus
txt_filename->Bind(wxEVT_KILL_FOCUS, [this](wxEvent& e) {
e.Skip();
txt_filename->SetInsertionPoint(txt_filename->GetLastPosition());
}, txt_filename->GetId());
#endif /* __linux__ */
Bind(wxEVT_SHOW, [=](const wxShowEvent &) {
// Another similar case where the function only works with EVT_SHOW + CallAfter,
// this time on Mac.

View File

@ -261,19 +261,31 @@ void RemovableDriveManager::eject_drive()
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
this->update();
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
#if __APPLE__
// If eject is still pending on the eject thread, wait until it finishes.
//FIXME while waiting for the eject thread to finish, the main thread is not pumping Cocoa messages, which may lead
// to blocking by the diskutil tool for a couple (up to 10) seconds. This is likely not critical, as the eject normally
// finishes quickly.
this->eject_thread_finish();
#endif
BOOST_LOG_TRIVIAL(info) << "Ejecting started";
DriveData drive_data;
{
tbb::mutex::scoped_lock lock(m_drives_mutex);
auto it_drive_data = this->find_last_save_path_drive_data();
if (it_drive_data != m_current_drives.end()) {
std::string correct_path(m_last_save_path);
#ifndef __APPLE__
for (size_t i = 0; i < correct_path.size(); ++i)
if (correct_path[i]==' ') {
correct_path = correct_path.insert(i,1,'\\');
++ i;
if (it_drive_data == m_current_drives.end())
return;
drive_data = *it_drive_data;
}
std::string correct_path(m_last_save_path);
#if __APPLE__
// On Apple, run the eject asynchronously on a worker thread, see the discussion at GH issue #4844.
m_eject_thread = new boost::thread([this, correct_path, drive_data]()
#endif
{
//std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n";
// there is no usable command in c++ so terminal command is used instead
// but neither triggers "succesful safe removal messege"
@ -296,32 +308,37 @@ void RemovableDriveManager::eject_drive()
// wait for command to finnish (blocks ui thread)
std::error_code ec;
child.wait(ec);
bool success = false;
if (ec) {
// The wait call can fail, as it did in https://github.com/prusa3d/PrusaSlicer/issues/5507
// It can happen even in cases where the eject is sucessful, but better report it as failed.
// We did not find a way to reliably retrieve the exit code of the process.
BOOST_LOG_TRIVIAL(error) << "boost::process::child::wait() failed during Ejection. State of Ejection is unknown. Error code: " << ec.value();
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
return;
}
} else {
int err = child.exit_code();
if (err) {
BOOST_LOG_TRIVIAL(error) << "Ejecting failed. Exit code: " << err;
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
return;
}
} else {
BOOST_LOG_TRIVIAL(info) << "Ejecting finished";
success = true;
}
}
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(std::move(*it_drive_data), true)));
m_current_drives.erase(it_drive_data);
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(drive_data, success)));
if (success) {
// Remove the drive_data from m_current drives, searching by value, not by pointer, as m_current_drives may get modified during
// asynchronous execution on m_eject_thread.
tbb::mutex::scoped_lock lock(m_drives_mutex);
auto it = std::find(m_current_drives.begin(), m_current_drives.end(), drive_data);
if (it != m_current_drives.end())
m_current_drives.erase(it);
}
}
#if __APPLE__
);
#endif // __APPLE__
}
std::string RemovableDriveManager::get_removable_drive_path(const std::string &path)
{
@ -382,7 +399,11 @@ void RemovableDriveManager::init(wxEvtHandler *callback_evt_handler)
void RemovableDriveManager::shutdown()
{
#if __APPLE__
this->unregister_window_osx();
// If eject is still pending on the eject thread, wait until it finishes.
//FIXME while waiting for the eject thread to finish, the main thread is not pumping Cocoa messages, which may lead
// to blocking by the diskutil tool for a couple (up to 10) seconds. This is likely not critical, as the eject normally
// finishes quickly.
this->eject_thread_finish();
#endif
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
@ -493,4 +514,15 @@ std::vector<DriveData>::const_iterator RemovableDriveManager::find_last_save_pat
[this](const DriveData &data){ return data.path == m_last_save_path; });
}
#if __APPLE__
void RemovableDriveManager::eject_thread_finish()
{
if (m_eject_thread) {
m_eject_thread->join();
delete m_eject_thread;
m_eject_thread = nullptr;
}
}
#endif // __APPLE__
}} // namespace Slic3r::GUI

View File

@ -132,6 +132,8 @@ private:
void eject_device(const std::string &path);
// Opaque pointer to RemovableDriveManagerMM
void *m_impl_osx;
boost::thread *m_eject_thread { nullptr };
void eject_thread_finish();
#endif
};

View File

@ -302,6 +302,13 @@ void Tab::create_preset_tab()
// This helps to process all the cursor key events on Windows in the tree control,
// so that the cursor jumps to the last item.
m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, [this](wxTreeEvent&) {
#ifdef __linux__
// Events queue is opposite On Linux. wxEVT_SET_FOCUS invokes after wxEVT_TREE_SEL_CHANGED,
// and a result wxEVT_KILL_FOCUS doesn't invoke for the TextCtrls.
// see https://github.com/prusa3d/PrusaSlicer/issues/5720
// So, call SetFocus explicitly for this control before changing of the selection
m_treectrl->SetFocus();
#endif
if (!m_disable_tree_sel_changed_event && !m_pages.empty()) {
if (m_page_switch_running)
m_page_switch_planned = true;
@ -499,7 +506,7 @@ void Tab::update_label_colours()
if (opt.first == "bed_shape" || opt.first == "filament_ramming_parameters" ||
opt.first == "compatible_prints" || opt.first == "compatible_printers" ) {
if (m_colored_Label_colors.find(opt.first) != m_colored_Label_colors.end())
*m_colored_Label_colors.at(opt.first) = *color;
m_colored_Label_colors.at(opt.first) = *color;
continue;
}
@ -540,7 +547,7 @@ void Tab::decorate()
if (opt.first == "bed_shape" || opt.first == "filament_ramming_parameters" ||
opt.first == "compatible_prints" || opt.first == "compatible_printers")
colored_label_clr = (m_colored_Label_colors.find(opt.first) == m_colored_Label_colors.end()) ? nullptr : m_colored_Label_colors.at(opt.first);
colored_label_clr = (m_colored_Label_colors.find(opt.first) == m_colored_Label_colors.end()) ? nullptr : &m_colored_Label_colors.at(opt.first);
if (!colored_label_clr) {
field = get_field(opt.first);
@ -3551,8 +3558,8 @@ void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::strin
line.widget = widget;
line.label_path = path;
m_colored_Label_colors[opt_key] = &m_default_text_clr;
line.full_Label_color = m_colored_Label_colors[opt_key];
m_colored_Label_colors[opt_key] = m_default_text_clr;
line.full_Label_color = &m_colored_Label_colors[opt_key];
optgroup->append_line(line);
}

View File

@ -246,7 +246,7 @@ public:
// map of option name -> wxColour (color of the colored label, associated with option)
// Used for options which don't have corresponded field
std::map<std::string, wxColour*> m_colored_Label_colors;
std::map<std::string, wxColour> m_colored_Label_colors;
// Counter for the updating (because of an update() function can have a recursive behavior):
// 1. increase value from the very beginning of an update() function

View File

@ -78,6 +78,12 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance
if (instance_type == NewSlicerInstanceType::Slicer && single_instance)
args.emplace_back("--single-instance");
boost::process::spawn(bin_path, args);
// boost::process::spawn() sets SIGCHLD to SIGIGN for the child process, thus if a child PrusaSlicer spawns another
// subprocess and the subrocess dies, the child PrusaSlicer will not receive information on end of subprocess
// (posix waitpid() call will always fail).
// https://jmmv.dev/2008/10/boostprocess-and-sigchld.html
// The child instance of PrusaSlicer has to reset SIGCHLD to its default, so that posix waitpid() and similar continue to work.
// See GH issue #5507
}
catch (const std::exception& ex) {
BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what();
@ -87,7 +93,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance
{
std::vector<const char*> args;
args.reserve(3);
#ifdef __linux
#ifdef __linux__
static const char* gcodeviewer_param = "--gcodeviewer";
{
// If executed by an AppImage, start the AppImage, not the main process.
@ -99,7 +105,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance
args.emplace_back(gcodeviewer_param);
}
}
#endif // __linux
#endif // __linux__
std::string my_path;
if (args.empty()) {
// Binary path was not set to the AppImage in the Linux specific block above, call the application directly.

View File

@ -313,7 +313,7 @@ void Serial::set_baud_rate(unsigned baud_rate)
speed_t newSpeed = baud_rate;
handle_errno(::ioctl(handle, IOSSIOSPEED, &newSpeed));
handle_errno(::tcsetattr(handle, TCSANOW, &ios));
#elif __linux
#elif __linux__
/* The following definitions are kindly borrowed from:
/usr/include/asm-generic/termbits.h

View File

@ -3,7 +3,7 @@
set(SLIC3R_APP_NAME "PrusaSlicer")
set(SLIC3R_APP_KEY "PrusaSlicer")
set(SLIC3R_VERSION "2.3.0-rc2")
set(SLIC3R_VERSION "2.3.0")
set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN")
set(SLIC3R_RC_VERSION "2,3,0,0")
set(SLIC3R_RC_VERSION_DOTS "2.3.0.0")