diff --git a/.cursor/rules/code-comments-language.mdc b/.cursor/rules/code-comments-language.mdc new file mode 100644 index 0000000000..cb3a640aea --- /dev/null +++ b/.cursor/rules/code-comments-language.mdc @@ -0,0 +1,24 @@ +--- +description: 代码注释默认语言 +alwaysApply: true +--- + +# 代码注释默认语言 + +- 代码里**新增 / 修改的注释默认使用英文**,与 BambuStudio / slic3r / PrusaSlicer 上游代码库保持一致风格。 +- 补充 `commit-msg` 规则里的"代码(变量名、注释、commit message)保持原有语言":该条仅针对**已有**注释(不要顺手翻译),新写的注释按本规则默认英文。 +- 允许混写中文的例外情况: + - 注释直接引用外部中文语境(Jira 标题、用户反馈、中文 UI 文案、commit message 片段) + - 已有文件内整体就是中文注释,且新增注释与邻近上下文紧密衔接、翻成英文反而影响可读性 +- 面向用户的字符串(UI 文案、i18n 资源、用户可见日志)按原有 i18n / 日志规范处理,不在本规则范围内。 +- 本规则只约束源码里的注释文字。commit message 语言见 `commit-msg` 规则。 + +示例: + +- 推荐: + - `// Fallback option: keep the current value visible when it is not in the preset list.` + - `// Only the user-initiated onChange should call set_selected_machine; polling must stay read-only.` +- 允许: + - `// 对齐 STUDIO-17964 "仅更新用户修改字段" 的需求。` (引用中文 Jira 语境) +- 不推荐: + - 在全英文文件里新写 `// 只读轮询:不带 dev_id…`(应写成英文) diff --git a/.gitignore b/.gitignore index 976a0d0231..5daf4b6e5f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ dep_win_new compile_commands.json .jira/ .claude/settings.local.json +**/node_modules/ +.worktrees/ + diff --git a/bbl/i18n/BambuStudio.pot b/bbl/i18n/BambuStudio.pot index 8acc549ce4..9853ec7ff9 100644 --- a/bbl/i18n/BambuStudio.pot +++ b/bbl/i18n/BambuStudio.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3150,10 +3150,10 @@ msgstr "" msgid "Filling" msgstr "" -msgid "Bed filling canceled." +msgid "Bed filling done." msgstr "" -msgid "Bed filling done." +msgid "Bed filling canceled." msgstr "" #. TRN: This is the title of the action appearing in undo/redo stack. @@ -3817,6 +3817,9 @@ msgstr "" msgid "Running post-processing scripts" msgstr "" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "" @@ -4495,6 +4498,9 @@ msgstr "" msgid "Fan Speed" msgstr "" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "" @@ -4570,6 +4576,9 @@ msgstr "" msgid "Fan Speed (%)" msgstr "" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "" @@ -4723,6 +4732,9 @@ msgstr "" msgid "Fan Speed: " msgstr "" +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "" @@ -4802,6 +4814,9 @@ msgstr "" msgid "Increase/decrease edit area" msgstr "" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "" @@ -5212,6 +5227,9 @@ msgstr "" msgid "Project" msgstr "" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "" @@ -5350,6 +5368,9 @@ msgstr "" msgid "Isometric View" msgstr "" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "" @@ -5374,9 +5395,6 @@ msgstr "" msgid "Save Project as" msgstr "" -msgid "Shift+" -msgstr "" - msgid "Save current project as" msgstr "" @@ -6462,6 +6480,18 @@ msgstr "" msgid "%s has a warning" msgstr "" +msgid "Collapse" +msgstr "" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "" + +msgid "Do not execute" +msgstr "" + #, possible-c-format, possible-boost-format msgid "%s info" msgstr "" @@ -7132,9 +7162,6 @@ msgstr "" msgid "Restore" msgstr "" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "" @@ -7214,6 +7241,12 @@ msgstr "" msgid "The name may show garbage characters!" msgstr "" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, possible-boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "" @@ -7745,6 +7778,11 @@ msgstr "" msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, possible-c-format, possible-boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -7804,6 +7842,11 @@ msgstr "" msgid "Plate Settings" msgstr "" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "" @@ -8638,6 +8681,10 @@ msgstr "" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, possible-c-format, possible-boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, possible-c-format, possible-boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "" @@ -8920,9 +8967,6 @@ msgstr "" msgid "This printer does not support printing all plates" msgstr "" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "" @@ -10210,6 +10254,9 @@ msgstr "" msgid "Camera view - Isometric" msgstr "" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12349,6 +12396,12 @@ msgstr "" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "" @@ -14955,9 +15008,6 @@ msgstr "" msgid "Keep original models" msgstr "" -msgid "Execute" -msgstr "" - msgid "Entity Only" msgstr "" @@ -15452,9 +15502,6 @@ msgstr "" msgid "For more information, please check out Wiki" msgstr "" -msgid "Collapse" -msgstr "" - msgid "Daily Tips" msgstr "" @@ -16076,12 +16123,6 @@ msgstr "" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "" - msgid "Filament-Saving Mode" msgstr "" @@ -16139,9 +16180,6 @@ msgstr "" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "" - msgid "Skip Objects" msgstr "" diff --git a/bbl/i18n/cs/BambuStudio_cs.po b/bbl/i18n/cs/BambuStudio_cs.po index dde3fbde36..c4381010b3 100644 --- a/bbl/i18n/cs/BambuStudio_cs.po +++ b/bbl/i18n/cs/BambuStudio_cs.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: Jakub Hencl \n" "Language-Team: \n" @@ -3181,12 +3181,12 @@ msgstr "Orientování" msgid "Filling" msgstr "Vyplňování" -msgid "Bed filling canceled." -msgstr "Plnění podložky bylo zrušeno." - msgid "Bed filling done." msgstr "Plnění podložky dokončeno." +msgid "Bed filling canceled." +msgstr "Plnění podložky bylo zrušeno." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3861,6 +3861,9 @@ msgstr "Přetečení zásobníku" msgid "Running post-processing scripts" msgstr "Spouštění post-processing skriptů" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "Skript pro následné zpracování byl úspěšně proveden." @@ -4601,6 +4604,9 @@ msgstr "Šířka linie" msgid "Fan Speed" msgstr "Rychlost ventilátoru" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Tok" @@ -4676,6 +4682,9 @@ msgstr "Rychlost (mm/s)" msgid "Fan Speed (%)" msgstr "Rychlost ventilátoru (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Teplota (°C)" @@ -4829,6 +4838,9 @@ msgstr "Čas vrstvy: " msgid "Fan Speed: " msgstr "Rychlost ventilátoru: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Teplota: " @@ -4912,6 +4924,9 @@ msgstr "Kolečko myši:" msgid "Increase/decrease edit area" msgstr "Zvětšit/zmenšit editační oblast" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sekvence" @@ -5324,6 +5339,9 @@ msgstr "Více zařízení" msgid "Project" msgstr "Projekt" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Ano" @@ -5466,6 +5484,9 @@ msgstr "Pohled zprava" msgid "Isometric View" msgstr "Izometrický pohled" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "Spustit nové okno" @@ -5490,9 +5511,6 @@ msgstr "Uložit aktuální projekt do souboru" msgid "Save Project as" msgstr "Uložit projekt jako" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Uložit aktuální projekt jako" @@ -6606,6 +6624,18 @@ msgstr "%s varování" msgid "%s has a warning" msgstr "%s má varování" +msgid "Collapse" +msgstr "Sbalit" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Spustit" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s info" @@ -7283,9 +7313,6 @@ msgstr "" msgid "Restore" msgstr "Obnovit" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "V aktuálním souboru 3mf je přítomen skript G-kódu, ověřte prosím obsah skriptu." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "Teplota vyhřívané podložky je aktuálně poměrně vysoká. Při tisku tohoto filamentu v uzavřeném prostoru může dojít k ucpání trysky. Otevřete prosím přední dveře a/nebo odstraňte horní sklo." @@ -7365,6 +7392,12 @@ msgstr "Název komponent uvnitř STEP souboru není ve formátu UTF8!" msgid "The name may show garbage characters!" msgstr "Název může zobrazovat neplatné znaky!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Nepodařilo se načíst soubor „%1%“. Byla zjištěna neplatná konfigurace." @@ -7916,6 +7949,11 @@ msgstr "Důvod: \"%1%\" a jiná část nemají průnik." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Byly zjištěny negativní části. Chcete před exportem provést booleovskou operaci se sítí?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -7977,6 +8015,11 @@ msgstr "Neplatné číslo" msgid "Plate Settings" msgstr "Nastavení podložky" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Věž pro oddělení trysky:" @@ -8829,6 +8872,10 @@ msgstr "Chybový kód" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Filament %s neodpovídá filamentu ve slotu AMS %s. Aktualizujte firmware tiskárny pro podporu přiřazení slotu AMS." @@ -9115,9 +9162,6 @@ msgstr "Nastavte dynamickou kalibraci toku na 'VYPNUTO', abyste mohli zadat vlas msgid "This printer does not support printing all plates" msgstr "Tato tiskárna nepodporuje tisk na všech podložkách." -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Aktuální firmware podporuje maximálně 16 materiálů. Počet materiálů můžete na stránce Příprava snížit na 16 nebo méně, nebo zkuste provést aktualizaci firmwaru. Pokud bude omezení přetrvávat i po aktualizaci, vyčkejte prosím na další podporu firmwaru." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Zkontrolujte, zda požadovaný průměr trysky a průtok odpovídají aktuálnímu zobrazení." @@ -10440,6 +10484,9 @@ msgstr "Pohled kamery – pravý" msgid "Camera view - Isometric" msgstr "Pohled kamery – izometrický" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12603,6 +12650,12 @@ msgstr "Objem materiálu potřebný k předplnění extruderu na věži, bez vý msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Objem materiálu potřebný k předplnění extruderu při výměně hotendu na věži." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Chlazení stírací věže" @@ -15268,9 +15321,6 @@ msgstr "Vybrané části" msgid "Keep original models" msgstr "Ponechat původní modely" -msgid "Execute" -msgstr "Spustit" - msgid "Entity Only" msgstr "Pouze entita" @@ -15794,9 +15844,6 @@ msgstr "Upravit přednastavení" msgid "For more information, please check out Wiki" msgstr "Pro více informací navštivte Wiki." -msgid "Collapse" -msgstr "Sbalit" - msgid "Daily Tips" msgstr "Denní tipy" @@ -16441,12 +16488,6 @@ msgstr "Seskupení filamentů" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "Už mi to nepřipomínat" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Žádné další vyskakovací okno se nezobrazí. Můžete jej znovu otevřít v 'Předvolby'" - msgid "Filament-Saving Mode" msgstr "Režim úspory filamentu" @@ -16504,9 +16545,6 @@ msgstr " pro nastavení počtu trysek" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Metoda seskupování filamentů pro aktuální podložku je určena volbou v rozbalovací nabídce u tlačítka řezání podložky." - msgid "Skip Objects" msgstr "Přeskočit objekty" @@ -17206,6 +17244,24 @@ msgid "" "Less babysitting, more predictable output. Example: a small farm running PETG parts avoids 'fail at hour 6' surprises and keeps batches on schedule." msgstr "" +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "V aktuálním souboru 3mf je přítomen skript G-kódu, ověřte prosím obsah skriptu." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Aktuální firmware podporuje maximálně 16 materiálů. Počet materiálů můžete na stránce Příprava snížit na 16 nebo méně, nebo zkuste provést aktualizaci firmwaru. Pokud bude omezení přetrvávat i po aktualizaci, vyčkejte prosím na další podporu firmwaru." + +#~ msgid "Don't remind me again" +#~ msgstr "Už mi to nepřipomínat" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Žádné další vyskakovací okno se nezobrazí. Můžete jej znovu otevřít v 'Předvolby'" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Metoda seskupování filamentů pro aktuální podložku je určena volbou v rozbalovací nabídce u tlačítka řezání podložky." + #, c-format, boost-format #~ msgid "Left nozzle: %smm" #~ msgstr "Levá tryska: %smm" diff --git a/bbl/i18n/de/BambuStudio_de.po b/bbl/i18n/de/BambuStudio_de.po index f190309d03..d912752f1f 100644 --- a/bbl/i18n/de/BambuStudio_de.po +++ b/bbl/i18n/de/BambuStudio_de.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -119,22 +119,22 @@ msgid "auxiliary hotend" msgstr "Nebenhotend" msgid "Left Hotend" -msgstr "" +msgstr "Linkes Hotend" msgid "Left hotend" -msgstr "" +msgstr "Linkes Hotend" msgid "left hotend" -msgstr "" +msgstr "linkes Hotend" msgid "Right Hotend" -msgstr "" +msgstr "Rechtes Hotend" msgid "Right hotend" -msgstr "" +msgstr "Rechtes Hotend" msgid "right hotend" -msgstr "" +msgstr "rechtes Hotend" msgid "main" msgstr "Haupt" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "So laden Sie TPU-Filament." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Zuführen von TPU-Filament beim X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "Die Verwendung von Filamenten, die nicht von Bambu stammen, kann zu Problemen bei der Druckqualität führen." @@ -473,7 +473,7 @@ msgstr "Version" #, c-format, boost-format msgid "Used Time: %s" -msgstr "Verwendete Zeit: %s" +msgstr "Nutzungszeit: %s" msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." msgstr "Dynamische Düsen sind auf der aktuellen Platte zugewiesen. Die Auswahl des Hotends wird nicht unterstützt." @@ -2657,7 +2657,7 @@ msgid "Assembly" msgstr "Zusammenbau" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "Die Verwendung einer variablen Schichthöhe zusammen mit einer Mischfarben-Subschicht kann zu einer schlechten Qualität der Farbmischung führen." msgid "Cut Connectors information" msgstr "Schnittverbinder Informationen" @@ -3043,7 +3043,7 @@ msgstr "Links (Aux)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "Links(Heizung)" msgctxt "air_duct" msgid "Chamber" @@ -3180,12 +3180,12 @@ msgstr "Ausrichten" msgid "Filling" msgstr "Füllung" -msgid "Bed filling canceled." -msgstr "Bettfüllung abgebrochen." - msgid "Bed filling done." msgstr "Bettfüllung fertig." +msgid "Bed filling canceled." +msgstr "Bettfüllung abgebrochen." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3866,6 +3866,9 @@ msgstr "Stapelüberlauf" msgid "Running post-processing scripts" msgstr "Ausführen von Nachbearbeitungsskripten" +msgid "Updating preview with post-processed G-code" +msgstr "Vorschau wird mit nachbearbeitetem G-Code aktualisiert" + msgid "Successfully executed post-processing script" msgstr "Nachbearbeitungsskript erfolgreich ausgeführt" @@ -4613,6 +4616,9 @@ msgstr "Linienbreite" msgid "Fan Speed" msgstr "Lüftergeschwindigkeit" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Fluss" @@ -4688,6 +4694,9 @@ msgstr "Geschwindigkeit (mm/s)" msgid "Fan Speed (%)" msgstr "Lüftergeschwindigkeit (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatur (°C)" @@ -4841,6 +4850,9 @@ msgstr "Schichtzeit: " msgid "Fan Speed: " msgstr "Lüftergeschwindigkeit: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatur: " @@ -4924,6 +4936,9 @@ msgstr "Mausrad:" msgid "Increase/decrease edit area" msgstr "Bearbeitungsbereich vergrößern/verkleinern" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Reihenfolge" @@ -5068,14 +5083,14 @@ msgid "Select Plate" msgstr "Druckplatte wählen" msgid "Change camera perspective" -msgstr "" +msgstr "Kameraperspektive ändern" msgid "Go to Wiki" msgstr "Zum Wiki gehen" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "Aktuelle Aufbaurate: %1%%%, Volumenrate: %2%%%" msgctxt "Camera" msgid "Top" @@ -5137,7 +5152,7 @@ msgid "Size:" msgstr "Größe:" msgid "Isolated objects detected" -msgstr "" +msgstr "Isolierte Objekte erkannt" msgid "Click to move them closer to the main body." msgstr "Klicken Sie, um sie näher an den Hauptkörper zu bewegen." @@ -5338,6 +5353,9 @@ msgstr "Mehrere Geräte" msgid "Project" msgstr "Projekt" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Ja" @@ -5480,6 +5498,9 @@ msgstr "Ansicht von rechts" msgid "Isometric View" msgstr "Isometrische Ansicht" +msgid "Fit Camera" +msgstr "Kamera anpassen" + msgid "Start a new window" msgstr "Neues Fenster starten" @@ -5504,9 +5525,6 @@ msgstr "Aktuelles Projekt in Datei speichern" msgid "Save Project as" msgstr "Projekt speichern als" -msgid "Shift+" -msgstr "Umschalttaste+" - msgid "Save current project as" msgstr "Aktuelles Projekt speichern als" @@ -6622,6 +6640,18 @@ msgstr "%s Warnung" msgid "%s has a warning" msgstr "%s hat eine Warnung" +msgid "Collapse" +msgstr "Minimieren" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Ausführen" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s Info" @@ -6917,10 +6947,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "Überprüft die Druckplatte zu Beginn eines Drucks auf Objekte, um Kollisionen zu vermeiden." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "Erkennung von Bauteilverschiebung" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "Überwacht das Bauteil während des Drucks und warnt sofort, falls es sich verschiebt oder umfällt." msgid "Ensures the build plate type and placement are correct." msgstr "Stellt sicher, dass der Typ und die Platzierung der Druckplatte korrekt sind." @@ -7104,7 +7134,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Filament(e) mit hoher Schrumpfung erkannt: %s. Diese Materialien können nach dem Abkühlen zu Maßabweichungen führen. Wenn Ihr Modell eine präzise Passung oder Montage erfordert, lesen Sie bitte die Wiki-Anleitung für Schrumpfungstests." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "Das Drucken von gemischtfarbigem Filament auf einem Drucker mit einem einzelnen Extruder erfordert häufige Filamentwechsel und Spülungen, was den Abfall und das Risiko einer Verstopfung der Düse / des Auswurfschachts erheblich erhöhen kann." #, boost-format msgid " plate %1%: " @@ -7249,13 +7279,13 @@ msgid "Remove last mixed filament" msgstr "Letztes gemischtes Filament entfernen" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "Gemischtes Filament hat ungültige oder nicht übereinstimmende Komponenten. Bitte bearbeiten Sie die betroffenen Einträge erneut." msgid "Search plate, object and part." msgstr "Suche Platte, Objekt und Teil." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "Das gemischte Ziel-Filament verwendet dieses physische Filament als Komponente. Beim Zusammenführen wird dieses physische Filament entfernt und das gemischte Filament möglicherweise ungültig. Fortfahren?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7281,7 +7311,7 @@ msgid "Mixed filament has broken component references" msgstr "Gemischtes Filament hat fehlerhafte Komponentenreferenzen" msgid "Edit / Delete / Merge" -msgstr "" +msgstr "Bearbeiten / Löschen / Zusammenführen" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7303,9 +7333,6 @@ msgstr "" msgid "Restore" msgstr "Wiederherstellen" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "In der aktuellen 3mf-Datei ist ein G-Code-Skript vorhanden. Bitte überprüfen Sie den Inhalt des Skripts." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7385,6 +7412,12 @@ msgstr "Namen der Komponenten in der Step-Datei sind nicht im UTF8-Format!" msgid "The name may show garbage characters!" msgstr "Aufgrund der nicht unterstützten Textkodierung können unbrauchbare Zeichen erscheinen!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Das Laden der Datei \"%1%\" ist fehlgeschlagen. Es wurde eine ungültige Konfiguration erkannt." @@ -7924,9 +7957,11 @@ msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." msgstr "" +"Exportieren der geslicten Datei fehlgeschlagen.\n" +"Bitte prüfen Sie, ob die Datei von einem anderen Programm verwendet wird oder ob genügend Speicherplatz vorhanden ist." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "Geslicte Datei exportieren" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7960,9 +7995,14 @@ msgstr "Grund: \"%1%\" und ein anderes Teil haben keine Überschneidung." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Negative Teile erkannt. Möchten Sie vor dem Exportieren eine Boolesche Analyse des Netzes durchführen?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "Das Kalibrierungs-Filament ist derzeit einem anderen Extruder zugewiesen als dem, der im PA-Kalibrierungsdialog (%s) ausgewählt wurde. Dies kann zu falschen Kalibrierungsergebnissen führen. Sie können die Zuweisung in den Filament-Gruppierungseinstellungen ändern." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "Es wird nicht empfohlen, PVA-Filamente mit 0,2mm Düsen zu verwenden." @@ -8021,6 +8061,11 @@ msgstr "Ungültige Nummer" msgid "Plate Settings" msgstr "Platteneinstellungen" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Reinigungsturm:" @@ -8282,7 +8327,7 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "Wenn diese Option aktiviert ist, wird das zuletzt verwendete Farbschema (z. B. Linientyp, Geschwindigkeit) beim nächsten Start automatisch angewendet." msgid "Display overview" -msgstr "" +msgstr "Übersicht anzeigen" msgid "Show assembly BVH primary bounds" msgstr "Primäre BVH-Begrenzungen der Baugruppe anzeigen" @@ -8634,7 +8679,7 @@ msgid "First layer filament sequence" msgstr "Filamentsequenz der ersten Schicht" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "Die Filamentliste enthält gemischte Filamente. Die benutzerdefinierte Filamentreihenfolge wird nicht wirksam." msgid "Same as Global Bed Type" msgstr "Wie globaler Betttyp" @@ -8873,6 +8918,10 @@ msgstr "Fehlercode" msgid "Recommended filament arrangement saves %s->" msgstr "Empfohlene Filamentanordnung spart %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Filament %s stimmt nicht mit dem Filament in AMS-Slot %s überein. Bitte aktualisieren Sie die Druckerfirmware, um die AMS-Slot-Zuordnung zu unterstützen." @@ -9046,7 +9095,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "Der aktuelle Düsendurchmesser (%.1fmm) stimmt nicht mit der Slicing-Datei (%.1fmm) überein. Bitte stellen Sie sicher, dass die installierte Düse mit den Einstellungen im Drucker übereinstimmt, und stellen Sie dann beim Slicen das entsprechende Druckerprofil ein." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "Die am Drucker installierte Filamentweiche stimmt nicht mit der Slicing-Datei überein. Bitte neu slicen, um Probleme mit der Druckqualität zu vermeiden." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "Dieser Druck erfordert eine Filamentweiche. Bitte installieren Sie diese zuerst." @@ -9161,9 +9210,6 @@ msgstr "Stellen Sie die dynamische Flusskalibrierung auf „AUS“, um einen ben msgid "This printer does not support printing all plates" msgstr "Dieser Drucker unterstützt nicht den Druck aller Platten" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Die aktuelle Firmware unterstützt maximal 16 Materialien. Sie können die Anzahl der Materialien auf der Vorbereitungsseite auf 16 oder weniger reduzieren oder versuchen, die Firmware zu aktualisieren. Wenn Sie auch nach dem Update eingeschränkt sind, warten Sie bitte auf zukünftige Firmware-Unterstützung." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Bitte überprüfen Sie, ob der erforderliche Düsendurchmesser und die Durchflussrate mit der aktuellen Anzeige übereinstimmen." @@ -9425,7 +9471,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "Wenn %s als Support für %s verwendet wird, empfehlen wir folgende Einstellungen:" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "Wenn PLA zum Stützen von TPU verwendet wird, empfehlen wir die folgenden Einstellungen:" @@ -10494,6 +10540,9 @@ msgstr "Kameraansicht – Rechts" msgid "Camera view - Isometric" msgstr "Kameraansicht – Isometrisch" +msgid "Camera view - Fit to scene or selection" +msgstr "Kameraansicht - An Szene oder Auswahl anpassen" + msgid "Shift+E" msgstr "" @@ -12675,6 +12724,12 @@ msgstr "Das Materialvolumen, das zum Vorbereiten des Extruders am Turm erforderl msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Das Materialvolumen, das erforderlich ist, um den Extruder für einen Hotend-Wechsel am Turm vorzubereiten." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Reinigungsturm Kühlung" @@ -14974,7 +15029,7 @@ msgstr "" "- Verschiedene Filamentmarken und -familien (Marke = Bambu, Familie = Basic, Matte)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux) unterstützt keine automatische Flusskalibrierung." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "Hinweis: Die Nummer des Hotends ist an den Halter gebunden. Wenn das Hotend in einen neuen Halter eingesetzt wird, wird seine Nummer automatisch aktualisiert.\n" @@ -15118,7 +15173,7 @@ msgid "PA Calibration" msgstr "PA-Kalibrierung" msgid "Extruder type" -msgstr "" +msgstr "Extrudertyp" msgid "PA Tower" msgstr "PA-Turm" @@ -15352,9 +15407,6 @@ msgstr "Ausgewählte Teile" msgid "Keep original models" msgstr "Originalmodelle beibehalten" -msgid "Execute" -msgstr "Ausführen" - msgid "Entity Only" msgstr "Nur Objekt" @@ -15871,9 +15923,6 @@ msgstr "Profil bearbeiten" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Minimieren" - msgid "Daily Tips" msgstr "Tägliche Tipps" @@ -16518,12 +16567,6 @@ msgstr "Filamentgruppierung" msgid "Fila Saving" msgstr "Filament-Einsparung" -msgid "Don't remind me again" -msgstr "Nicht mehr erinnern" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Es wird kein weiteres Popup-Fenster erscheinen. Sie können dies in den \"Einstellungen\" aktualisieren" - msgid "Filament-Saving Mode" msgstr "Filament-Sparmodus" @@ -16581,9 +16624,6 @@ msgstr " um die Düsenanzahl festzulegen" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Generiert eine Filamentgruppierung für %s und %s basierend auf der Druckqualität, wobei die Druckqualität Vorrang vor der Filamenteinsparung hat" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Die Methode zur Gruppierung der Filamente für die aktuelle Platte wird durch die Dropdown-Option auf der Schaltfläche „Platte Slicen“ bestimmt." - msgid "Skip Objects" msgstr "Objekte überspringen" @@ -16965,59 +17005,59 @@ msgid "Print Outcome: " msgstr "Druckergebnis: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Gemischtes Filament bearbeiten" msgid "Effect Preview" -msgstr "" +msgstr "Effektvorschau" msgid "Select Mixed Materials" -msgstr "" +msgstr "Gemischte Materialien auswählen" msgid "+ Add Material" -msgstr "" +msgstr "+ Material hinzufügen" msgid "- Delete Material" -msgstr "" +msgstr "- Material löschen" msgid "Ratio" -msgstr "" +msgstr "Verhältnis" msgid "Gradient Effect" -msgstr "" +msgstr "Verlaufseffekt" msgid "Mixing Recommendations" -msgstr "" +msgstr "Mischempfehlungen" msgid "-- Select --" -msgstr "" +msgstr "-- Auswählen --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "Der Verlaufseffekt erfordert, dass die 'Mischfarben-Subschicht' aktiviert ist. Möchten Sie diese jetzt aktivieren?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Mischfarben-Subschicht" #, c-format, boost-format msgid "Slot %s (%s)" msgstr "" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "können nicht gemischt werden. Bitte wählen Sie den gleichen Filamenttyp aus." msgid "Please select a filament for all components" -msgstr "" +msgstr "Bitte wählen Sie ein Filament für alle Komponenten aus" msgid "Cannot mix different filament types" -msgstr "" +msgstr "Unterschiedliche Filamenttypen können nicht gemischt werden" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Maximal 3 Materialien zum Mischen" msgid "Maximum number of components reached" -msgstr "" +msgstr "Maximale Anzahl an Komponenten erreicht" msgid "Remove the third material" -msgstr "" +msgstr "Entfernen Sie das dritte Material" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17307,6 +17347,24 @@ msgstr "" "Zuverlässigkeit auf Anhieb\n" "Weniger Überwachung, vorhersagbarere Ausgabe. Beispiel: Eine kleine Farm, die PETG-Teile druckt, vermeidet Überraschungen wie \"Ausfall in Stunde 6\" und hält Chargen im Zeitplan." +#~ msgid "Shift+" +#~ msgstr "Umschalttaste+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "In der aktuellen 3mf-Datei ist ein G-Code-Skript vorhanden. Bitte überprüfen Sie den Inhalt des Skripts." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Die aktuelle Firmware unterstützt maximal 16 Materialien. Sie können die Anzahl der Materialien auf der Vorbereitungsseite auf 16 oder weniger reduzieren oder versuchen, die Firmware zu aktualisieren. Wenn Sie auch nach dem Update eingeschränkt sind, warten Sie bitte auf zukünftige Firmware-Unterstützung." + +#~ msgid "Don't remind me again" +#~ msgstr "Nicht mehr erinnern" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Es wird kein weiteres Popup-Fenster erscheinen. Sie können dies in den \"Einstellungen\" aktualisieren" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Die Methode zur Gruppierung der Filamente für die aktuelle Platte wird durch die Dropdown-Option auf der Schaltfläche „Platte Slicen“ bestimmt." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Links" diff --git a/bbl/i18n/en/BambuStudio_en.po b/bbl/i18n/en/BambuStudio_en.po index dbd319df16..82f004ca97 100644 --- a/bbl/i18n/en/BambuStudio_en.po +++ b/bbl/i18n/en/BambuStudio_en.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -3166,12 +3166,12 @@ msgstr "Orienting" msgid "Filling" msgstr "Filling" -msgid "Bed filling canceled." -msgstr "Bed filling canceled." - msgid "Bed filling done." msgstr "Bed filling done." +msgid "Bed filling canceled." +msgstr "Bed filling canceled." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3835,6 +3835,9 @@ msgstr "Stack overflow" msgid "Running post-processing scripts" msgstr "Running post-processing scripts" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "Successfully executed post-processing script" @@ -4569,6 +4572,9 @@ msgstr "Line Width" msgid "Fan Speed" msgstr "Fan Speed" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Flow" @@ -4644,6 +4650,9 @@ msgstr "Speed (mm/s)" msgid "Fan Speed (%)" msgstr "Fan Speed (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperature (°C)" @@ -4797,6 +4806,9 @@ msgstr "Layer Time: " msgid "Fan Speed: " msgstr "Fan Speed: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperature: " @@ -4878,6 +4890,9 @@ msgstr "Mouse wheel:" msgid "Increase/decrease edit area" msgstr "Increase/decrease edit area" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sequence" @@ -5290,6 +5305,9 @@ msgstr "Multi-device" msgid "Project" msgstr "Project" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Yes" @@ -5428,6 +5446,9 @@ msgstr "Right View" msgid "Isometric View" msgstr "" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "Start a new window" @@ -5452,9 +5473,6 @@ msgstr "Save current project to file" msgid "Save Project as" msgstr "Save Project as" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Save current project as" @@ -6564,6 +6582,18 @@ msgstr "%s warning" msgid "%s has a warning" msgstr "%s has a warning" +msgid "Collapse" +msgstr "Collapse" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s info" @@ -7236,9 +7266,6 @@ msgstr "" msgid "Restore" msgstr "Restore" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7318,6 +7345,12 @@ msgstr "Name of components inside step file is not UTF8 format!" msgid "The name may show garbage characters!" msgstr "The name may show garbage characters!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Failed loading file \"%1%\". An invalid configuration was found." @@ -7865,6 +7898,11 @@ msgstr "Reason: \"%1%\" and another part have no intersection." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Negative parts detected. Would you like to perform mesh boolean before exporting?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -7926,6 +7964,11 @@ msgstr "Invalid number" msgid "Plate Settings" msgstr "Plate Settings" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "" @@ -8762,6 +8805,10 @@ msgstr "Error code" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -9046,9 +9093,6 @@ msgstr "" msgid "This printer does not support printing all plates" msgstr "This printer does not support printing all plates" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "" @@ -10358,6 +10402,9 @@ msgstr "" msgid "Camera view - Isometric" msgstr "" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12501,6 +12548,12 @@ msgstr "" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "" @@ -15134,9 +15187,6 @@ msgstr "" msgid "Keep original models" msgstr "" -msgid "Execute" -msgstr "" - msgid "Entity Only" msgstr "Entity only" @@ -15657,9 +15707,6 @@ msgstr "Edit Preset" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Collapse" - msgid "Daily Tips" msgstr "Daily Tips" @@ -16294,12 +16341,6 @@ msgstr "" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "" - msgid "Filament-Saving Mode" msgstr "" @@ -16357,9 +16398,6 @@ msgstr "" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "" - msgid "Skip Objects" msgstr "Skip Objects" @@ -17059,6 +17097,9 @@ msgid "" "Less babysitting, more predictable output. Example: a small farm running PETG parts avoids 'fail at hour 6' surprises and keeps batches on schedule." msgstr "" +#~ msgid "Shift+" +#~ msgstr "Shift+" + #~ msgid "Assembly View" #~ msgstr "Assembly View" diff --git a/bbl/i18n/es/BambuStudio_es.po b/bbl/i18n/es/BambuStudio_es.po index bbb5ccfaf9..0221563145 100644 --- a/bbl/i18n/es/BambuStudio_es.po +++ b/bbl/i18n/es/BambuStudio_es.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "Cómo alimentar el filamento de TPU." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Cómo alimentar el filamento de TPU en X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "El uso de filamento que no sea de Bambu puede presentar problemas de calidad de impresión." @@ -2657,7 +2657,7 @@ msgid "Assembly" msgstr "Montaje" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "El uso de altura de capa variable, junto con una subcapa de color mixto, puede dar como resultado una mala calidad de mezcla de colores." msgid "Cut Connectors information" msgstr "Información sobre conectores cortados" @@ -3180,12 +3180,12 @@ msgstr "Orientando..." msgid "Filling" msgstr "Relleno" -msgid "Bed filling canceled." -msgstr "Se canceló el rellenado de la cama." - msgid "Bed filling done." msgstr "Se ha completado el rellenado de la cama." +msgid "Bed filling canceled." +msgstr "Se canceló el rellenado de la cama." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3862,6 +3862,9 @@ msgstr "Columna de Sobre Flujo" msgid "Running post-processing scripts" msgstr "Ejecución de scripts de posprocesamiento" +msgid "Updating preview with post-processed G-code" +msgstr "Actualizando vista previa con el G-code posprocesado" + msgid "Successfully executed post-processing script" msgstr "El script de posprocesamiento se ejecutó correctamente" @@ -4609,6 +4612,9 @@ msgstr "Ancho de la línea" msgid "Fan Speed" msgstr "Velocidad del ventilador" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Flujo" @@ -4684,6 +4690,9 @@ msgstr "Velocidad (mm/s)" msgid "Fan Speed (%)" msgstr "Velocidad del ventilador (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatura (°C)" @@ -4837,6 +4846,9 @@ msgstr "Tiempo de la capa: " msgid "Fan Speed: " msgstr "Velocidad del ventilador: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatura: " @@ -4920,6 +4932,9 @@ msgstr "Rueda del ratón:" msgid "Increase/decrease edit area" msgstr "Aumentar/reducir el área de edición" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Secuencia" @@ -5336,6 +5351,9 @@ msgstr "Multidispositivo" msgid "Project" msgstr "Proyecto" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Sí" @@ -5478,6 +5496,9 @@ msgstr "Vista derecha" msgid "Isometric View" msgstr "Vista isométrica" +msgid "Fit Camera" +msgstr "Ajuste la cámara" + msgid "Start a new window" msgstr "Iniciar una nueva ventana" @@ -5502,9 +5523,6 @@ msgstr "Guardar el proyecto actual en un archivo" msgid "Save Project as" msgstr "Guardar proyecto como" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Guardar el proyecto actual como" @@ -6620,6 +6638,18 @@ msgstr "%s aviso" msgid "%s has a warning" msgstr "%s tiene un aviso" +msgid "Collapse" +msgstr "Colapso" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Ejecutar" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s info" @@ -7100,7 +7130,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Filamentos de alta contracción detectados: %s. Estos materiales pueden provocar desviaciones dimensionales tras el enfriamiento. Si su modelo requiere un ajuste o ensamblaje preciso, consulte la guía Wiki para pruebas de contracción." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "La impresión con filamento de colores mezclados en una impresora de un solo extrusor requiere cambios frecuentes de filamento y purgas, lo que puede aumentar significativamente el desperdicio y el riesgo de obstrucción de la boquilla o del conducto de residuos." #, boost-format msgid " plate %1%: " @@ -7299,9 +7329,6 @@ msgstr "" msgid "Restore" msgstr "Restaurar" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "Hay un script del G-code presente en el archivo 3mf actual, verifique el contenido del script." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7381,6 +7408,12 @@ msgstr "¡El nombre de los componentes del archivo step no está en formato UTF8 msgid "The name may show garbage characters!" msgstr "¡El nombre puede mostrar caracteres basura!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Ha fallado la carga del archivo \"%1%\". Se ha encontrado una configuración no válida." @@ -7959,6 +7992,11 @@ msgstr "Motivo: %1% \"\" y otra parte no tienen intersección." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Partes negativas detectadas. ¿Desea realizar una booleana de malla antes de exportar?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "El filamento de calibración está asignado actualmente a un extrusor diferente al seleccionado en el cuadro de diálogo de calibración PA (%s). Esto puede provocar resultados de calibración incorrectos. Puede cambiar la asignación en la configuración de agrupación de filamentos." @@ -8020,6 +8058,11 @@ msgstr "Número inválido" msgid "Plate Settings" msgstr "Ajustes de placa" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Torre principal:" @@ -8874,6 +8917,10 @@ msgstr "Código de error:" msgid "Recommended filament arrangement saves %s->" msgstr "La disposición recomendada de filamentos ahorra %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "El filamento %s no coincide con el filamento de la ranura AMS %s. Actualice el firmware de la impresora para admitir la asignación de ranuras AMS." @@ -9162,9 +9209,6 @@ msgstr "Establezca la calibración de flujo dinámico en «DESACTIVADA» para ha msgid "This printer does not support printing all plates" msgstr "Esta impresora no admite la impresión de todas las planchas" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "El firmware actual admite un máximo de 16 materiales. Puede reducir la cantidad de materiales a 16, o menos, en la página de preparación o intentar actualizar el firmware. Si la restricción persiste después de la actualización, espere a que se publiquen actualizaciones de firmware." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Por favor, verifique si el diámetro de la boquilla y la tasa de flujo requeridos coinciden con la pantalla actual." @@ -10497,6 +10541,9 @@ msgstr "Vista de la cámara - Derecha" msgid "Camera view - Isometric" msgstr "Vista de la cámara - Isométrica" +msgid "Camera view - Fit to scene or selection" +msgstr "Vista de la Cámara - Ajustar a la escena o la selección" + msgid "Shift+E" msgstr "" @@ -12678,6 +12725,12 @@ msgstr "El volumen de material necesario para cebar el extrusor en la torre, exc msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "El volumen de material necesario para cebar el extrusor al cambiar el Hotend en la torre." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Enfriamiento de la torre de limpieza" @@ -15355,9 +15408,6 @@ msgstr "Piezas seleccionadas" msgid "Keep original models" msgstr "Mantener modelos originales" -msgid "Execute" -msgstr "Ejecutar" - msgid "Entity Only" msgstr "Solo Entidad" @@ -15880,9 +15930,6 @@ msgstr "Editar preajuste" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Colapso" - msgid "Daily Tips" msgstr "Consejos diarios" @@ -16527,12 +16574,6 @@ msgstr "Agrupación de filamentos" msgid "Fila Saving" msgstr "Ahorrar filamento" -msgid "Don't remind me again" -msgstr "No me lo vuelvas a recordar" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "No aparecerá ninguna otra ventana emergente. Puedes actualizarla en «Preferencias»" - msgid "Filament-Saving Mode" msgstr "Modo de ahorro de filamentos" @@ -16590,9 +16631,6 @@ msgstr " para configurar el número de boquillas" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Genere agrupaciones de filamento para %s y %s en función de la calidad de las impresiones, priorizando la calidad de impresión sobre el ahorro de filamento" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "El método de agrupamiento de filamentos para la placa actual se determina mediante la opción desplegable del botón de la placa de corte." - msgid "Skip Objects" msgstr "Omitir objetos" @@ -16974,59 +17012,59 @@ msgid "Print Outcome: " msgstr "Resultado de la impresión: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Editar el filamento mixto" msgid "Effect Preview" -msgstr "" +msgstr "Vista previa del efecto" msgid "Select Mixed Materials" -msgstr "" +msgstr "Seleccionar los materiales mixtos" msgid "+ Add Material" -msgstr "" +msgstr "+ Añadir material" msgid "- Delete Material" -msgstr "" +msgstr "- Eliminar material" msgid "Ratio" msgstr "" msgid "Gradient Effect" -msgstr "" +msgstr "Efecto del gradiente" msgid "Mixing Recommendations" -msgstr "" +msgstr "Recomendaciones para la mezcla" msgid "-- Select --" -msgstr "" +msgstr "-- Seleccionar --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "El efecto degradado requiere que la opción \"Subcapa de color mixto\" esté activada. ¿La activa ahora?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Subcapa de color mixto" #, c-format, boost-format msgid "Slot %s (%s)" -msgstr "" +msgstr "Ranura %s (%s)" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "no se pueden mezclar. Por favor, seleccione el mismo tipo de filamento." msgid "Please select a filament for all components" -msgstr "" +msgstr "Por favor, seleccione un filamento para todos los componentes" msgid "Cannot mix different filament types" -msgstr "" +msgstr "No se pueden mezclar diferentes tipos de filamento" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Máximo de 3 materiales para mezclar" msgid "Maximum number of components reached" -msgstr "" +msgstr "Número máximo de componentes alcanzado" msgid "Remove the third material" -msgstr "" +msgstr "Retire el tercer material" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17314,6 +17352,24 @@ msgstr "" "Fiabilidad a la primera\n" "Menos supervisión, resultados más predecibles. Ejemplo: una pequeña granja que procesa piezas de PETG evita sorpresas de \"fallo a la hora 6\" y mantiene los lotes según lo previsto." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "Hay un script del G-code presente en el archivo 3mf actual, verifique el contenido del script." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "El firmware actual admite un máximo de 16 materiales. Puede reducir la cantidad de materiales a 16, o menos, en la página de preparación o intentar actualizar el firmware. Si la restricción persiste después de la actualización, espere a que se publiquen actualizaciones de firmware." + +#~ msgid "Don't remind me again" +#~ msgstr "No me lo vuelvas a recordar" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "No aparecerá ninguna otra ventana emergente. Puedes actualizarla en «Preferencias»" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "El método de agrupamiento de filamentos para la placa actual se determina mediante la opción desplegable del botón de la placa de corte." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Izquierda" diff --git a/bbl/i18n/fr/BambuStudio_fr.po b/bbl/i18n/fr/BambuStudio_fr.po index bf24fc63e8..f06498e196 100644 --- a/bbl/i18n/fr/BambuStudio_fr.po +++ b/bbl/i18n/fr/BambuStudio_fr.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -47,19 +47,19 @@ msgid "auxiliary extruder" msgstr "extrudeur auxiliaire" msgid "Left Extruder" -msgstr "Extrudeuse gauche" +msgstr "Extrudeur Gauche" msgid "Left extruder" -msgstr "Extrudeur Gauche" +msgstr "Extrudeur gauche" msgid "left extruder" msgstr "extrudeur gauche" msgid "Right Extruder" -msgstr "Extrudeuse droite" +msgstr "Extrudeur Droit" msgid "Right extruder" -msgstr "Extrudeur Droit" +msgstr "Extrudeur droit" msgid "right extruder" msgstr "extrudeur droit" @@ -119,22 +119,22 @@ msgid "auxiliary hotend" msgstr "hotend auxiliaire" msgid "Left Hotend" -msgstr "" +msgstr "Hotend Gauche" msgid "Left hotend" -msgstr "" +msgstr "Hotend gauche" msgid "left hotend" -msgstr "" +msgstr "hotend gauche" msgid "Right Hotend" -msgstr "" +msgstr "Hotend Droit" msgid "Right hotend" -msgstr "" +msgstr "Hotend droit" msgid "right hotend" -msgstr "" +msgstr "hotend droit" msgid "main" msgstr "principal" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "Comment charger du filament TPU." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Comment charger du filament TPU dans la X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "L'utilisation de filaments non Bambu peut entraîner des problèmes de qualité d'impression." @@ -2657,7 +2657,7 @@ msgid "Assembly" msgstr "Assemblé" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "L'utilisation d'une hauteur de couche variable avec une sous-couche à couleurs mélangées peut entraîner une mauvaise qualité de mélange des couleurs." msgid "Cut Connectors information" msgstr "Informations sur les connecteurs de coupe" @@ -3043,7 +3043,7 @@ msgstr "Gauche (Aux)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "Gauche (En Chauffe)" msgctxt "air_duct" msgid "Chamber" @@ -3176,12 +3176,12 @@ msgstr "Orienter" msgid "Filling" msgstr "Remplissage" -msgid "Bed filling canceled." -msgstr "Remplissage de plateau annulé." - msgid "Bed filling done." msgstr "Remplissage du plateau fait." +msgid "Bed filling canceled." +msgstr "Remplissage de plateau annulé." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3856,6 +3856,9 @@ msgstr "Débordement de pile" msgid "Running post-processing scripts" msgstr "Exécution de scripts de post-traitement" +msgid "Updating preview with post-processed G-code" +msgstr "Mise à jour de l'aperçu avec le G-code post-traité" + msgid "Successfully executed post-processing script" msgstr "Script de post-traitement exécuté avec succès" @@ -4600,6 +4603,9 @@ msgstr "Largeur de ligne" msgid "Fan Speed" msgstr "Vitesse du ventilateur" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Débit" @@ -4675,6 +4681,9 @@ msgstr "Vitesse (mm/s)" msgid "Fan Speed (%)" msgstr "Vitesse Ventilateur (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Température (°C)" @@ -4828,6 +4837,9 @@ msgstr "Temps de Couche: " msgid "Fan Speed: " msgstr "Vitesse Ventilateur: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Température : " @@ -4909,6 +4921,9 @@ msgstr "Molette de la souris :" msgid "Increase/decrease edit area" msgstr "Augmenter/diminuer la zone d'édition" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Séquence" @@ -5053,14 +5068,14 @@ msgid "Select Plate" msgstr "Sélectionner la plaque" msgid "Change camera perspective" -msgstr "" +msgstr "Changer la perspective de la caméra" msgid "Go to Wiki" msgstr "Aller sur le Wiki" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "Vitesse d'assemblage actuelle : %1%%%, vitesse de volume : %2%%%" msgctxt "Camera" msgid "Top" @@ -5122,7 +5137,7 @@ msgid "Size:" msgstr "Taille:" msgid "Isolated objects detected" -msgstr "" +msgstr "Objets isolés détectés" msgid "Click to move them closer to the main body." msgstr "Cliquer pour les rapprocher du corps principal." @@ -5325,6 +5340,9 @@ msgstr "Multi-Imprimante" msgid "Project" msgstr "Projet" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Oui" @@ -5467,6 +5485,9 @@ msgstr "Vue Droite" msgid "Isometric View" msgstr "Vue isométrique" +msgid "Fit Camera" +msgstr "Ajuster Caméra" + msgid "Start a new window" msgstr "Démarrer une nouvelle fenêtre" @@ -5491,9 +5512,6 @@ msgstr "Enregistrer le projet actuel dans un fichier" msgid "Save Project as" msgstr "Enregistrer le projet sous" -msgid "Shift+" -msgstr "Maj+" - msgid "Save current project as" msgstr "Enregistrer le projet actuel sous" @@ -6609,6 +6627,18 @@ msgstr "%s avertissement" msgid "%s has a warning" msgstr "%s a un avertissement" +msgid "Collapse" +msgstr "Réduire" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Exécuter" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s infos" @@ -6900,10 +6930,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "Vérifie la présence d'objets sur le plateau d'impression au début de chaque impression afin d'éviter les collisions." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "Détection du Déplacement des Pièces Imprimées" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "Surveille la pièce imprimée pendant l'impression et alerte immédiatement en cas de déplacement ou de chute." msgid "Ensures the build plate type and placement are correct." msgstr "S'assure que le type et le positionnement du plateau d'impression sont corrects." @@ -7087,7 +7117,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Filament(s) à fort retrait détecté(s) : %s. Ces matériaux peuvent entraîner des écarts dimensionnels après refroidissement. Si votre modèle nécessite un ajustement ou un assemblage précis, veuillez consulter le guide Wiki relatif aux tests de retrait." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "L'impression de filament multicolore sur une imprimante à extrudeur unique nécessite de fréquents changements de filament et des purges, ce qui peut augmenter considérablement les déchets et le risque de bouchage de la buse / de la goulotte d'évacuation des déchets." #, boost-format msgid " plate %1%: " @@ -7232,13 +7262,13 @@ msgid "Remove last mixed filament" msgstr "Retirer le dernier mélange de filament" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "Le filament mixte contient des composants invalides ou incompatibles. Veuillez rééditer les entrées concernées." msgid "Search plate, object and part." msgstr "Recherchez une plaque, un objet ou une pièce." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "Le filament mélangé cible utilise ce filament physique comme composant. La fusion supprimera ce filament physique et pourrait invalider le filament mélangé. Continuer ?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7264,7 +7294,7 @@ msgid "Mixed filament has broken component references" msgstr "Le mélange de filaments contient des références de composants invalides" msgid "Edit / Delete / Merge" -msgstr "" +msgstr "Modifier / Supprimer / Fusionner" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7286,9 +7316,6 @@ msgstr "" msgid "Restore" msgstr "Restaurer" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "Un script G-code est présent dans le fichier 3mf actuel, veuillez vérifier le contenu du script." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7368,6 +7395,12 @@ msgstr "Le nom des composants dans le fichier .step n'est pas au format UTF8 !" msgid "The name may show garbage characters!" msgstr "Le nom peut contenir des caractères incohérents !" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Échec du chargement du fichier \"%1%\". Une configuration invalide a été trouvée." @@ -7906,9 +7939,11 @@ msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." msgstr "" +"Échec de l'exportation du fichier tranché.\n" +"Veuillez vérifier si le fichier est utilisé par un autre programme ou s'il y a suffisamment d'espace disque." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "Exporter le fichier tranché" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7942,9 +7977,14 @@ msgstr "Raison : « %1% » et une autre partie n’ont pas d’intersection." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Parties négatives détectées. Souhaitez-vous effectuer un maillage booléen avant d'exporter ?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "Le filament d'étalonnage est actuellement affecté à un extrudeur différent de celui sélectionné dans la boîte de dialogue d'étalonnage PA (%s). Cela peut entraîner des résultats d'étalonnage incorrects. Vous pouvez modifier l'affectation dans les paramètres de regroupement des filaments." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "Il n'est pas recommandé d'utiliser des filaments PVA avec des buses de 0,2 mm." @@ -8001,6 +8041,11 @@ msgstr "Numéro invalide" msgid "Plate Settings" msgstr "Paramètres de la plaque" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Tour d'Amorçage :" @@ -8262,7 +8307,7 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "Une fois activé, le dernier Mode d'Affichage utilisé (par exemple, Type de ligne, Vitesse) sera automatiquement appliqué au prochain démarrage." msgid "Display overview" -msgstr "" +msgstr "Aperçu de l'affichage" msgid "Show assembly BVH primary bounds" msgstr "Afficher les limites principales de la BVH de l’assemblage" @@ -8614,7 +8659,7 @@ msgid "First layer filament sequence" msgstr "Séquence de filament de première couche" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "La liste des filaments contient des filaments mélangés. La séquence de filament personnalisée ne prendra pas effet." msgid "Same as Global Bed Type" msgstr "Identique au type de plaque général" @@ -8853,6 +8898,10 @@ msgstr "Code erreur" msgid "Recommended filament arrangement saves %s->" msgstr "La disposition recommandée du filament permet d’économiser %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Le filament %s ne correspond pas au filament du slot AMS %s. Veuillez mettre à jour le firmware de l'imprimante pour qu'il prenne en charge l'attribution des slots AMS." @@ -9026,7 +9075,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "Le diamètre actuel de la buse (%.1fmm) ne correspond pas au fichier de découpe (%.1fmm). Veuillez vous assurer que la buse installée correspond aux paramètres de l'imprimante, puis réglez le préréglage correspondant de l'imprimante lors du tranchage." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "Le Filament Track Switch installé sur l'imprimante ne correspond pas au fichier de tranchage. Veuillez re-trancher pour éviter des problèmes de qualité d'impression." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "Cette impression nécessite un Filament Track Switch. Veuillez l'installer d'abord." @@ -9141,9 +9190,6 @@ msgstr "Régler l'étalonnage de la dynamique de débit sur \"OFF\" pour activer msgid "This printer does not support printing all plates" msgstr "Cette imprimante ne prend pas en charge l'impression de toutes les plaques" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Le firmware actuel prend en charge un maximum de 16 matériaux. Vous pouvez réduire le nombre de matériaux à 16 ou moins sur la page de préparation, ou essayer de mettre à jour le firmware. Si vous êtes toujours limité après la mise à jour, veuillez attendre un support firmware ultérieur." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Veuillez vérifier si le diamètre et le débit requis de la buse correspondent à l'affichage actuel." @@ -9405,7 +9451,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "Lors de l'utilisation de %s pour supporter le %s, nous recommandons les paramètres suivants :" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "Lors de l'utilisation de PLA pour supporter le TPU, nous recommandons les paramètres suivants :" @@ -10472,6 +10518,9 @@ msgstr "Vue caméra - Droite" msgid "Camera view - Isometric" msgstr "Vue caméra - Isométrique" +msgid "Camera view - Fit to scene or selection" +msgstr "Vue caméra - Adapter à la scène ou à la sélection" + msgid "Shift+E" msgstr "Maj+E" @@ -12653,6 +12702,12 @@ msgstr "Le volume de matériau nécessaire pour amorcer l'extrudeur sur la tour, msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Le volume de matériau nécessaire pour amorcer l'extrudeur lors d'un changement de hotend sur la tourelle." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Refroidissement de la tour de purge" @@ -14952,7 +15007,7 @@ msgstr "" "- Différentes marques et familles de filament (Marque = Bambu, Famille = Basic, Matte)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux) ne prend pas en charge l'étalonnage automatique du débit." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "- Remarque : Le numéro du Hotend est lié au support. Lorsque le Hotend est déplacé vers un nouveau support, son numéro se met automatiquement à jour.\n" @@ -15096,7 +15151,7 @@ msgid "PA Calibration" msgstr "Calibration PA" msgid "Extruder type" -msgstr "" +msgstr "Type d'extrudeur" msgid "PA Tower" msgstr "Tour PA" @@ -15330,9 +15385,6 @@ msgstr "Parties Sélectionnées" msgid "Keep original models" msgstr "Conserver les modèles originaux" -msgid "Execute" -msgstr "Exécuter" - msgid "Entity Only" msgstr "Entité uniquement" @@ -15855,9 +15907,6 @@ msgstr "Modifier Préréglage" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Réduire" - msgid "Daily Tips" msgstr "Astuces du Jour" @@ -16502,12 +16551,6 @@ msgstr "Groupement de filaments" msgid "Fila Saving" msgstr "Éco. de Filam." -msgid "Don't remind me again" -msgstr "Ne me rappelle plus" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Aucune autre fenêtre ne s'affichera. Vous pouvez la rouvrir dans les \"Préférences" - msgid "Filament-Saving Mode" msgstr "Mode Économie de Filament" @@ -16565,9 +16608,6 @@ msgstr " pour définir le nombre de buses" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Génère des groupements de filaments pour les %s et %s en fonction de la qualité des impressions, en privilégiant la qualité d'impression à l'économie de filament" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "La méthode de regroupement des filaments pour la plaque actuelle est déterminée par l'option déroulante du bouton de la plaque de tranchage." - msgid "Skip Objects" msgstr "Ignorer les Objets" @@ -16949,59 +16989,59 @@ msgid "Print Outcome: " msgstr "Résultat d'Impression : " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Modifier le Mélange de Filaments" msgid "Effect Preview" -msgstr "" +msgstr "Aperçu du Rendu" msgid "Select Mixed Materials" -msgstr "" +msgstr "Sélectionner des Matériaux Mélangés" msgid "+ Add Material" -msgstr "" +msgstr "+ Ajouter Matériau" msgid "- Delete Material" -msgstr "" +msgstr "- Supprimer Matériau" msgid "Ratio" msgstr "" msgid "Gradient Effect" -msgstr "" +msgstr "Effet Dégradé" msgid "Mixing Recommendations" -msgstr "" +msgstr "Recommandations de Mélange" msgid "-- Select --" -msgstr "" +msgstr "-- Sélectionner --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "L'effet de dégradé nécessite l'activation de l'option « Sous-calque de couleur mixte ». L'activer maintenant ?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Sous-couche Couleur Mélangée" #, c-format, boost-format msgid "Slot %s (%s)" msgstr "" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "ne peut pas être mélangé. Veuillez sélectionner le même type de filament." msgid "Please select a filament for all components" -msgstr "" +msgstr "Veuillez sélectionner un filament pour tous les composants" msgid "Cannot mix different filament types" -msgstr "" +msgstr "Impossible de mélanger différents types de filaments" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Maximum 3 matériaux pour le mélange" msgid "Maximum number of components reached" -msgstr "" +msgstr "Nombre maximum de composants atteint" msgid "Remove the third material" -msgstr "" +msgstr "Supprimer le troisième matériau" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17291,6 +17331,24 @@ msgstr "" "Fiabilité Garantie du Premier Coup\n" "Moins de surveillance, une production plus prévisible. Exemple : une petite exploitation agricole produisant des pièces en PETG évite les mauvaises surprises \"panne au bout de 6 h\" et respecte les délais de production." +#~ msgid "Shift+" +#~ msgstr "Maj+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "Un script G-code est présent dans le fichier 3mf actuel, veuillez vérifier le contenu du script." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Le firmware actuel prend en charge un maximum de 16 matériaux. Vous pouvez réduire le nombre de matériaux à 16 ou moins sur la page de préparation, ou essayer de mettre à jour le firmware. Si vous êtes toujours limité après la mise à jour, veuillez attendre un support firmware ultérieur." + +#~ msgid "Don't remind me again" +#~ msgstr "Ne me rappelle plus" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Aucune autre fenêtre ne s'affichera. Vous pouvez la rouvrir dans les \"Préférences" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "La méthode de regroupement des filaments pour la plaque actuelle est déterminée par l'option déroulante du bouton de la plaque de tranchage." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Gauche" diff --git a/bbl/i18n/hu/BambuStudio_hu.po b/bbl/i18n/hu/BambuStudio_hu.po index 1ffbcd92bd..10bee7e0bd 100644 --- a/bbl/i18n/hu/BambuStudio_hu.po +++ b/bbl/i18n/hu/BambuStudio_hu.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -119,22 +119,22 @@ msgid "auxiliary hotend" msgstr "segédhotend" msgid "Left Hotend" -msgstr "" +msgstr "Bal hotend" msgid "Left hotend" -msgstr "" +msgstr "Bal hotend" msgid "left hotend" -msgstr "" +msgstr "bal hotend" msgid "Right Hotend" -msgstr "" +msgstr "Jobb hotend" msgid "Right hotend" -msgstr "" +msgstr "Jobb hotend" msgid "right hotend" -msgstr "" +msgstr "jobb hotend" msgid "main" msgstr "fő" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "TPU filament betöltése." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "TPU filament betöltése az X2D-be." msgid "Using non-bambu filament may have printing quality issues." msgstr "Nem Bambu filament használata nyomtatási minőségi problémákat okozhat." @@ -2657,7 +2657,7 @@ msgid "Assembly" msgstr "Összeállítás" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "A változó rétegmagasság és a színkevert alréteg együttes használata rossz színkeverési minőséget eredményezhet." msgid "Cut Connectors information" msgstr "Összekötési információk kivágása" @@ -3043,7 +3043,7 @@ msgstr "Bal(Aux)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "Bal(fűtés)" msgctxt "air_duct" msgid "Chamber" @@ -3180,12 +3180,12 @@ msgstr "Orientáció" msgid "Filling" msgstr "Kitöltés" -msgid "Bed filling canceled." -msgstr "Asztal feltöltése megszakítva." - msgid "Bed filling done." msgstr "Asztal feltöltve." +msgid "Bed filling canceled." +msgstr "Asztal feltöltése megszakítva." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3862,6 +3862,9 @@ msgstr "Verem túlcsordulás" msgid "Running post-processing scripts" msgstr "Utófeldolgozási szkriptek futtatása" +msgid "Updating preview with post-processed G-code" +msgstr "Előnézet frissítése a feldolgozott G-kóddal" + msgid "Successfully executed post-processing script" msgstr "Utófeldolgozási szkriptek sikeresen végrehajtva" @@ -4609,6 +4612,9 @@ msgstr "Vonalszélesség" msgid "Fan Speed" msgstr "Ventilátor fordulatszám" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Anyagáramlás" @@ -4684,6 +4690,9 @@ msgstr "Sebesség (mm/mp)" msgid "Fan Speed (%)" msgstr "Ventilátor fordulatszám (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Hőmérséklet (°C)" @@ -4837,6 +4846,9 @@ msgstr "Rétegidő: " msgid "Fan Speed: " msgstr "Ventilátor fordulatszám: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Hőmérséklet: " @@ -4920,6 +4932,9 @@ msgstr "Egérgörgő:" msgid "Increase/decrease edit area" msgstr "Szerkesztési terület növelése/csökkentése" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sorrend" @@ -5064,14 +5079,14 @@ msgid "Select Plate" msgstr "Tálca kiválasztása" msgid "Change camera perspective" -msgstr "" +msgstr "Kameraperspektíva módosítása" msgid "Go to Wiki" msgstr "Tovább a Wikihez" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "Jelenlegi összeszerelési sebesség: %1%%%, térfogati sebesség: %2%%%" msgctxt "Camera" msgid "Top" @@ -5133,7 +5148,7 @@ msgid "Size:" msgstr "Méret:" msgid "Isolated objects detected" -msgstr "" +msgstr "Izolált objektumok észlelve" msgid "Click to move them closer to the main body." msgstr "Kattints a fő testhez való közelebb húzásához." @@ -5336,6 +5351,9 @@ msgstr "Multi-eszköz" msgid "Project" msgstr "Projekt" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Igen" @@ -5478,6 +5496,9 @@ msgstr "Jobb nézet" msgid "Isometric View" msgstr "Izometrikus nézet" +msgid "Fit Camera" +msgstr "Kamera illesztése" + msgid "Start a new window" msgstr "Új ablak nyitása" @@ -5502,9 +5523,6 @@ msgstr "Jelenlegi projekt mentése egy fájlba" msgid "Save Project as" msgstr "Projekt mentése másként" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Jelenlegi projekt mentése másként" @@ -6620,6 +6638,18 @@ msgstr "%s figyelmeztetés" msgid "%s has a warning" msgstr "%s figyelmeztetést tartalmaz" +msgid "Collapse" +msgstr "Összecsuk" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Végrehajtás" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s infó" @@ -6913,10 +6943,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "A nyomtatás kezdetén ellenőrzi, hogy nincsenek-e tárgyak a nyomtatótálcán az ütközések elkerülése érdekében." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "Nyomtatott tárgy elmozdulásának érzékelése" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "Nyomtatás közben figyeli a nyomtatott tárgyat, és azonnal figyelmeztet, ha az elmozdul vagy összedől." msgid "Ensures the build plate type and placement are correct." msgstr "Biztosítja, hogy a tálca típusa és elhelyezése megfelelő legyen." @@ -7100,7 +7130,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Nagy zsugorodású filament(ek) észlelve: %s. Ezek az anyagok lehűlés után méretbeli eltérést okozhatnak. Ha a modell precíz illesztést vagy összeszerelést igényel, kérjük, tekintsd meg a Wiki-útmutatót a zsugorodás tesztelésével kapcsolatban." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "A vegyes színű filament nyomtatása egy extruderes nyomtatón gyakori filamentcserét és öblítést igényel, ami jelentősen megnövelheti a keletkező hulladék mennyiségét és a fúvóka / kidobónyílás eltömődésének kockázatát." #, boost-format msgid " plate %1%: " @@ -7245,13 +7275,13 @@ msgid "Remove last mixed filament" msgstr "Az utolsó vegyes filament eltávolítása" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "Érvénytelen vegyes filament vagy nem egyező összetevők. Kérjük, módosítsd az érintett elemeket." msgid "Search plate, object and part." msgstr "Tálca, objektum és tárgy keresése." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "A megcélzott vegyes filament ezt a fizikai filamentet használja komponensként. Az egyesítés eltávolítja ezt a fizikai filamentet, és érvénytelenítheti a vegyes filamentet. Folytatod?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7277,7 +7307,7 @@ msgid "Mixed filament has broken component references" msgstr "A vegyes filament hibás komponenshivatkozásokat tartalmaz" msgid "Edit / Delete / Merge" -msgstr "" +msgstr "Szerkesztés / Törlés / Egyesítés" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7299,9 +7329,6 @@ msgstr "" msgid "Restore" msgstr "Visszaállítás" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "A jelenlegi 3mf fájl tartalmaz G-kód szkriptet, kérjük, ellenőrizd a szkript tartalmát." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7381,6 +7408,12 @@ msgstr "A STEP fájlon belüli komponens neve nem UTF-8 formátumban van!" msgid "The name may show garbage characters!" msgstr "A névben helytelen karakterek jelenhetnek meg!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Nem sikerült betölteni \"%1%\" fájlt. Érvénytelen konfiguráció." @@ -7918,9 +7951,11 @@ msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." msgstr "" +"Nem sikerült exportálni a szeletelt fájlt.\n" +"Ellenőrizd, hogy a fájlt nem használja-e egy másik program, vagy van-e elég szabad lemezterület." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "Szeletelt fájl exportálása" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7954,9 +7989,14 @@ msgstr "Ok: %1% és egy másik tárgy nem metszik egymást." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Negatív tárgyakat észleltünk. Exportálás előtt szeretnéd végrehajtani a logikai műveletet a hálón?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "A kalibrációs filament jelenleg egy másik extruderhez van hozzárendelve, mint amelyiket a PA kalibrációs ablakban kiválasztottál (%s). Ez helytelen kalibrációs eredményekhez vezethet. A hozzárendelést a filament csoportosítási beállításaiban módosíthatod." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "Nem ajánlott a PVA filament használata 0,2 mm-es fúvókával." @@ -8015,6 +8055,11 @@ msgstr "Érvénytelen szám" msgid "Plate Settings" msgstr "Tálcabeállítások" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Törlőtorony" @@ -8276,7 +8321,7 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "Ha engedélyezve van, a legutóbb használt színséma (pl. vonaltípus, sebesség) kerül automatikusan alkalmazásra a következő indításkor." msgid "Display overview" -msgstr "" +msgstr "Megjelenítés áttekintése" msgid "Show assembly BVH primary bounds" msgstr "Térfogat hierarchia megjelenítése" @@ -8628,7 +8673,7 @@ msgid "First layer filament sequence" msgstr "Kezdőréteg filament sorrendje" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "A filamentlista vegyes filamenteket tartalmaz. Az egyéni filament-sorrend nem lép érvénybe." msgid "Same as Global Bed Type" msgstr "Ugyanaz, mint a globális tálca típusa" @@ -8867,6 +8912,10 @@ msgstr "Hibakód" msgid "Recommended filament arrangement saves %s->" msgstr "Az ajánlott filamentelrendezéssel elérhető megtakarítás %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "%s filament típusa nem egyezik a(z) %s AMS-férőhelyben találhatóval. Kérjük, frissítsd a nyomtató szoftverét az AMS-kiosztás támogatásához." @@ -9040,7 +9089,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "A jelenlegi fúvókaátmérő (%.1f mm) nem egyezik a szeletelt fájlban megadott értékkel (%.1f mm). Kérjük, ellenőrizd, hogy a beszerelt fúvóka megfelel-e a nyomtató beállításainak, majd szeleteléskor használd a megfelelő nyomtatóbeállítást." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "A nyomtatóra szerelt filamentváltó nem egyezik a szeletelt fájlban megadott értékkel. Kérjük, szeleteld újra a fájlt a nyomtatási minőségi problémák elkerülése érdekében." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "Ez a nyomtatás filamentváltót igényel. Kérjük, először telepítsd." @@ -9155,9 +9204,6 @@ msgstr "Az egyéni dinamikus áramlási értékek engedélyezéséhez állítsd msgid "This printer does not support printing all plates" msgstr "Ez a nyomtató nem támogatja az összes tálcára való nyomtatást" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "A jelenlegi firmware maximum 16 anyagot támogat. Vagy csökkentsd az anyagok számát 16-ra (vagy kevesebbre) az Előkészítés oldalon, vagy próbáld meg frissíteni a firmware-t. Ha a frissítés után sem tudsz több filamentet használni, kérjük várj a következő firmware-verzióra." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Kérjük, ellenőrizd, hogy a fúvókaátmérő és áramlási sebesség megegyezik-e a kijelzőn lévővel." @@ -9417,7 +9463,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "Amikor %s-t használsz %s támaszanyagaként, a következő beállításokat javasoljuk:" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "Ha PLA-t használsz TPU-támaszként, a következő beállításokat javasoljuk:" @@ -10486,6 +10532,9 @@ msgstr "Kameranézet - Jobb" msgid "Camera view - Isometric" msgstr "Kameranézet - Izometrikus" +msgid "Camera view - Fit to scene or selection" +msgstr "Kameranézet – Jelenethez vagy kijelöléshez igazítás" + msgid "Shift+E" msgstr "" @@ -12667,6 +12716,12 @@ msgstr "Az extruder átöblítéséhez szükséges anyagmennyiség, a hotend cse msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Az extruder átöblítéséhez szükséges anyagmennyiség a hotend cseréjekor." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Törlőtorony hűtés" @@ -14966,7 +15021,7 @@ msgstr "" "- Különböző márkájú és típusú filamentek (Márka = Bambu, Típus = Basic, Matte stb.)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux) nem támogatja az automatikus áramláskalibrálást." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "- Megjegyzés: A hotend száma a tartóhoz van rendelve. Amikor a hotendet áthelyezed egy új tartóra, a száma automatikusan frissül.\n" @@ -15110,7 +15165,7 @@ msgid "PA Calibration" msgstr "PA kalibrálás" msgid "Extruder type" -msgstr "" +msgstr "Extruder típusa" msgid "PA Tower" msgstr "PA-torony" @@ -15344,9 +15399,6 @@ msgstr "Kijelölt tárgyak" msgid "Keep original models" msgstr "Eredeti modellek megtartása" -msgid "Execute" -msgstr "Végrehajtás" - msgid "Entity Only" msgstr "Csak objektum" @@ -15865,9 +15917,6 @@ msgstr "Beállítás módosítása" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Összecsuk" - msgid "Daily Tips" msgstr "Napi tippek" @@ -16512,12 +16561,6 @@ msgstr "Filamentcsoportosítás" msgid "Fila Saving" msgstr "Filamentmegtakarítás" -msgid "Don't remind me again" -msgstr "Ne emlékeztessen újra" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Nem fog több felugró ablak megjelenni. A 'Beállítások' menüpontban újra megnyithatod." - msgid "Filament-Saving Mode" msgstr "Filament-takarékos üzemmód" @@ -16575,9 +16618,6 @@ msgstr " a fúvókaszám beállításához" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Filamentcsoportosítást hoz létre ezekhez: %s és %s, a nyomtatási minőséget előnyben részesítve a filamentmegtakarítással szemben" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "A tálcához tartozó filamentcsoportosítási módszert a tálca szeletelése gombnál található legördülő opció határozza meg." - msgid "Skip Objects" msgstr "Objektumok kihagyása" @@ -16959,59 +16999,59 @@ msgid "Print Outcome: " msgstr "Nyomtatási eredmény: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Vegyes filament szerkesztése" msgid "Effect Preview" -msgstr "" +msgstr "Effekt előnézet" msgid "Select Mixed Materials" -msgstr "" +msgstr "Vegyes anyagok kiválasztása" msgid "+ Add Material" -msgstr "" +msgstr "+ Anyag hozzáadása" msgid "- Delete Material" -msgstr "" +msgstr "- Anyag törlése" msgid "Ratio" -msgstr "" +msgstr "Arány" msgid "Gradient Effect" -msgstr "" +msgstr "Színátmenet" msgid "Mixing Recommendations" -msgstr "" +msgstr "Keverési javaslatok" msgid "-- Select --" -msgstr "" +msgstr "-- Kiválaszt --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "A színátmenethez engedélyezni kell a „Vegyes színű alréteg” beállítást. Engedélyezed?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Vegyes színű alréteg" #, c-format, boost-format msgid "Slot %s (%s)" -msgstr "" +msgstr "Férőhely: %s (%s)" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "nem keverhető. Kérjük, válassz azonos típusú filamentet." msgid "Please select a filament for all components" -msgstr "" +msgstr "Kérjük, válassz egy filamentet az összes komponenshez" msgid "Cannot mix different filament types" -msgstr "" +msgstr "A különböző típusú filamenteket nem lehet keverni" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Maximum 3 anyag keverhető" msgid "Maximum number of components reached" -msgstr "" +msgstr "Elérted a komponensek maximális számát" msgid "Remove the third material" -msgstr "" +msgstr "Harmadik anyag eltávolítása" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17302,6 +17342,24 @@ msgstr "" "Elsőre megbízható\n" "Kevesebb figyelem, kiszámíthatóbb eredmények. Példa: egy kis műhely, amely PETG tárgyakat gyárt, elkerülheti a „6. órában le kell állítani“ meglepetéseket, és tartani tudja a határidőket." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "A jelenlegi 3mf fájl tartalmaz G-kód szkriptet, kérjük, ellenőrizd a szkript tartalmát." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "A jelenlegi firmware maximum 16 anyagot támogat. Vagy csökkentsd az anyagok számát 16-ra (vagy kevesebbre) az Előkészítés oldalon, vagy próbáld meg frissíteni a firmware-t. Ha a frissítés után sem tudsz több filamentet használni, kérjük várj a következő firmware-verzióra." + +#~ msgid "Don't remind me again" +#~ msgstr "Ne emlékeztessen újra" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Nem fog több felugró ablak megjelenni. A 'Beállítások' menüpontban újra megnyithatod." + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "A tálcához tartozó filamentcsoportosítási módszert a tálca szeletelése gombnál található legördülő opció határozza meg." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Bal" diff --git a/bbl/i18n/it/BambuStudio_it.po b/bbl/i18n/it/BambuStudio_it.po index ee552501a9..f250bc726d 100644 --- a/bbl/i18n/it/BambuStudio_it.po +++ b/bbl/i18n/it/BambuStudio_it.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "Come caricare il filamento TPU." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Come inserire il filamento TPU su X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "L'uso di filamenti non Bambu può causare problemi di qualità di stampa." @@ -2657,7 +2657,7 @@ msgid "Assembly" msgstr "Assemblaggio" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "L'uso dell'altezza variabile del layer insieme a sublayer a colori misti può causare una scarsa qualità di miscelazione dei colori." msgid "Cut Connectors information" msgstr "Informazioni sui connettori di taglio" @@ -3180,12 +3180,12 @@ msgstr "Orientamento" msgid "Filling" msgstr "Riempimento" -msgid "Bed filling canceled." -msgstr "Riempimento del piano annullato." - msgid "Bed filling done." msgstr "Riempimento del piano completato." +msgid "Bed filling canceled." +msgstr "Riempimento del piano annullato." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3867,6 +3867,9 @@ msgstr "Stack overflow" msgid "Running post-processing scripts" msgstr "Esecuzione script di post-elaborazione" +msgid "Updating preview with post-processed G-code" +msgstr "Aggiornamento anteprima con G-code post-elaborato" + msgid "Successfully executed post-processing script" msgstr "Script post-elaborazione eseguito con successo" @@ -4614,6 +4617,9 @@ msgstr "Larghezza linea" msgid "Fan Speed" msgstr "Velocità ventola" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Flusso" @@ -4689,6 +4695,9 @@ msgstr "Velocità (mm/s)" msgid "Fan Speed (%)" msgstr "Velocità ventola (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatura (°C)" @@ -4842,6 +4851,9 @@ msgstr "Tempo layer:" msgid "Fan Speed: " msgstr "Velocità ventola: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatura: " @@ -4923,6 +4935,9 @@ msgstr "Rotella del mouse:" msgid "Increase/decrease edit area" msgstr "Aumenta/diminuisci l'area di modifica" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sequenza" @@ -5145,7 +5160,7 @@ msgid "Move closer" msgstr "Avvicina" msgid "The main assembly bounding box is too far from the world origin. Reset assembly relationships and move to origin?" -msgstr "Il bounding box dell'assieme principale è troppo lontano dall'origine. Reimpostare le relazioni dell'assieme e spostare all'origine?" +msgstr "Il bounding box dell'assieme principale è troppo lontano dall'origine degli assi. Reimpostare le relazioni dell'assieme e spostare all'origine?" msgid "Reset to origin" msgstr "Ripristina origine" @@ -5335,6 +5350,9 @@ msgstr "Gestione Dispositivi" msgid "Project" msgstr "Progetto" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Sì" @@ -5477,6 +5495,9 @@ msgstr "Vista destra" msgid "Isometric View" msgstr "Vista Isometrica" +msgid "Fit Camera" +msgstr "Adatta Telecamera" + msgid "Start a new window" msgstr "Inizia in una nuova finestra" @@ -5501,9 +5522,6 @@ msgstr "Salva progetto corrente su file" msgid "Save Project as" msgstr "Salva Progetto come" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Salva Progetto corrente come" @@ -6617,6 +6635,18 @@ msgstr "attenzione %s" msgid "%s has a warning" msgstr "%s ha un avviso" +msgid "Collapse" +msgstr "Comprimi" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Esegui" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "info %s" @@ -7097,7 +7127,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Rilevato filamento(i) ad alto ritiro: %s. Questi materiali potrebbero causare deviazioni dimensionali dopo il raffreddamento. Se il tuo modello richiede un montaggio o un accoppiamento preciso, fai riferimento alla guida Wiki per il test di ritiro." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "La stampa di filamenti multicolore su una stampante a estrusore singolo richiede frequenti cambi di filamento e spurghi, il che può aumentare significativamente gli sprechi e il rischio di intasamento del nozzle / scivolo di spurgo." #, boost-format msgid " plate %1%: " @@ -7296,9 +7326,6 @@ msgstr "" msgid "Restore" msgstr "Ripristina" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "Nel file 3mf corrente è presente uno script G-code; verifica il contenuto dello script." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "L'attuale temperatura del letto è relativamente alta. Il nozzle potrebbe essere ostruito quando si stampa questo filamento in un involucro chiuso. Si prega di aprire lo sportello anteriore e/o rimuovere il vetro superiore." @@ -7378,6 +7405,12 @@ msgstr "Il nome dei componenti all'interno del file step non è in formato UTF8! msgid "The name may show garbage characters!" msgstr "Il nome potrebbe mostrare caratteri sporchi!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Caricamento del file \"%1%\" non riuscito. Trovata configurazione non valida." @@ -7956,6 +7989,11 @@ msgstr "Motivo: \"%1%\" e un'altra parte non hanno intersezione." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Rilevate parti negative. Vuoi eseguire una mesh booleana prima dell'esportazione?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "Il filamento di calibrazione è assegnato a un estrusore diverso da quello selezionato nella finestra di dialogo Calibrazione PA (%s). Ciò può portare a risultati di calibrazione errati. Puoi modificare l’assegnazione nelle impostazioni di raggruppamento del filamento." @@ -8017,6 +8055,11 @@ msgstr "Numero non valido" msgid "Plate Settings" msgstr "Impostazioni Piatto" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "" @@ -8869,6 +8912,10 @@ msgstr "Codice di errore" msgid "Recommended filament arrangement saves %s->" msgstr "La disposizione filamento consigliata risparmia %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Il filamento %s non corrisponde al filamento nello slot AMS %s. Aggiorna il firmware della stampante per supportare l'assegnazione degli slot AMS." @@ -9155,9 +9202,6 @@ msgstr "Imposta la calibrazione del flow dinamico su 'OFF' per abilitare un valo msgid "This printer does not support printing all plates" msgstr "Questa stampante non supporta la stampa di piatti multipla" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Il firmware attuale supporta un massimo di 16 materiali. Puoi ridurre il numero di materiali a 16 o meno nella pagina di preparazione oppure provare ad aggiornare il firmware. Se dopo l'aggiornamento hai ancora limitazioni, attendi il supporto nei futuri aggiornamenti del firmware." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Verifica se il diametro del nozzle richiesto e il flusso corrispondono all'indicazione attuale." @@ -10488,6 +10532,9 @@ msgstr "Vista telecamera - Destra" msgid "Camera view - Isometric" msgstr "Vista telecamera - Isometrica" +msgid "Camera view - Fit to scene or selection" +msgstr "Vista telecamera - Adatta alla scena o alla selezione" + msgid "Shift+E" msgstr "" @@ -12672,6 +12719,12 @@ msgstr "Il volume di materiale necessario per innescare l'estrusore sulla torre, msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Volume di materiale necessario per innescare l'estrusore in vista di una sostituzione dell'hotend sulla torre." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Raffredda wipe tower" @@ -15355,9 +15408,6 @@ msgstr "Parti Selezionate" msgid "Keep original models" msgstr "Mantieni modelli originali" -msgid "Execute" -msgstr "Esegui" - msgid "Entity Only" msgstr "Solo entità" @@ -15880,9 +15930,6 @@ msgstr "Modifica preset" msgid "For more information, please check out Wiki" msgstr "Per ulteriori informazioni, consulta il Wiki" -msgid "Collapse" -msgstr "Comprimi" - msgid "Daily Tips" msgstr "Suggerimenti del giorno" @@ -16521,12 +16568,6 @@ msgstr "Raggruppamento filamenti" msgid "Fila Saving" msgstr "Risparmio Fila" -msgid "Don't remind me again" -msgstr "Non ricordarmelo più" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Non apparirà nessun altro pop-up. Puoi aggiornarlo in 'Preferenze'" - msgid "Filament-Saving Mode" msgstr "Modalità risparmio filamento" @@ -16584,9 +16625,6 @@ msgstr " per impostare il numero di Nozzle" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Genera il raggruppamento filamento per %s e %s in base alla qualità di stampa, privilegiando la qualità rispetto al risparmio di filamento" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Il metodo di raggruppamento del filamento per il piano attuale è determinato dall'opzione a discesa nel pulsante del piano di slicing." - msgid "Skip Objects" msgstr "Salta oggetti" @@ -16968,59 +17006,59 @@ msgid "Print Outcome: " msgstr "Risultato Stampa: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Modifica Filamento Misto" msgid "Effect Preview" -msgstr "" +msgstr "Effetto Anteprima" msgid "Select Mixed Materials" -msgstr "" +msgstr "Seleziona Materiali Misti" msgid "+ Add Material" -msgstr "" +msgstr "+ Aggiungi Materiale" msgid "- Delete Material" -msgstr "" +msgstr "- Elimina Materiale" msgid "Ratio" -msgstr "" +msgstr "Rapporto" msgid "Gradient Effect" -msgstr "" +msgstr "Effetto Gradiente" msgid "Mixing Recommendations" -msgstr "" +msgstr "Raccomandazioni Miscelazione" msgid "-- Select --" -msgstr "" +msgstr "-- Seleziona --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "L'effetto sfumato richiede l'abilitazione di 'Sublayer colore misto'. Vuoi abilitarlo?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Sublayer Colore Misto" #, c-format, boost-format msgid "Slot %s (%s)" msgstr "" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "non possono essere miscelati. Seleziona lo stesso tipo di filamento." msgid "Please select a filament for all components" -msgstr "" +msgstr "Seleziona un filamento per tutti i componenti" msgid "Cannot mix different filament types" -msgstr "" +msgstr "Non è possibile mischiare diversi tipi di filamento" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Massimo 3 materiali da mescolare" msgid "Maximum number of components reached" -msgstr "" +msgstr "Numero massimo di componenti raggiunto" msgid "Remove the third material" -msgstr "" +msgstr "Rimuovere il terzo materiale" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17310,6 +17348,24 @@ msgstr "" "Affidabilità al Primo Tentativo\n" "Meno supervisione, risultati più prevedibili. Ad esempio: una piccola produzione che stampa parti in PETG evita sorprese tipo \"fallimento alla sesta ora\" e mantiene i lotti nei tempi previsti." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "Nel file 3mf corrente è presente uno script G-code; verifica il contenuto dello script." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Il firmware attuale supporta un massimo di 16 materiali. Puoi ridurre il numero di materiali a 16 o meno nella pagina di preparazione oppure provare ad aggiornare il firmware. Se dopo l'aggiornamento hai ancora limitazioni, attendi il supporto nei futuri aggiornamenti del firmware." + +#~ msgid "Don't remind me again" +#~ msgstr "Non ricordarmelo più" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Non apparirà nessun altro pop-up. Puoi aggiornarlo in 'Preferenze'" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Il metodo di raggruppamento del filamento per il piano attuale è determinato dall'opzione a discesa nel pulsante del piano di slicing." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Sinistra" diff --git a/bbl/i18n/ja/BambuStudio_ja.po b/bbl/i18n/ja/BambuStudio_ja.po index 9143daf598..0248d0e3fb 100644 --- a/bbl/i18n/ja/BambuStudio_ja.po +++ b/bbl/i18n/ja/BambuStudio_ja.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "TPU フィラメントの供給方法" msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "X2DでのTPUフィラメントの供給方法" msgid "Using non-bambu filament may have printing quality issues." msgstr "Bambu 以外のフィラメントを使用すると、造形品質に問題が発生する可能性があります。" @@ -2652,7 +2652,7 @@ msgid "Assembly" msgstr "アセンブリ" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "可変積層ピッチと混色サブレイヤーを併用すると、色の混合品質が低下する可能性があります。" msgid "Cut Connectors information" msgstr "カットコネクタ情報" @@ -3167,12 +3167,12 @@ msgstr "向き調整中" msgid "Filling" msgstr "充填" -msgid "Bed filling canceled." -msgstr "ベッド充填がキャンセルされました。" - msgid "Bed filling done." msgstr "ベッドの充填が完了しました。" +msgid "Bed filling canceled." +msgstr "ベッド充填がキャンセルされました。" + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3847,6 +3847,9 @@ msgstr "Stack Overflow" msgid "Running post-processing scripts" msgstr "後処理スクリプトを実行" +msgid "Updating preview with post-processed G-code" +msgstr "後処理済み G コードでプレビューを更新中" + msgid "Successfully executed post-processing script" msgstr "後処理スクリプトの実行に成功" @@ -4589,6 +4592,9 @@ msgstr "線幅" msgid "Fan Speed" msgstr "ファン回転速度" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "流量" @@ -4664,6 +4670,9 @@ msgstr "速度 (mm/s)" msgid "Fan Speed (%)" msgstr "ファン回転速度 (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "温度 (°C)" @@ -4817,6 +4826,9 @@ msgstr "積層時間: " msgid "Fan Speed: " msgstr "ファン回転速度: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "温度: " @@ -4900,6 +4912,9 @@ msgstr "マウスホイール" msgid "Increase/decrease edit area" msgstr "編集領域を拡大/縮小" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "順番" @@ -5310,6 +5325,9 @@ msgstr "複数デバイス" msgid "Project" msgstr "プロジェクト" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "はい" @@ -5452,6 +5470,9 @@ msgstr "右側" msgid "Isometric View" msgstr "アイソメトリックビュー" +msgid "Fit Camera" +msgstr "カメラを全体に合わせる" + msgid "Start a new window" msgstr "新規ウインドウ" @@ -5476,9 +5497,6 @@ msgstr "現在のプロジェクトを保存" msgid "Save Project as" msgstr "プロジェクトを名前を付けて保存" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "プロジェクトを名前を付けて保存" @@ -6582,6 +6600,18 @@ msgstr "%s 警告" msgid "%s has a warning" msgstr "%s 警告" +msgid "Collapse" +msgstr "折りたたむ" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "実行" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s 情報" @@ -7058,7 +7088,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "高収縮フィラメント(%s)が検出されました。これらの材料は冷却後に寸法ズレが発生する可能性があります。精密な嵌合や組み立てが必要な場合は、収縮テストに関するWikiガイドをご参照ください" msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "単一押出機のプリンターで混色フィラメントを使用すると、頻繁なフィラメント切り替えとパージが必要になり、材料の無駄やノズル/廃材シュートの詰まりリスクが大幅に増加する可能性があります。" #, boost-format msgid " plate %1%: " @@ -7257,9 +7287,6 @@ msgstr "" msgid "Restore" msgstr "復元" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "現在の 3mf ファイルには G-code スクリプトが含まれています。内容を確認してください。" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "現在のヒートベッド温度は比較的高いです。このフィラメントを密閉環境で印刷すると、ノズルが詰まる可能性があります。フロントドアを開けるか、上部ガラスを取り外してください。" @@ -7339,6 +7366,12 @@ msgstr "ファイルのエンコーディング方式はUTF8形式ではあり msgid "The name may show garbage characters!" msgstr "名前が文字化けする可能性があります!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "ファイル %1% を読み込めませんでした。" @@ -7908,6 +7941,11 @@ msgstr "理由:「%1% 」と他のパーツには交差がありません。" msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "負のパーツが検出されました。エクスポート前にメッシュブール演算を実行しますか?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "キャリブレーション用フィラメントが、PAキャリブレーションダイアログで選択されている押出機(%s)とは異なる押出機に割り当てられています。これにより、正しいキャリブレーション結果が得られない可能性があります。フィラメント割り当て設定で変更できます。" @@ -7969,6 +8007,11 @@ msgstr "無効な数字" msgid "Plate Settings" msgstr "プレート設定" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "プライムタワー:" @@ -8821,6 +8864,10 @@ msgstr "エラーコード:" msgid "Recommended filament arrangement saves %s->" msgstr "推奨フィラメント配置により、%s を削減できます->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "フィラメント %sがAMSスロット%sのフィラメントと一致していません。" @@ -9110,9 +9157,6 @@ msgstr "カスタム値を使用するには、動的流量キャリブレーシ msgid "This printer does not support printing all plates" msgstr "プリンターが全てのプレートを造形することができません" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "現在のファームウェアでは、最大16種類の材料まで対応しています。準備ページで材料数を16個以下に減らすか、ファームウェアのアップデートをお試しください。アップデート後も制限が続く場合は、今後のファームウェア対応をお待ちください。" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "必要なノズル径とフロー速度が現在の表示内容と一致しているかご確認ください。" @@ -10438,6 +10482,9 @@ msgstr "カメラビュー - 右" msgid "Camera view - Isometric" msgstr "カメラビュー アイソメビュー" +msgid "Camera view - Fit to scene or selection" +msgstr "カメラ表示 - シーンまたは選択範囲に合わせる" + msgid "Shift+E" msgstr "" @@ -12630,6 +12677,12 @@ msgstr "ホットエンドの変更を伴わない場合に、プライムタワ msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "ホットエンド変更を伴う場合に、プライムタワー上で押出機を初期化するために必要な材料量です。" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "ワイプタワー冷却" @@ -15317,9 +15370,6 @@ msgstr "選択されたパーツ" msgid "Keep original models" msgstr "元のモデルを保持" -msgid "Execute" -msgstr "実行" - msgid "Entity Only" msgstr "エンティティのみ" @@ -15835,9 +15885,6 @@ msgstr "プリセットを編集" msgid "For more information, please check out Wiki" msgstr "詳細については、Wikiをご覧ください。" -msgid "Collapse" -msgstr "折りたたむ" - msgid "Daily Tips" msgstr "毎日のヒント" @@ -16480,12 +16527,6 @@ msgstr "フィラメントのグループ化" msgid "Fila Saving" msgstr "フィラメント節約" -msgid "Don't remind me again" -msgstr "今後通知しない" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "これ以上ポップアップは表示されません。この設定は「設定」から更新できます。" - msgid "Filament-Saving Mode" msgstr "フィラメント節約モード" @@ -16543,9 +16584,6 @@ msgstr "ノズル数を設定してください" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "造形品質を優先し、フィラメント節約より品質を重視して、%s と %s のフィラメント割り当てを生成します。" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "現在のプレートのフィラメントグループ化方法は、スライスプレートボタンのドロップダウンオプションによって決まります。" - msgid "Skip Objects" msgstr "オブジェクトをスキップ" @@ -16927,59 +16965,59 @@ msgid "Print Outcome: " msgstr "造形結果:" msgid "Edit Mixed Filament" -msgstr "" +msgstr "混合フィラメントを編集" msgid "Effect Preview" -msgstr "" +msgstr "効果プレビュー" msgid "Select Mixed Materials" -msgstr "" +msgstr "混合材料を選択" msgid "+ Add Material" -msgstr "" +msgstr "+ 材料を追加" msgid "- Delete Material" -msgstr "" +msgstr "- 材料を削除" msgid "Ratio" -msgstr "" +msgstr "比率" msgid "Gradient Effect" -msgstr "" +msgstr "グラデーション効果" msgid "Mixing Recommendations" -msgstr "" +msgstr "混合の推奨設定" msgid "-- Select --" -msgstr "" +msgstr "-- 選択 --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "グラデーション効果を使用するには「混色サブレイヤー」を有効にする必要があります。有効にしますか?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "混色サブレイヤー" #, c-format, boost-format msgid "Slot %s (%s)" -msgstr "" +msgstr "スロット %s (%s)" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "混用はできません。同じ種類のフィラメントを選択してください。" msgid "Please select a filament for all components" -msgstr "" +msgstr "すべての構成要素にフィラメントを選択してください。" msgid "Cannot mix different filament types" -msgstr "" +msgstr "異なるフィラメント種類を混合できません。" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "混合できる材料は最大3種類までです。" msgid "Maximum number of components reached" -msgstr "" +msgstr "構成要素の上限に達しました。" msgid "Remove the third material" -msgstr "" +msgstr "3つ目の材料を削除してください。" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17268,6 +17306,24 @@ msgstr "" "一発成功の信頼性\n" "見守りの手間を減らし、より予測可能な造形を実現。例:PETG 部品を小規模ファームで運用する場合でも、「6時間目で失敗」といった不意打ちを避け、バッチを計画どおりに進められます。" +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "現在の 3mf ファイルには G-code スクリプトが含まれています。内容を確認してください。" + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "現在のファームウェアでは、最大16種類の材料まで対応しています。準備ページで材料数を16個以下に減らすか、ファームウェアのアップデートをお試しください。アップデート後も制限が続く場合は、今後のファームウェア対応をお待ちください。" + +#~ msgid "Don't remind me again" +#~ msgstr "今後通知しない" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "これ以上ポップアップは表示されません。この設定は「設定」から更新できます。" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "現在のプレートのフィラメントグループ化方法は、スライスプレートボタンのドロップダウンオプションによって決まります。" + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "左側" diff --git a/bbl/i18n/ko/BambuStudio_ko.po b/bbl/i18n/ko/BambuStudio_ko.po index 130dc8cd10..860a503f3e 100644 --- a/bbl/i18n/ko/BambuStudio_ko.po +++ b/bbl/i18n/ko/BambuStudio_ko.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -47,19 +47,19 @@ msgid "auxiliary extruder" msgstr "보조 압출기" msgid "Left Extruder" -msgstr "왼쪽 압출기의 커터가 멈췄습니다. 커터 핸들을 빼내십시오." +msgstr "왼쪽 압출기" msgid "Left extruder" -msgstr "왼쪽 압출기의 커터가 멈췄습니다. 커터 핸들을 빼내십시오." +msgstr "왼쪽 압출기" msgid "left extruder" msgstr "왼쪽 압출기" msgid "Right Extruder" -msgstr "오른쪽 압출기의 커터가 멈췄습니다. 커터 핸들을 빼내십시오." +msgstr "오른쪽 압출기" msgid "Right extruder" -msgstr "오른쪽 압출기의 커터가 멈췄습니다. 커터 핸들을 빼내십시오." +msgstr "오른쪽 압출기" msgid "right extruder" msgstr "오른쪽 압출기" @@ -119,22 +119,22 @@ msgid "auxiliary hotend" msgstr "보조 핫엔드" msgid "Left Hotend" -msgstr "" +msgstr "왼쪽 핫엔드" msgid "Left hotend" -msgstr "" +msgstr "왼쪽 핫엔드" msgid "left hotend" -msgstr "" +msgstr "왼쪽 핫엔드" msgid "Right Hotend" -msgstr "" +msgstr "오른쪽 핫엔드" msgid "Right hotend" -msgstr "" +msgstr "오른쪽 핫엔드" msgid "right hotend" -msgstr "" +msgstr "오른쪽 핫엔드" msgid "main" msgstr "메인" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "TPU 필라멘트 공급 방법" msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "X2D에 TPU 필라멘트 공급 방법." msgid "Using non-bambu filament may have printing quality issues." msgstr "Bambu가 아닌 필라멘트를 사용하면 출력 품질 문제가 발생할 수 있습니다." @@ -2654,7 +2654,7 @@ msgid "Assembly" msgstr "결합" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "가변 레이어 높이를 혼합 색상 하위 레이어와 함께 사용하면 색상 혼합 품질이 저하될 수 있습니다." msgid "Cut Connectors information" msgstr "컷 커넥터 정보" @@ -3038,7 +3038,7 @@ msgstr "왼쪽(보조)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "왼쪽(가열)" msgctxt "air_duct" msgid "Chamber" @@ -3175,12 +3175,12 @@ msgstr "회전 중" msgid "Filling" msgstr "채우기" -msgid "Bed filling canceled." -msgstr "베드 채우기 취소됨" - msgid "Bed filling done." msgstr "베드 채우기 완료." +msgid "Bed filling canceled." +msgstr "베드 채우기 취소됨" + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3857,6 +3857,9 @@ msgstr "스택 오버플로" msgid "Running post-processing scripts" msgstr "포스트 프로세싱 스크립트 실행" +msgid "Updating preview with post-processed G-code" +msgstr "후처리된 G-code로 미리보기 업데이트 중" + msgid "Successfully executed post-processing script" msgstr "성공적으로 실행된 후처리 스크립트" @@ -4604,6 +4607,9 @@ msgstr "라인 폭" msgid "Fan Speed" msgstr "팬 속도" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "유량" @@ -4679,6 +4685,9 @@ msgstr "속도 (mm/s)" msgid "Fan Speed (%)" msgstr "팬 속도 (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "온도 (°C)" @@ -4832,6 +4841,9 @@ msgstr "레이어 시간: " msgid "Fan Speed: " msgstr "팬 속도: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "온도: " @@ -4915,6 +4927,9 @@ msgstr "마우스 휠:" msgid "Increase/decrease edit area" msgstr "편집 영역 늘리기/줄이기" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "순서" @@ -5059,14 +5074,14 @@ msgid "Select Plate" msgstr "빌드 플레이트 선택" msgid "Change camera perspective" -msgstr "" +msgstr "카메라 시점 변경" msgid "Go to Wiki" msgstr "Wiki로 가기" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "현재 조립률: %1%%%, 볼륨률: %2%%%" msgctxt "Camera" msgid "Top" @@ -5128,7 +5143,7 @@ msgid "Size:" msgstr "크기:" msgid "Isolated objects detected" -msgstr "" +msgstr "고립 물체 감지" msgid "Click to move them closer to the main body." msgstr "클릭하면 본체에 더 가깝게 이동됩니다." @@ -5331,6 +5346,9 @@ msgstr "멀티 디바이스" msgid "Project" msgstr "프로젝트" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "예" @@ -5473,6 +5491,9 @@ msgstr "오른쪽 뷰" msgid "Isometric View" msgstr "아이소메트릭 뷰" +msgid "Fit Camera" +msgstr "카메라 맞춤" + msgid "Start a new window" msgstr "새 창 시작" @@ -5497,9 +5518,6 @@ msgstr "현재 프로젝트를 파일에 저장" msgid "Save Project as" msgstr "다른 이름으로 프로젝트 저장" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "현재 프로젝트를 다른 이름으로 저장" @@ -6612,6 +6630,18 @@ msgstr "%s 경고" msgid "%s has a warning" msgstr "%s에 경고가 있습니다." +msgid "Collapse" +msgstr "접기" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "실행" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s 정보" @@ -6901,10 +6931,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "출력 시작 시 빌드 플레이트에 물체가 있는지 확인하여 충돌을 방지합니다." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "출력 부품 변위 감지" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "출력 중 출력물을 모니터링하고, 출력물이 움직이거나 무너지면 즉시 경고합니다." msgid "Ensures the build plate type and placement are correct." msgstr "빌드 플레이트의 유형과 배치가 올바른지 확인하세요." @@ -7088,7 +7118,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "고수축성 필라멘트(%s)가 감지되었습니다. 이 재료는 냉각 후 치수 편차를 유발할 수 있습니다. 모델이 정밀하게 맞거나 조립되어야 하는 경우, 수축 테스트를 위한 Wiki 가이드를 참조하십시오." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "단일 압출기 프린터에서 혼합색 필라멘트를 출력하려면 빈번한 필라멘트 교체 및 플러싱이 필요하며, 이는 폐기물을 크게 증가시키고 노즐 / 폐기물 슈트 막힘의 위험을 높일 수 있습니다." #, boost-format msgid " plate %1%: " @@ -7235,13 +7265,13 @@ msgid "Remove last mixed filament" msgstr "마지막 혼합 필라멘트 제거" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "혼합 필라멘트에 유효하지 않거나 일치하지 않는 구성 요소가 있습니다. 해당 항목을 다시 편집하십시오." msgid "Search plate, object and part." msgstr "플레이트, 개체 및 부품을 검색합니다." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "대상 혼합 필라멘트는 이 물리적 필라멘트를 구성 요소로 사용합니다. 병합하면 이 물리적 필라멘트가 제거되어 혼합 필라멘트가 무효화될 수 있습니다. 계속하시겠습니까?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7267,7 +7297,7 @@ msgid "Mixed filament has broken component references" msgstr "혼합 필라멘트에서 구성 요소 참조가 깨졌습니다" msgid "Edit / Delete / Merge" -msgstr "" +msgstr "편집 / 삭제 / 병합" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7289,9 +7319,6 @@ msgstr "" msgid "Restore" msgstr "복원" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "현재 3mf 파일에 G 코드 스크립트가 포함되어 있습니다. 스크립트 내용을 확인해 주십시오." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "현재 열판 온도가 상대적으로 높습니다. 밀폐된 환경에서 이 필라멘트를 출력할 경우 노즐이 막힐 수 있습니다. 전면 도어를 열거나 상단 유리를 제거하세요." @@ -7371,6 +7398,12 @@ msgstr "STEP 파일 내의 구성 요소 이름이 UTF8 형식이 아닙니다!" msgid "The name may show garbage characters!" msgstr "이름에 이상한 문자가 표시될 수 있습니다!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "\"%1%\" 파일을 불러오지 못했습니다. 잘못된 설정이 발견되었습니다." @@ -7911,9 +7944,11 @@ msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." msgstr "" +"슬라이스된 파일 내보내기 실패.\n" +"다른 프로그램에서 파일을 사용 중인지 또는 디스크 공간이 충분한지 확인하십시오." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "슬라이스된 파일 내보내기" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7947,9 +7982,14 @@ msgstr "이유: \"%1%\"과 다른 부분은 교집합이 없습니다." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "음량 부분이 감지되었습니다. 내보내기 전에 메시 비우기를 수행하시겠습니까?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "현재 교정 필라멘트가 PA 교정 대화 상자(%s)에서 선택한 압출기와 다른 압출기에 할당되어 있습니다. 이로 인해 교정 결과가 부정확해질 수 있습니다. 필라멘트 그룹 설정에서 할당을 변경할 수 있습니다." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "0.2mm 노즐에는 PVA 필라멘트를 사용하는 것은 권장하지 않습니다." @@ -8008,6 +8048,11 @@ msgstr "잘못된 번호" msgid "Plate Settings" msgstr "플레이트 설정" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "프라임 타워:" @@ -8269,7 +8314,7 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "활성화하면 마지막으로 사용한 색상 구성(예: Line Type, 속도)이 다음 시작 시 자동으로 적용됩니다." msgid "Display overview" -msgstr "" +msgstr "개요 표시" msgid "Show assembly BVH primary bounds" msgstr "어셈블리 BVH 기본 경계 표시" @@ -8621,7 +8666,7 @@ msgid "First layer filament sequence" msgstr "첫 레이어 필라멘트 순서" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "필라멘트 목록에 여러 필라멘트가 혼합되어 있습니다. 사용자 지정 필라멘트 순서는 적용되지 않습니다." msgid "Same as Global Bed Type" msgstr "글로벌 플레이트 타입과 동일" @@ -8860,6 +8905,10 @@ msgstr "오류 코드" msgid "Recommended filament arrangement saves %s->" msgstr "권장 필라멘트 배열로 %s를 절약합니다->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "필라멘트 %s가 AMS 슬롯 %s의 필라멘트와 일치하지 않습니다. AMS 슬롯 할당을 지원하도록 프린터 펌웨어를 업데이트하십시오." @@ -9033,7 +9082,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "현재 노즐 직경(%.1fmm)이 슬라이싱 파일(%.1fmm)과 일치하지 않습니다. 설치된 노즐이 프린터의 설정과 일치하는지 확인한 다음 슬라이싱할 때 해당 프린터 프리셋을 설정하세요." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "프린터에 설치된 필라멘트 트랙 스위치가 슬라이싱 파일과 일치하지 않습니다. 출력 품질 문제를 방지하려면 다시 슬라이싱하십시오." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "이 출력에는 필라멘트 트랙 스위치가 필요합니다. 먼저 설치해 주십시오." @@ -9148,9 +9197,6 @@ msgstr "사용자 지정 동적 흐름 값을 사용하려면 동적 흐름 보 msgid "This printer does not support printing all plates" msgstr "이 프린터는 모든 플레이트 출력을 지원하지 않습니다." -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "현재 펌웨어는 최대 16개의 재료를 지원합니다. 준비 페이지에서 재료 수를 16개 이하로 줄이거나 펌웨어를 업데이트해 보세요. 업데이트 후에도 여전히 제한이 있는 경우, 다음 펌웨어 지원이 나올 때까지 기다려 주세요." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "필요한 노즐 직경과 유량이 현재 표시와 일치하는지 확인하세요." @@ -9411,7 +9457,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "%s 를 사용하여 %s를 지지하는 경우, 다음 설정을 권장합니다:" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "PLA를 지지대로 사용하여 TPU를 출력할 때, 다음 설정을 권장합니다:" @@ -10477,6 +10523,9 @@ msgstr "카메라 뷰 - 오른쪽" msgid "Camera view - Isometric" msgstr "카메라 뷰 - 아이소메트릭" +msgid "Camera view - Fit to scene or selection" +msgstr "카메라 시점 - 장면 또는 선택 영역에 맞추기" + msgid "Shift+E" msgstr "" @@ -12658,6 +12707,12 @@ msgstr "핫엔드 교체를 제외하고, 타워에서 압출기를 준비하는 msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "타워에서 핫엔드를 교체하기 위해 압출기를 준비하는 데 필요한 재료 부피." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "와이프 타워 냉각" @@ -14957,7 +15012,7 @@ msgstr "" "- 다른 필라멘트 브랜드 및 제품군(브랜드 = Bambu, 제품군 = 기본, 매트)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux)는 자동 유량 보정을 지원하지 않습니다." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "- 참고: 핫엔드 번호는 홀더에 연결되어 있습니다. 핫엔드를 새 홀더로 이동하면 번호가 자동으로 업데이트됩니다.\n" @@ -15101,7 +15156,7 @@ msgid "PA Calibration" msgstr "PA 보정" msgid "Extruder type" -msgstr "" +msgstr "압출기 유형" msgid "PA Tower" msgstr "PA 타워" @@ -15335,9 +15390,6 @@ msgstr "선택된 출력물" msgid "Keep original models" msgstr "원본 모델 유지" -msgid "Execute" -msgstr "실행" - msgid "Entity Only" msgstr "개체만 해당됨" @@ -15859,9 +15911,6 @@ msgstr "프리셋 편집" msgid "For more information, please check out Wiki" msgstr "자세한 내용은 위키에서 확인하세요" -msgid "Collapse" -msgstr "접기" - msgid "Daily Tips" msgstr "일일 팁" @@ -16506,12 +16555,6 @@ msgstr "필라멘트 그룹화" msgid "Fila Saving" msgstr "필라멘트 절약" -msgid "Don't remind me again" -msgstr "다시 알리지 마세요" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "더 이상 팝업이 표시되지 않습니다. '환경설정'에서 다시 열 수 있습니다" - msgid "Filament-Saving Mode" msgstr "필라멘트 절약 모드" @@ -16569,9 +16612,6 @@ msgstr " 노즐 개수를 설정하려면" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "%s 및 %s 에 대해 출력 품질을 기준으로 필라멘트 그룹을 생성하며, 필라멘트 절약보다 출력 품질을 우선시합니다" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "현재 플레이트의 필라멘트 그룹화 방법은 슬라이스 플레이트 버튼의 드롭다운 옵션에 따라 결정됩니다." - msgid "Skip Objects" msgstr "객체 건너뛰기" @@ -16953,59 +16993,59 @@ msgid "Print Outcome: " msgstr "출력 결과: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "혼합 필라멘트 편집" msgid "Effect Preview" -msgstr "" +msgstr "효과 미리보기" msgid "Select Mixed Materials" -msgstr "" +msgstr "혼합 재료 선택" msgid "+ Add Material" -msgstr "" +msgstr "+ 재료 추가" msgid "- Delete Material" -msgstr "" +msgstr "- 재료 삭제" msgid "Ratio" -msgstr "" +msgstr "비율" msgid "Gradient Effect" -msgstr "" +msgstr "그라디언트 효과" msgid "Mixing Recommendations" -msgstr "" +msgstr "권장 혼합" msgid "-- Select --" -msgstr "" +msgstr "-- 선택 --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "그라디언트 효과를 사용하려면 '혼합 색상 하위 레이어'를 활성화해야 합니다. 지금 활성화하시겠습니까?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "혼합 색상 하위 레이어" #, c-format, boost-format msgid "Slot %s (%s)" -msgstr "" +msgstr "슬롯 %s (%s)" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "혼합할 수 없습니다. 동일한 필라멘트 종류를 선택해 주세요." msgid "Please select a filament for all components" -msgstr "" +msgstr "모든 부품에 필라멘트를 선택하세요." msgid "Cannot mix different filament types" -msgstr "" +msgstr "다른 필라멘트 유형을 섞을 수 없습니다." msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "혼합 가능한 재료는 최대 3가지입니다." msgid "Maximum number of components reached" -msgstr "" +msgstr "최대 구성 요소 수에 도달했습니다." msgid "Remove the third material" -msgstr "" +msgstr "세 번째 재료를 제거하세요" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17295,6 +17335,24 @@ msgstr "" "첫 시도 성공 신뢰성\n" "관리 부담 감소, 예측 가능한 생산량 증가. 예: PETG 부품을 생산하는 소규모 농장은 '6시간 후 실패'와 같은 예상치 못한 문제 발생을 방지하고 생산 일정을 준수할 수 있습니다." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "현재 3mf 파일에 G 코드 스크립트가 포함되어 있습니다. 스크립트 내용을 확인해 주십시오." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "현재 펌웨어는 최대 16개의 재료를 지원합니다. 준비 페이지에서 재료 수를 16개 이하로 줄이거나 펌웨어를 업데이트해 보세요. 업데이트 후에도 여전히 제한이 있는 경우, 다음 펌웨어 지원이 나올 때까지 기다려 주세요." + +#~ msgid "Don't remind me again" +#~ msgstr "다시 알리지 마세요" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "더 이상 팝업이 표시되지 않습니다. '환경설정'에서 다시 열 수 있습니다" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "현재 플레이트의 필라멘트 그룹화 방법은 슬라이스 플레이트 버튼의 드롭다운 옵션에 따라 결정됩니다." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "왼쪽" diff --git a/bbl/i18n/nl/BambuStudio_nl.po b/bbl/i18n/nl/BambuStudio_nl.po index 00bf07cf5c..d41aec07f1 100644 --- a/bbl/i18n/nl/BambuStudio_nl.po +++ b/bbl/i18n/nl/BambuStudio_nl.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -119,22 +119,22 @@ msgid "auxiliary hotend" msgstr "hulp hotend" msgid "Left Hotend" -msgstr "" +msgstr "Linker hotend" msgid "Left hotend" -msgstr "" +msgstr "Linker hotend" msgid "left hotend" -msgstr "" +msgstr "linker hotend" msgid "Right Hotend" -msgstr "" +msgstr "Rechter hotend" msgid "Right hotend" -msgstr "" +msgstr "Rechter hotend" msgid "right hotend" -msgstr "" +msgstr "rechter hotend" msgid "main" msgstr "hoofd" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "Hoe TPU-filament te voeden." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Hoe TPU-filament te laden op de X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "Het gebruik van niet-bambu filament kan problemen geven met de printkwaliteit." @@ -2657,7 +2657,7 @@ msgid "Assembly" msgstr "Montage" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "Het gebruik van variabele laaghoogte samen met een gemengde kleursublaag kan leiden tot een slechte kleurmengkwaliteit." msgid "Cut Connectors information" msgstr "Snede connectors informatie" @@ -3043,7 +3043,7 @@ msgstr "Links (Aux)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "Linker (verwarming)" msgctxt "air_duct" msgid "Chamber" @@ -3180,12 +3180,12 @@ msgstr "Oriënteren " msgid "Filling" msgstr "Vullen" -msgid "Bed filling canceled." -msgstr "Bed vulling geannuleerd." - msgid "Bed filling done." msgstr "Bedden gevuld." +msgid "Bed filling canceled." +msgstr "Bed vulling geannuleerd." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3862,6 +3862,9 @@ msgstr "Stack overflow" msgid "Running post-processing scripts" msgstr "Het uitvoeren van post-processing scripts" +msgid "Updating preview with post-processed G-code" +msgstr "Voorvertoning bijwerken met nabewerkte G-code" + msgid "Successfully executed post-processing script" msgstr "Succesvol uitgevoerd nabewerkingsscript" @@ -4609,6 +4612,9 @@ msgstr "Lijnbreedte" msgid "Fan Speed" msgstr "Ventilator snelheid" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Flow" @@ -4684,6 +4690,9 @@ msgstr "Snelheid (mm/s)" msgid "Fan Speed (%)" msgstr "Ventilatorsnelheid (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatuur (°C)" @@ -4837,6 +4846,9 @@ msgstr "Laagtijd:" msgid "Fan Speed: " msgstr "Ventilatorsnelheid: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatuur: " @@ -4920,6 +4932,9 @@ msgstr "Muiswiel:" msgid "Increase/decrease edit area" msgstr "Bewerkingsgebied vergroten/verkleinen" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Reeks" @@ -5064,14 +5079,14 @@ msgid "Select Plate" msgstr "Printbed selecteren" msgid "Change camera perspective" -msgstr "" +msgstr "Wijzig cameraperspectief" msgid "Go to Wiki" msgstr "Ga naar Wiki" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "Huidige assemblagesnelheid: %1%%%, volumetrische snelheid: %2%%%" msgctxt "Camera" msgid "Top" @@ -5133,7 +5148,7 @@ msgid "Size:" msgstr "Maat:" msgid "Isolated objects detected" -msgstr "" +msgstr "Geïsoleerde objecten gedetecteerd" msgid "Click to move them closer to the main body." msgstr "Klik om ze dichter naar het hoofdgedeelte te verplaatsen." @@ -5336,6 +5351,9 @@ msgstr "Meerdere apparaten" msgid "Project" msgstr "Project" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Ja" @@ -5478,6 +5496,9 @@ msgstr "Rechterzijde bekijken" msgid "Isometric View" msgstr "Isometrische weergave" +msgid "Fit Camera" +msgstr "Camera passen" + msgid "Start a new window" msgstr "Een nieuw venster openen" @@ -5502,9 +5523,6 @@ msgstr "Bewaar huidig project als" msgid "Save Project as" msgstr "Bewaar project als" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Bewaar huidig project als" @@ -6620,6 +6638,18 @@ msgstr "%s waarschuwing" msgid "%s has a warning" msgstr "%s heeft een waarschuwing" +msgid "Collapse" +msgstr "Instorten" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Uitvoeren" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s info" @@ -6913,10 +6943,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "Controleert aan het begin van een printopdracht of er objecten op de bouwplaat aanwezig zijn om botsingen te voorkomen." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "Detectie van verplaatsing van geprint onderdeel" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "Houdt het geprinte onderdeel tijdens het printen in de gaten en waarschuwt onmiddellijk als het verschuift of instort." msgid "Ensures the build plate type and placement are correct." msgstr "Zorgt ervoor dat het type en de plaatsing van het bouwoppervlak correct zijn." @@ -7100,7 +7130,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Hoge krimpende filament(en) gedetecteerd: %s. Deze materialen kunnen dimensionale afwijkingen vertonen na afkoeling. Als uw model een nauwkeurige passing of assemblage vereist, raadpleeg dan de Wiki-handleiding voor krimp-testen." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "Het printen van meerkleurig filament op een printer met één extruder vereist frequent wisselen en spoelen van filament, wat de verspilling aanzienlijk kan verhogen en het risico op verstopping van de nozzle / afvoergoot." #, boost-format msgid " plate %1%: " @@ -7245,13 +7275,13 @@ msgid "Remove last mixed filament" msgstr "Verwijder laatste gemengde filament" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "Gemengd filament heeft ongeldige of verkeerd passende componenten. Bewerk de betreffende vermeldingen opnieuw." msgid "Search plate, object and part." msgstr "Zoek plaat, object en onderdeel." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "Het doel gemengde filament gebruikt dit fysieke filament als component. Samenvoegen verwijdert dit fysieke filament en kan het gemengde filament ongeldig maken. Doorgaan?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7277,7 +7307,7 @@ msgid "Mixed filament has broken component references" msgstr "Mixed filament heeft gebroken componentreferenties" msgid "Edit / Delete / Merge" -msgstr "" +msgstr "Bewerken / Verwijderen / Samenvoegen" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7299,9 +7329,6 @@ msgstr "" msgid "Restore" msgstr "Herstellen" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "Er is een G-code-script aanwezig in het huidige 3mf-bestand, controleer alstublieft de inhoud van het script." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7381,6 +7408,12 @@ msgstr "Naam van onderdelen in stapbestand is niet UTF8-formaat!" msgid "The name may show garbage characters!" msgstr "De naam kan onzintekens bevatten!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Kan bestand \"%1%\" niet laden. Er is een ongeldige configuratie gevonden." @@ -7921,9 +7954,11 @@ msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." msgstr "" +"Het gesliced bestand kon niet worden geëxporteerd.\n" +"Controleer of het bestand door een ander programma wordt bezet of dat er voldoende schijfruimte is." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "Gesliced bestand exporteren" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7957,9 +7992,14 @@ msgstr "Reden: \"%1%\" en een ander deel hebben geen snijpunt." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Negatieve delen gedetecteerd. Wil je mesh booleaans uitvoeren voordat je exporteert?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "Het kalibratiefilament is momenteel toegewezen aan een andere extruder dan degene die is geselecteerd in het PA-kalibratiedialoogvenster (%s). Dit kan leiden tot onjuiste kalibratieresultaten. U kunt de toewijzing wijzigen in de instellingen voor filamentgroepering." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "Het wordt niet aanbevolen om PVA-filamenten met nozzles van 0,2 mm te gebruiken." @@ -8018,6 +8058,11 @@ msgstr "Ongeldig nummer" msgid "Plate Settings" msgstr "Plaatinstellingen" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Prime Toren:" @@ -8279,7 +8324,7 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "Wanneer ingeschakeld, wordt het laatst gebruikte kleurenschema (bijv. Lijntype, Snelheid) automatisch toegepast bij de volgende opstart." msgid "Display overview" -msgstr "" +msgstr "Weergaveoverzicht" msgid "Show assembly BVH primary bounds" msgstr "Toon assemblage BVH primaire grenzen" @@ -8631,7 +8676,7 @@ msgid "First layer filament sequence" msgstr "Eerste laag filamentvolgorde" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "De filamentenlijst bevat gemengde filamenten. De aangepaste filamentvolgorde wordt niet van kracht." msgid "Same as Global Bed Type" msgstr "Hetzelfde als Global Bed Type" @@ -8870,6 +8915,10 @@ msgstr "Foutcode" msgid "Recommended filament arrangement saves %s->" msgstr "Aanbevolen filamentindeling bespaart %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Filament %s komt niet overeen met het filament in AMS-sleuf %s. Werk de firmware van de printer bij om de toewijzing van AMS-sleuven te ondersteunen." @@ -9043,7 +9092,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "De huidige nozzle diameter (%.1fmm) komt niet overeen met het snijbestand (%.1fmm). Controleer of de geïnstalleerde nozzle overeenkomt met de instellingen in de printer en stel vervolgens de corresponderende voorinstelling van de printer in tijdens het slicen." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "De filamentwisselaar die op de printer is geïnstalleerd, komt niet overeen met het slicingbestand. Snijd opnieuw om problemen met de printkwaliteit te voorkomen." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "Deze print vereist een filamentwisselaar. Installeer deze eerst alstublieft." @@ -9158,9 +9207,6 @@ msgstr "Stel dynamische stroomkalibratie in op 'UIT' om aangepaste dynamische st msgid "This printer does not support printing all plates" msgstr "Deze printer biedt geen ondersteuning voor het afdrukken van alle platen" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "De huidige firmware ondersteunt maximaal 16 materialen. U kunt het aantal materialen terugbrengen tot 16 of minder op de Voorbereidingspagina, of proberen de firmware bij te werken. Als u na de update nog steeds beperkt bent, wacht dan op volgende firmware-ondersteuning." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Controleer of de vereiste nozzle diameter en doorvoersnelheid overeenkomen met de huidige weergave." @@ -9421,7 +9467,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "Bij gebruik van %s ter ondersteuning van %s raden we de volgende instellingen aan:" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "Bij gebruik van PLA ter ondersteuning van TPU raden we de volgende instellingen aan:" @@ -10492,6 +10538,9 @@ msgstr "Cameraweergave - Rechts" msgid "Camera view - Isometric" msgstr "Cameraweergave - Isometrisch" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12673,6 +12722,12 @@ msgstr "Het volume materiaal dat nodig is om de extruder op de toren te primen, msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Het volume materiaal dat nodig is om de extruder te primen voor een hot-end wissel op de toren." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Afkoeling veegtoren" @@ -14970,7 +15025,7 @@ msgstr "" "- Verschillende filamentmerken en -families (Merk = Bambu, Familie = Basis, Mat)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux) ondersteunt geen automatische stroomkalibratie." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "- Opmerking: Het nummer van de hot-end is gekoppeld aan de houder. Wanneer de hot-end naar een nieuwe houder wordt verplaatst, wordt het nummer automatisch bijgewerkt.\n" @@ -15346,9 +15401,6 @@ msgstr "Geselecteerde onderdelen" msgid "Keep original models" msgstr "Bewaar originele modellen" -msgid "Execute" -msgstr "Uitvoeren" - msgid "Entity Only" msgstr "Alleen entiteit" @@ -15871,9 +15923,6 @@ msgstr "Preset bewerken" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Instorten" - msgid "Daily Tips" msgstr "Dagelijkse tips" @@ -16518,12 +16567,6 @@ msgstr "Draadgroepering" msgid "Fila Saving" msgstr "Filament besparing" -msgid "Don't remind me again" -msgstr "Herinner me er niet meer aan" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Er verschijnt geen pop-up meer. U kunt dit bijwerken in 'Voorkeuren'" - msgid "Filament-Saving Mode" msgstr "Filament-besparende modus" @@ -16581,9 +16624,6 @@ msgstr " om het aantal nozzles in te stellen" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Genereert filamentgroepering voor de %s en %s op basis van de printkwaliteit, waarbij printkwaliteit boven filamentbesparing gaat" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "De filamentgroeperingsmethode voor de huidige plaat wordt bepaald door de vervolgkeuzemogelijkheid bij de knop voor het snijden van de plaat." - msgid "Skip Objects" msgstr "Objecten overslaan" @@ -16965,59 +17005,59 @@ msgid "Print Outcome: " msgstr "Printresultaat: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Voeg gemengd filament toe" msgid "Effect Preview" -msgstr "" +msgstr "Effectvoorbeeld" msgid "Select Mixed Materials" -msgstr "" +msgstr "Selecteer gemengde materialen" msgid "+ Add Material" -msgstr "" +msgstr "+ Materiaal toevoegen" msgid "- Delete Material" -msgstr "" +msgstr "- Materialen verwijderen" msgid "Ratio" -msgstr "" +msgstr "Verhouding" msgid "Gradient Effect" -msgstr "" +msgstr "Verloop effect" msgid "Mixing Recommendations" -msgstr "" +msgstr "Aanbevelingen voor het mengen" msgid "-- Select --" -msgstr "" +msgstr "-- Selecteer --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "Voor het verloopeffect moet de optie 'Sublaag gemengde kleuren' zijn ingeschakeld. Wilt u deze nu inschakelen?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Sublaag met gemengde kleur" #, c-format, boost-format msgid "Slot %s (%s)" msgstr "" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "kan niet gemengd worden. Selecteer het type filament." msgid "Please select a filament for all components" -msgstr "" +msgstr "Selecteer een filament voor alle componenten." msgid "Cannot mix different filament types" -msgstr "" +msgstr "Verschillende soorten filamenten kunnen niet door elkaar gebruikt worden." msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Maximaal 3 materialen voor menging" msgid "Maximum number of components reached" -msgstr "" +msgstr "Maximaal aantal componenten bereikt" msgid "Remove the third material" -msgstr "" +msgstr "Verwijder het derde materiaal." #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17307,6 +17347,24 @@ msgstr "" "Betrouwbaarheid in één keer goed\n" "Minder toezicht, voorspelbaardere output. Voorbeeld: een kleine boerderij die PETG-onderdelen produceert, voorkomt verrassingen zoals 'falen na 6 uur' en houdt batches op schema." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "Er is een G-code-script aanwezig in het huidige 3mf-bestand, controleer alstublieft de inhoud van het script." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "De huidige firmware ondersteunt maximaal 16 materialen. U kunt het aantal materialen terugbrengen tot 16 of minder op de Voorbereidingspagina, of proberen de firmware bij te werken. Als u na de update nog steeds beperkt bent, wacht dan op volgende firmware-ondersteuning." + +#~ msgid "Don't remind me again" +#~ msgstr "Herinner me er niet meer aan" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Er verschijnt geen pop-up meer. U kunt dit bijwerken in 'Voorkeuren'" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "De filamentgroeperingsmethode voor de huidige plaat wordt bepaald door de vervolgkeuzemogelijkheid bij de knop voor het snijden van de plaat." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Links" diff --git a/bbl/i18n/pl/BambuStudio_pl.po b/bbl/i18n/pl/BambuStudio_pl.po index e6eb475eea..4996dfde8c 100644 --- a/bbl/i18n/pl/BambuStudio_pl.po +++ b/bbl/i18n/pl/BambuStudio_pl.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -29,22 +29,22 @@ msgid "The filament model is unknown. A random filament preset will be used." msgstr "Model filamentu jest nieznany. Losowy profil filamentu zostanie użyty" msgid "Main Extruder" -msgstr "" +msgstr "Ekstruder główny" msgid "Main extruder" -msgstr "" +msgstr "Ekstruder główny" msgid "main extruder" -msgstr "" +msgstr "ekstruder główny" msgid "Auxiliary Extruder" -msgstr "" +msgstr "Ekstruder pomocniczy" msgid "Auxiliary extruder" -msgstr "" +msgstr "Ekstruder pomocniczy" msgid "auxiliary extruder" -msgstr "" +msgstr "ekstruder pomocniczy" msgid "Left Extruder" msgstr "Lewy ekstruder" @@ -65,22 +65,22 @@ msgid "right extruder" msgstr "prawy ekstruder" msgid "Main Nozzle" -msgstr "" +msgstr "Główna dysza" msgid "Main nozzle" -msgstr "" +msgstr "Główna dysza" msgid "main nozzle" -msgstr "" +msgstr "główna dysza" msgid "Auxiliary Nozzle" -msgstr "" +msgstr "Dysza pomocnicza" msgid "Auxiliary nozzle" -msgstr "" +msgstr "Dysza pomocnicza" msgid "auxiliary nozzle" -msgstr "" +msgstr "dysza pomocnicza" msgid "Left Nozzle" msgstr "Lewa dysza" @@ -101,52 +101,52 @@ msgid "right nozzle" msgstr "prawej dyszy" msgid "Main Hotend" -msgstr "" +msgstr "Główny hotend" msgid "Main hotend" -msgstr "" +msgstr "Główny hotend" msgid "main hotend" -msgstr "" +msgstr "główny hotend" msgid "Auxiliary Hotend" -msgstr "" +msgstr "Hotend pomocniczy" msgid "Auxiliary hotend" -msgstr "" +msgstr "Hotend pomocniczy" msgid "auxiliary hotend" -msgstr "" +msgstr "hotend pomocniczy" msgid "Left Hotend" -msgstr "" +msgstr "Lewy hotend" msgid "Left hotend" -msgstr "" +msgstr "Lewy hotend" msgid "left hotend" -msgstr "" +msgstr "lewy hotend" msgid "Right Hotend" -msgstr "" +msgstr "Prawy hotend" msgid "Right hotend" -msgstr "" +msgstr "Prawy hotend" msgid "right hotend" -msgstr "" +msgstr "prawy hotend" msgid "main" -msgstr "" +msgstr "główny" msgid "auxiliary" -msgstr "" +msgstr "pomocniczy" msgid "Main" -msgstr "" +msgstr "Główny" msgid "Auxiliary" -msgstr "Auxiliary" +msgstr "Pomocniczy" msgid "left" msgstr "lewo" @@ -192,7 +192,7 @@ msgid "How to feed TPU filament." msgstr "Jak podawać filament TPU." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Jak podawać filament TPU na X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "Użycie filamentu innego niż Bambu może powodować problemy z jakością wydruku." @@ -2660,7 +2660,7 @@ msgid "Assembly" msgstr "Montaż" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "Użycie zmiennej wysokości warstwy w połączeniu z sub-warstwą o mieszanych kolorach może skutkować słabą jakością mieszania kolorów." msgid "Cut Connectors information" msgstr "Usuń informacje o łącznikach" @@ -3048,7 +3048,7 @@ msgstr "Lewy (Aux)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "Lewy (nagrzewanie)" msgctxt "air_duct" msgid "Chamber" @@ -3185,12 +3185,12 @@ msgstr "Ustawianie orientacji" msgid "Filling" msgstr "Wypełnianie" -msgid "Bed filling canceled." -msgstr "Anulowanie wypełniania stołu." - msgid "Bed filling done." msgstr "Wypełnianie stołu zakończone." +msgid "Bed filling canceled." +msgstr "Anulowanie wypełniania stołu." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3495,7 +3495,7 @@ msgstr "Proszę podać prawidłową wartość (K w zakresie %.1f~%.1f, N w %.1f~ #, c-format, boost-format msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." -msgstr "" +msgstr "Uwaga: Numer hotendu na %s jest powiązany z uchwytem. Po przeniesieniu hotendu na nowy uchwyt jego numer zostanie automatycznie zaktualizowany." msgid "" "The nozzle flow is not set. Please set the nozzle flow rate before editing the filament.\n" @@ -3610,7 +3610,7 @@ msgstr "Wybierz spośród następujących filamentów" #, c-format, boost-format msgid "Select filament that installed to the %s" -msgstr "" +msgstr "Wybierz filament zainstalowany w %s" msgid "Left AMS" msgstr "Lewy AMS" @@ -3718,7 +3718,7 @@ msgstr "MOKRY" #, c-format, boost-format msgid "Please select the filament installed on the %s." -msgstr "" +msgstr "Proszę wybrać filament zainstalowany w %s." msgid "Please select the filament." msgstr "Proszę wybrać filament." @@ -3867,6 +3867,9 @@ msgstr "Przepełnienie stosu" msgid "Running post-processing scripts" msgstr "Uruchamianie skryptów post-processing" +msgid "Updating preview with post-processed G-code" +msgstr "Aktualizowanie podglądu po przetworzeniu G-code" + msgid "Successfully executed post-processing script" msgstr "Pomyślnie wykonano skrypt post-processingu" @@ -4088,6 +4091,11 @@ msgid "" "Yes - Enable Arachne wall generator\n" "No - Keep current wall generator and set fuzzy skin to [Displacement] mode" msgstr "" +"Skóra fuzzy [Ekstruzja] i [Kombinacja] wymagają generatora ścian Arachne.\n" +"\n" +"Czy chcesz automatycznie zmienić te ustawienia?\n" +"Tak - Włącz generator ścian Arachne\n" +"Nie - Zachowaj bieżący generator ścian i ustaw fuzzy skin na tryb [Przesunięcie]" msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support Layer Height is on.\n" @@ -4364,34 +4372,34 @@ msgid "Purifying the chamber air" msgstr "Oczyszczanie powietrza w komorze" msgid "Measuring Rotary Attachment" -msgstr "" +msgstr "Pomiar z przystawką obrotową" msgid "The toolhead moves above the purge chute" -msgstr "" +msgstr "Głowica przemieszcza się nad rynnę zsypu na odpady" msgid "Cooling down the nozzle" -msgstr "" +msgstr "Schłodzenie dyszy" msgid "The toolhead moves to the center of the heatbed" -msgstr "" +msgstr "Głowica przemieszcza się do środka stołu" msgid "Active Arc Fitting" -msgstr "" +msgstr "Aktywne dopasowanie łuku" msgid "Hotend Type Detection" -msgstr "" +msgstr "Wykrywanie typu hotendu" msgid "Build plate alignment detection" -msgstr "" +msgstr "Wykrywanie wyrównania płyty roboczej" msgid "Heatbed surface foreign object detection" -msgstr "" +msgstr "Wykrywanie ciał obcych na powierzchni podgrzewanego stołu" msgid "Heatbed underside foreign object detection" -msgstr "" +msgstr "Wykrywanie ciał obcych pod podgrzewanym stołem" msgid "Pre-extrusion before printing" -msgstr "" +msgstr "Wstępne wytłaczanie przed drukowaniem" msgid "Preparing AMS" msgstr "Przygotowanie AMS" @@ -4501,7 +4509,7 @@ msgid "Disable Purification for This Print" msgstr "Wyłącz oczyszczanie dla tego wydruku" msgid "Don't Remind Me" -msgstr "" +msgstr "Nie przypominaj" msgid "Done" msgstr "Gotowe" @@ -4608,6 +4616,9 @@ msgstr "Szerokość ekstruzji" msgid "Fan Speed" msgstr "Prędkość wentylatora" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Przepływ" @@ -4683,6 +4694,9 @@ msgstr "Prędkość (mm/s)" msgid "Fan Speed (%)" msgstr "Prędkość wentylatora (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatura (°C)" @@ -4836,6 +4850,9 @@ msgstr "Czas warstwy: " msgid "Fan Speed: " msgstr "Prędkość wentylatora: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatura: " @@ -4919,6 +4936,9 @@ msgstr "Koło myszy:" msgid "Increase/decrease edit area" msgstr "Zwiększ/zmniejsz obszar edycji" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sekwencja" @@ -5057,20 +5077,20 @@ msgid "Click to Collapse" msgstr "Kliknij, aby zwinąć" msgid "Overview" -msgstr "" +msgstr "Podsumowanie" msgid "Select Plate" msgstr "Wybierz płytę" msgid "Change camera perspective" -msgstr "" +msgstr "Zmień perspektywę kamery" msgid "Go to Wiki" -msgstr "" +msgstr "Przejdź do Wiki" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "Aktualna prędkość montażu: %1%%%, przepływ objętościowy: %2%%%" msgctxt "Camera" msgid "Top" @@ -5132,19 +5152,19 @@ msgid "Size:" msgstr "Rozmiar:" msgid "Isolated objects detected" -msgstr "" +msgstr "Wykryto odizolowane obiekty" msgid "Click to move them closer to the main body." -msgstr "" +msgstr "Kliknij, aby przesunąć je bliżej głównego elementu" msgid "Move closer" -msgstr "" +msgstr "Przesuń bliżej" msgid "The main assembly bounding box is too far from the world origin. Reset assembly relationships and move to origin?" -msgstr "" +msgstr "Główny obszar montażu znajduje się zbyt daleko od początku układu współrzędnych. Czy przywrócić relacje montażu i przesunąć do początku ?" msgid "Reset to origin" -msgstr "" +msgstr "Przywróć początek" #, c-format, boost-format msgid "Conflicts of gcode paths have been found at layer %d. Please separate the conflicted objects farther (%s <-> %s)." @@ -5335,6 +5355,9 @@ msgstr "Wiele urządzeń" msgid "Project" msgstr "Projekt" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Tak" @@ -5477,6 +5500,9 @@ msgstr "Widok z prawej" msgid "Isometric View" msgstr "Widok izometryczny" +msgid "Fit Camera" +msgstr "Dopasuj kamerę" + msgid "Start a new window" msgstr "Uruchom nowe okno" @@ -5501,9 +5527,6 @@ msgstr "Zapisz bieżący projekt do pliku" msgid "Save Project as" msgstr "Zapisz projekt jako" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Zapisz bieżący projekt jako" @@ -6622,6 +6645,18 @@ msgstr "%s ostrzeżenie" msgid "%s has a warning" msgstr "%s ma ostrzeżenie" +msgid "Collapse" +msgstr "Zwiń" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Wykonaj" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s info" @@ -6919,10 +6954,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "Sprawdza obecność wszelkich obiektów na stole roboczym na początku druku, aby uniknąć kolizji." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "Wykrywanie przemieszczenia się drukowanych części" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "Monitoruje element podczas druku i natychmiast powiadamia, jeśli nastąpi jego przesunięcie lub przewrócenie." msgid "Ensures the build plate type and placement are correct." msgstr "Zapewnia poprawny typ i ustawienie płyty roboczej." @@ -7106,7 +7141,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Wykryto filament(y) o wysokim skurczu: %s. Materiały te mogą powodować odchylenia wymiarowe po ostygnięciu. Jeśli Twój model wymaga precyzyjnego dopasowania lub montażu, zapoznaj się z przewodnikiem w Wiki dotyczącym testowania skurczu." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "Drukowanie filamentem w mieszanych kolorach na drukarce z pojedynczym ekstruderem wymaga częstej wymiany filamentu i jego przepłukiwania, co może znacznie zwiększyć ilość odpadów i ryzyko zatkania dyszy/zsypu odpadów." #, boost-format msgid " plate %1%: " @@ -7239,25 +7274,25 @@ msgid "Set filaments to use" msgstr "Ustaw filamenty do użycia" msgid "Add Mixed Filament" -msgstr "" +msgstr "Dodaj filament mieszany" msgid "Mixed Filament" -msgstr "" +msgstr "Filament mieszany" msgid "Add mixed filament" -msgstr "" +msgstr "Dodaj filament mieszany" msgid "Remove last mixed filament" -msgstr "" +msgstr "Usuń ostatni filament mieszany" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "Mieszany filament zawiera nieprawidłowe lub niedopasowane komponenty. Proszę ponownie edytować wpisy, których dotyczy problem." msgid "Search plate, object and part." msgstr "Wyszukaj płytę, obiekt i część." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "Docelowa mieszanka korzysta z tego filamentu jako komponentu. Po jego usunięciu może stać się nieprawidłowa. Kontynuować?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7280,10 +7315,10 @@ msgid "Filament type and color information have been synchronized, but slot info msgstr "Informacje o typie i kolorze filamentu zostały zsynchronizowane, ale brak informacji o gnieździe." msgid "Mixed filament has broken component references" -msgstr "" +msgstr "Odwołania do komponentów w mieszanym filamencie są nieprawidłowe." msgid "Edit / Delete / Merge" -msgstr "" +msgstr "Edytuj / Usuń / Scal" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7305,9 +7340,6 @@ msgstr "" msgid "Restore" msgstr "Przywróć" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "W bieżącym pliku 3mf znajduje się skrypt G-code. Sprawdź zawartość skryptu." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "Aktualna temperatura stołu roboczego jest stosunkowo wysoka. Dysza może się zatkać podczas drukowania tego filamentu w zamkniętej obudowie. Proszę otworzyć drzwi z przodu i/lub usunąć górną szybę." @@ -7387,6 +7419,12 @@ msgstr "Nazwa komponentów w pliku step nie jest w formacie UTF8!" msgid "The name may show garbage characters!" msgstr "Nazwa może wyświetlać nieprawidłowe znaki!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Błąd podczas wczytywania pliku \"%1%\". Znaleziono nieprawidłową konfigurację." @@ -7926,10 +7964,10 @@ msgstr "Zapisz pocięty plik jako:" msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." -msgstr "" +msgstr "Nie udało się wyeksportować pociętego pliku. Sprawdź, czy plik nie jest używany przez inny program oraz czy na dysku jest wystarczająca ilość wolnego miejsca." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "Eksportuj pocięty plik" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7963,9 +8001,14 @@ msgstr "Przyczyna: \"%1%\" i inna nie mają wspólnego przecięcia." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Wykryto części ujemne. Czy chcesz przeprowadzić operacje boole'owskie na siatce przed eksportem?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "Filament kalibracyjny jest obecnie przypisany do innego ekstrudera niż ten wybrany w oknie kalibracji PA (%s). Może to prowadzić do nieprawidłowych wyników kalibracji. Przypisanie można zmienić w ustawieniach grupowania filamentów." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "Nie zaleca się stosowania filamentów PVA z dyszami 0.2 mm." @@ -8024,6 +8067,11 @@ msgstr "Błędny numer" msgid "Plate Settings" msgstr "Ustawienia stołu" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Wieża czyszcząca:" @@ -8285,13 +8333,13 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "Po włączeniu ostatnio używany schemat kolorów (np. typ linii, prędkość) zostanie automatycznie zastosowany przy następnym uruchomieniu." msgid "Display overview" -msgstr "" +msgstr "Podgląd widoku" msgid "Show assembly BVH primary bounds" -msgstr "" +msgstr "Pokaż podstawowe granice montażu BVH" msgid "Display the BVH primary bounding box wireframe in assembly view." -msgstr "" +msgstr "Wyświetlaj siatkę pierwszego prostopadłościanu BVH w widoku montażu." msgid "Improve rendering performance by lod" msgstr "Poprawa wydajności renderowania przy pomocy LOD" @@ -8637,7 +8685,7 @@ msgid "First layer filament sequence" msgstr "Sekwencja filamentu pierwszej warstwy" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "Lista filamentów zawiera mieszane filamenty. Niestandardowa sekwencja filamentów nie zostanie zastosowana." msgid "Same as Global Bed Type" msgstr "Tak samo jak globalny Typ Płyty" @@ -8834,7 +8882,7 @@ msgid "To ensure print quality, the drying temperature will be lowered during pr msgstr "Aby zapewnić jakość wydruku, podczas drukowania temperatura suszenia zostanie obniżona." msgid "Select timelapse storage location" -msgstr "" +msgstr "Wskaż miejsce zapisu timelapse" msgid "" "This checks the flatness of heatbed. Leveling makes extruded height uniform.\n" @@ -8876,6 +8924,10 @@ msgstr "Kod błędu" msgid "Recommended filament arrangement saves %s->" msgstr "Zalecane rozmieszczenie filamentu pozwala zaoszczędzić %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Filament %s nie pasuje do filamentu w gnieździe AMS %s. Zaktualizuj oprogramowanie drukarki, aby obsługiwać przypisywanie gniazd w AMS." @@ -8926,35 +8978,35 @@ msgid "This process determines the dynamic flow values to improve overall print msgstr "Ten proces określa dynamiczne wartości przepływu w celu poprawy ogólnej jakości druku." msgid "Internal" -msgstr "" +msgstr "Wewnętrzna" #, c-format, boost-format msgid "%s space less than 10MB. Timelapse may not save properly. You can turn it off or" -msgstr "" +msgstr "%s ma mniej niż 10 MB wolnego miejsca. Timelapse może nie zostać poprawnie zapisany. Możesz go wyłączyć lub" msgid "Clean up files" -msgstr "" +msgstr "Usuń pliki" msgid "Low internal storage. This timelapse will overwrite the oldest video files." -msgstr "" +msgstr "Mało miejsca na pamięci wewnętrznej. Ten timelapse nadpisze najstarsze pliki wideo." msgid "Low external storage. This timelapse will overwrite the oldest video files." -msgstr "" +msgstr "Mało miejsca na pamięci zewnętrznej. Ten timelapse nadpisze najstarsze pliki wideo." msgid "Insufficient external storage for time-lapse photography. Connect to computer to delete files, or use a larger memory card." -msgstr "" +msgstr "Zbyt mało miejsca w pamięci zewnętrznej dla timelapse. Podłącz do komputera, aby usunąć pliki, lub zastosuj większą kartę pamięci." msgid "Storage Space Not Enough" -msgstr "" +msgstr "Niewystarczająca ilość miejsca w pamięci" msgid "Confirm & Print" -msgstr "" +msgstr "Potwierdź i drukuj" msgid "Cancel Timelapse & Print" -msgstr "" +msgstr "Anuluj Timelapse i wydrukuj" msgid "Clean Up" -msgstr "" +msgstr "Wyczyść" msgid "Auto: If the filament/nozzle of the main extruder hasn't changed, the last calibration value will be reused. The auxiliary extruder will use the system default value." msgstr "Automatycznie: Jeśli filament/dysza głównego ekstrudera nie uległy zmianie, zostanie użyta ostatnia wartość kalibracji. Ekstruder pomocniczy użyje domyślnej wartości systemowej." @@ -9049,7 +9101,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "Bieżąca średnica dyszy (%.1fmm) nie jest zgodna z plikiem cięcia (%.1fmm). Upewnij się, że zainstalowana dysza jest zgodna z ustawieniami drukarki, a następnie ustaw odpowiednie ustawienia drukarki podczas krojenia." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "Zainstalowany w drukarce przełącznik ścieżki filamentu nie odpowiada plikowi cięcia. Wykonaj ponownie cięcie, aby uniknąć problemów z jakością druku." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "Do tego wydruku wymagany jest przełącznik ścieżki filamentu. Najpierw należy go zainstalować." @@ -9084,7 +9136,7 @@ msgid "The hardness of current material (%s) exceeds the hardness of %s (%s). It msgstr "Twardość obecnego materiału (%s) przekracza twardość %s (%s). Może to spowodować zużycie dyszy, co prowadzi do wycieku materiału i niestabilnego przepływu. Podczas korzystania z tego materiału należy zachować ostrożność." msgid "Some filaments may switch between extruders during printing. Manual K-value calibration cannot be applied throughout the entire print, which may affect print quality. Enabling Flow Dynamics Calibration is recommended." -msgstr "" +msgstr "Podczas drukowania niektóre filamenty mogą być przełączane między ekstruderami. Ręczna kalibracja wartości K nie może być stosowana dla całego wydruku, co może wpływać na jego jakość. Zaleca się włączenie kalibracji dynamiki przepływu." msgid "Cool" msgstr "" @@ -9164,9 +9216,6 @@ msgstr "Ustaw dynamiczną kalibrację flow na 'wyłączony' aby włączyć włas msgid "This printer does not support printing all plates" msgstr "Ta drukarka nie obsługuje drukowania wszystkich stołów" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Aktualne firmware obsługuje maksymalnie 16 materiałów. Możesz zmniejszyć ich liczbę do 16 (lub mniej) na stronie przygotowania albo spróbować zaktualizować firmware. Jeśli po aktualizacji ograniczenie nadal występuje, prosimy o cierpliwość i oczekiwanie na kolejne wersje firmware z rozszerzonym wsparciem." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Sprawdź, czy wymagana średnica dyszy i natężenie przepływu odpowiadają aktualnie wyświetlanym wartościom." @@ -9187,7 +9236,7 @@ msgstr "Spróbuj się połączyć" msgctxt "sendtoprint" msgid "Cache" -msgstr "" +msgstr "Pamięć podręczna" msgctxt "sendtoprint" msgid "External" @@ -9428,7 +9477,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "Przy używaniu %s jako materiału podporowego dla %s, zalecamy następujące ustawienia:" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "Przy używaniu PLA jako materiału podporowego dla TPU, zalecamy następujące ustawienia:" @@ -9663,19 +9712,19 @@ msgid "Part cooling fan" msgstr "Wentylator chłodzący wydruk" msgid "Initial layer fan" -msgstr "" +msgstr "Wentylator pierwszej warstwy" msgid "Set the part cooling fan speed for the first few layers. Set to 0 to keep the fan off for better bed adhesion" -msgstr "" +msgstr "Prędkość wentylatora chłodzącego wydruk dla pierwszych kilku warstw. Ustaw na 0, aby wentylator był wyłączony w celu lepszej przyczepności do stołu." msgid "Linear ramp up to" -msgstr "" +msgstr "Wzrost liniowy do" msgid "Fan speed will linearly increase from the initial layer speed to the layer-time-based speed over the specified number of layers" -msgstr "" +msgstr "Prędkość wentylatora będzie wzrastać liniowo od prędkości dla pierwszej warstwy do prędkości opartej na czasie warstwy przez określoną liczbę warstw" msgid "At" -msgstr "" +msgstr "Na" msgid "layers" msgstr "warstwy" @@ -9696,19 +9745,19 @@ msgid "Auxiliary part cooling fan" msgstr "Dodatkowy wentylator chłodzący wydruk" msgid "Set the auxiliary fan speed for the first few layers" -msgstr "" +msgstr "Ustaw prędkość wentylatora pomocniczego dla pierwszych kilku warstw" msgid "Linear ramp up" -msgstr "" +msgstr "Wzrost liniowy" msgid "Auxiliary fan speed will linearly increase from the initial layer speed to the target speed over the specified number of layers" -msgstr "" +msgstr "Prędkość wentylatora pomocniczego będzie wzrastać liniowo od prędkości dla pierwszej warstwy do prędkości opartej na czasie warstwy przez określoną liczbę warstw" msgid "At layer" -msgstr "" +msgstr "Na warstwie" msgid "ramp up to" -msgstr "" +msgstr "zwiększ do" msgid "Exhaust fan" msgstr "Wentylator wyciągowy" @@ -9862,11 +9911,11 @@ msgstr "Skopiuj parametr" #, c-format, boost-format msgid "Modify paramters of %s" -msgstr "" +msgstr "Zmodyfikuj parametry %s" #, c-format, boost-format msgid "Do you want to modify the following parameters of the %s to that of the %s?" -msgstr "" +msgstr "Czy chcesz zmodyfikować następujące parametry %s aby były zgodne z parametrami %s?" msgid "No available nozzles for current preset" msgstr "Brak dostępnych dysz dla aktualnego profilu" @@ -10504,6 +10553,9 @@ msgstr "Widok z kamery - prawa" msgid "Camera view - Isometric" msgstr "Widok z kamery - Izometryczny" +msgid "Camera view - Fit to scene or selection" +msgstr "Widok kamery - dopasuj do sceny lub zaznaczenia" + msgid "Shift+E" msgstr "" @@ -12162,7 +12214,7 @@ msgid "Set special cooling fan for the first certain layers.The part cooling fan msgstr "Ustaw specjalny tryb pracy wentylatora chłodzącego wydruk dla kilku pierwszych warstw. Wentylator chłodzący wydruk dla pierwszej warstwy jest wyłączony, aby uzyskać lepszą przyczepność do płyty roboczej, a później sterowany jest automatycznie." msgid "Part cooling fan speed for the first few layers. Set to 0 to disable the part cooling fan on the initial layers for better bed adhesion" -msgstr "" +msgstr "Prędkość wentylatora chłodzącego wydruk dla pierwszych kilku warstw. Ustaw na 0, aby wyłączyć wentylator chłodzący wydruk dla pierwszych warstw, co zapewnia lepszą przyczepność do podłoża." msgid "Special auxiliary cooling fan speed, effective only for the first x layers" msgstr "Prędkość pomocniczego wentylatora chłodzącego, stosowana jedynie dla pierwszych X warstw." @@ -12636,34 +12688,34 @@ msgid "Support material is commonly used to print support and support interface" msgstr "Materiał podporowy jest powszechnie używany do drukowania podpór i warstw łączących podpory z modelem" msgid "Is mixed filament" -msgstr "" +msgstr "To jest filament mieszany" msgid "Whether this filament slot is a mixed filament composed of multiple physical filaments" -msgstr "" +msgstr "Czy to gniazdo filamentu zawiera mieszankę kilku filamentów" msgid "Mixed filament components" -msgstr "" +msgstr "Komponenty mieszanego filamentu" msgid "Comma-separated 1-based indices of component filaments, e.g. \"1,3\"" -msgstr "" +msgstr "Indeksy poszczególnych filamentów, oddzielone przecinkami i zaczynające się od 1, np. \"1,3\"" msgid "Mixed filament sublayer ratios" -msgstr "" +msgstr "Proporcje sub-warstw w mieszanym filamencie" msgid "Comma-separated ratio values summing to 1.0, e.g. \"0.7,0.3\"" -msgstr "" +msgstr "Wartości proporcji oddzielone przecinkami, których suma wyniesie 1,0, np. \"0,7,0,3\"" msgid "Mixed filament gradient" -msgstr "" +msgstr "Gradient mieszanego filamentu" msgid "Enable Z-direction gradient mode for mixed filament sub-layers. When enabled, the sub-layer ratios vary linearly across layers." -msgstr "" +msgstr "Włącz tryb gradientu w kierunku Z dla sub-warstw mieszanych filamentów. Po włączeniu proporcje sub-warstw zmieniają się liniowo w kolejnych warstwach." msgid "Mixed filament gradient range" -msgstr "" +msgstr "Zakres gradientu mieszanego filamentu" msgid "Start and end ratios for the first component in gradient mode. Comma-separated pair, e.g. \"0.10,0.90\" means 10% to 90%." -msgstr "" +msgstr "Początkowy i końcowy udział pierwszego komponentu w trybie gradientu. Para wartości oddzielona przecinkiem, np. \"0,10,0,90\" oznacza 10%–90%." msgid "Filament printable" msgstr "Filament do druku" @@ -12692,6 +12744,12 @@ msgstr "Objętość materiału wymagana do oczyszczania ekstrudera na wieży, z msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Objętość materiału wymagana do oczyszczania ekstrudera na wieży przed zmianą hotendu." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Chłodzenie wieży czyszczącej" @@ -14271,10 +14329,10 @@ msgid "Describe how long the nozzle will move along the last path when retractin msgstr "Opisuje, jak długo dysza będzie przemieszczać się wzdłuż ostatniej ścieżki podczas retrakcji" msgid "Mixed color sublayer" -msgstr "" +msgstr "Sub-warstwa mieszanych kolorów" msgid "Enable mixed color sublayer splitting. When enabled, layers containing mixed color filaments will be split into sub-layers to achieve color mixing effects." -msgstr "" +msgstr "Włącz podział sub-warstw mieszanych kolorów. Warstwy zawierające mieszane kolory filamentu zostaną rozdzielone na sub-warstwy w celu uzyskania efektu mieszania kolorów." msgid "The wiping tower can be used to clean up the residue on the nozzle and stabilize the chamber pressure inside the nozzle, in order to avoid appearance defects when printing objects." msgstr "Wieża czyszcząca może być używana do oczyszczenia resztek na dyszy i stabilizacji ciśnienia komory wewnątrz dyszy, aby uniknąć wad wyglądu podczas drukowania obiektów." @@ -14992,7 +15050,7 @@ msgstr "" "- Różne marki i rodziny filamentów (Marka = Bambu, Rodzina = Basic, Matte)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux) nie obsługuje automatycznej kalibracji przepływu." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "- Uwaga: Numer hotendu jest powiązany z jego uchwytem. Po przeniesieniu hotendu na inny uchwyt, jego numer zostanie zaktualizowany automatycznie.\n" @@ -15062,7 +15120,7 @@ msgstr "Łączenie z drukarką" #, c-format, boost-format msgid "Calibration only supports cases where the %s and %s diameters are identical." -msgstr "" +msgstr "Kalibracja jest możliwa tylko w przypadkach, gdy średnice %s i %s są identyczne." msgid "From k Value" msgstr "Od wartości k" @@ -15136,7 +15194,7 @@ msgid "PA Calibration" msgstr "Kalibracja PA" msgid "Extruder type" -msgstr "" +msgstr "Typ ekstrudera" msgid "PA Tower" msgstr "Wieża PA" @@ -15370,9 +15428,6 @@ msgstr "Wybrane części" msgid "Keep original models" msgstr "Zachowaj oryginalne modele" -msgid "Execute" -msgstr "Wykonaj" - msgid "Entity Only" msgstr "Tylko element" @@ -15897,9 +15952,6 @@ msgstr "Edytuj Profile" msgid "For more information, please check out Wiki" msgstr "Dla dodatkowych informacji, odwiedź Wiki" -msgid "Collapse" -msgstr "Zwiń" - msgid "Daily Tips" msgstr "Wyświetl Wskazówki" @@ -16544,12 +16596,6 @@ msgstr "Grupowanie filamentów" msgid "Fila Saving" msgstr "Oszczędzanie filamentu" -msgid "Don't remind me again" -msgstr "Nie przypominaj mi ponownie" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Nie pojawi się już żadne wyskakujące okienko. Możesz to zmienić w \"Preferencjach\"" - msgid "Filament-Saving Mode" msgstr "Tryb oszczędzania filamentu" @@ -16564,19 +16610,19 @@ msgstr "Tryb niestandardowy" #, c-format, boost-format msgid "Generates filament grouping for the %s and %s based on the most filament-saving principles to minimize waste" -msgstr "" +msgstr "Generuje grupy filamentów dla %s i %s na podstawie zasad oszczędzania materiału, w celu minimalizacji odpadów." #, c-format, boost-format msgid "Generates filament grouping for the %s and %s based on the printer's actual filament status, reducing the need for manual filament adjustment" -msgstr "" +msgstr "Generuje grupy filamentów dla %s i %s na podstawie rzeczywistego statusu filamentów w drukarce, zmniejszając potrzebę ręcznego dostosowywania filamentu" #, c-format, boost-format msgid "Generates filament grouping for the %s and %s based on quality optimization principles" -msgstr "" +msgstr "Generuje grupy filamentów dla %s i %s na podstawie zasad optymalizacji jakości" #, c-format, boost-format msgid "Manually assign filament to the %s or %s" -msgstr "" +msgstr "Ręcznie przypisz filament do %s lub %s" msgid "Global settings" msgstr "Ustawienia globalne" @@ -16605,10 +16651,7 @@ msgstr " aby ustawić liczbę dysz" #, c-format, boost-format msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" -msgstr "" - -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Metoda grupowania materiału dla obecnej płyty jest zależna od opcji w menu, wyświetlanym po najechaniu na przycisk Potnij aktualną płytę." +msgstr "Generuje grupy filamentów dla %s i %s na podstawie jakości wydruku, koncentrując się na jakości wydruków zamiast na oszczędzaniu filamentu." msgid "Skip Objects" msgstr "Pomiń obiekty" @@ -16828,7 +16871,7 @@ msgid " Please plug in the power and then use the drying function." msgstr " Podłącz zasilanie, a następnie użyj funkcji suszenia." msgid " The high drying temperature may cause AMS blockage. Please unload the filament manually before proceeding." -msgstr "" +msgstr " Wysoka temperatura suszenia może spowodować zablokowanie AMS. Przed kontynuacją należy ręcznie rozładować filament." msgid "System is busy" msgstr "System jest zajęty" @@ -16991,59 +17034,59 @@ msgid "Print Outcome: " msgstr "Rezultat wydruku:" msgid "Edit Mixed Filament" -msgstr "" +msgstr "Edytuj filament mieszany" msgid "Effect Preview" -msgstr "" +msgstr "Podgląd efektu" msgid "Select Mixed Materials" -msgstr "" +msgstr "Wybierz mieszane materiały" msgid "+ Add Material" -msgstr "" +msgstr "+ Dodaj materiał" msgid "- Delete Material" -msgstr "" +msgstr "- Usuń materiał" msgid "Ratio" -msgstr "" +msgstr "Współczynnik" msgid "Gradient Effect" -msgstr "" +msgstr "Efekt gradientu" msgid "Mixing Recommendations" -msgstr "" +msgstr "Rekomendacje dotyczące mieszania" msgid "-- Select --" -msgstr "" +msgstr "-- Wybierz --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "Efekt gradientu wymaga włączenia \"Sub-warstwa mieszanych kolorów\". Włączyć ją teraz?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Sub-warstwa mieszanych kolorów" #, c-format, boost-format msgid "Slot %s (%s)" -msgstr "" +msgstr "Gniazdo %s (%s)" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "nie można mieszać. Proszę wybrać ten sam rodzaj filamentu." msgid "Please select a filament for all components" -msgstr "" +msgstr "Proszę wybrać filament dla wszystkich komponentów" msgid "Cannot mix different filament types" -msgstr "" +msgstr "Nie można mieszać różnych typów filamentu" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Maksymalnie 3 materiały do mieszania" msgid "Maximum number of components reached" -msgstr "" +msgstr "Osiągnięto maksymalną liczbę komponentów" msgid "Remove the third material" -msgstr "" +msgstr "Usuń trzeci materiał" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17333,6 +17376,24 @@ msgstr "" "Niezawodność od pierwszego razu\n" "Mniej nadzoru, bardziej przewidywalne wyniki. Przykład: mała farma drukarek 3D produkująca części z PETG unika niespodzianek typu „awaria po 6 godzinach” i utrzymuje harmonogram partii." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "W bieżącym pliku 3mf znajduje się skrypt G-code. Sprawdź zawartość skryptu." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Aktualne firmware obsługuje maksymalnie 16 materiałów. Możesz zmniejszyć ich liczbę do 16 (lub mniej) na stronie przygotowania albo spróbować zaktualizować firmware. Jeśli po aktualizacji ograniczenie nadal występuje, prosimy o cierpliwość i oczekiwanie na kolejne wersje firmware z rozszerzonym wsparciem." + +#~ msgid "Don't remind me again" +#~ msgstr "Nie przypominaj mi ponownie" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Nie pojawi się już żadne wyskakujące okienko. Możesz to zmienić w \"Preferencjach\"" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Metoda grupowania materiału dla obecnej płyty jest zależna od opcji w menu, wyświetlanym po najechaniu na przycisk Potnij aktualną płytę." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Lewy" diff --git a/bbl/i18n/pt_BR/BambuStudio_pt_BR.po b/bbl/i18n/pt_BR/BambuStudio_pt_BR.po index 253634787e..8f60bea37a 100644 --- a/bbl/i18n/pt_BR/BambuStudio_pt_BR.po +++ b/bbl/i18n/pt_BR/BambuStudio_pt_BR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -51,22 +51,22 @@ msgid "auxiliary extruder" msgstr "extrusora auxiliar" msgid "Left Extruder" -msgstr "Extrusora ESQUERDA" +msgstr "Extrusora Esquerda" msgid "Left extruder" -msgstr "Extrusora ESQUERDA" +msgstr "Extrusora esquerda" msgid "left extruder" -msgstr "Extrusora ESQUERDA" +msgstr "extrusora esquerda" msgid "Right Extruder" -msgstr "Extrusora DIREITA" +msgstr "Extrusora Direita" msgid "Right extruder" -msgstr "Extrusora DIREITA" +msgstr "Extrusora direita" msgid "right extruder" -msgstr "Extrusora DIREITA" +msgstr "extrusora direita" msgid "Main Nozzle" msgstr "Bico Principal" @@ -90,7 +90,7 @@ msgid "Left Nozzle" msgstr " Bico Esquerdo" msgid "Left nozzle" -msgstr " Bico Esquerdo" +msgstr " Bico esquerdo" msgid "left nozzle" msgstr " Bico esquerdo" @@ -123,22 +123,22 @@ msgid "auxiliary hotend" msgstr "hotend auxiliar" msgid "Left Hotend" -msgstr "" +msgstr "Hotend Esquerdo" msgid "Left hotend" -msgstr "" +msgstr "Hotend esquerdo" msgid "left hotend" -msgstr "" +msgstr "hotend esquerdo" msgid "Right Hotend" -msgstr "" +msgstr "Hotend Direito" msgid "Right hotend" -msgstr "" +msgstr "Hotend direito" msgid "right hotend" -msgstr "" +msgstr "hotend direito" msgid "main" msgstr "principal" @@ -196,7 +196,7 @@ msgid "How to feed TPU filament." msgstr "Como alimentar o filamento de TPU" msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Como alimentar o filamento de TPU na X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "O uso de filamento que não seja de bambu pode causar problemas de qualidade na impressão." @@ -2661,7 +2661,7 @@ msgid "Assembly" msgstr "Montagem" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "O uso de altura de camada variável em conjunto com uma subcamada de cores misturadas pode resultar em baixa qualidade na mistura de cores." msgid "Cut Connectors information" msgstr "Informações sobre conectores de corte" @@ -3047,7 +3047,7 @@ msgstr "Esquerdo (Aux)" msgctxt "air_duct" msgid "Left(Heating)" -msgstr "" +msgstr "Esquerda (Aquecimento)" msgctxt "air_duct" msgid "Chamber" @@ -3184,12 +3184,12 @@ msgstr "Orientando" msgid "Filling" msgstr "Preenchendo" -msgid "Bed filling canceled." -msgstr "O enchimento da cama foi cancelado." - msgid "Bed filling done." msgstr "Enchimento da cama feito." +msgid "Bed filling canceled." +msgstr "O enchimento da cama foi cancelado." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3866,6 +3866,9 @@ msgstr "Estouro de pilha" msgid "Running post-processing scripts" msgstr "Executando scripts de pós-processamento" +msgid "Updating preview with post-processed G-code" +msgstr "Atualizando a pré-visualização com o código G pós-processado." + msgid "Successfully executed post-processing script" msgstr "Script de pós-processamento executado com sucesso" @@ -4612,6 +4615,9 @@ msgstr "Largura da linha" msgid "Fan Speed" msgstr "Velocidade do ventilador" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Fluxo" @@ -4687,6 +4693,9 @@ msgstr "Velocidade (mm/s)" msgid "Fan Speed (%)" msgstr "Velocidade do ventilador (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatura (°C)" @@ -4840,6 +4849,9 @@ msgstr "Tempo da camada: " msgid "Fan Speed: " msgstr "Velocidade do ventilador: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatura: " @@ -4923,6 +4935,9 @@ msgstr "Roda do mouse:" msgid "Increase/decrease edit area" msgstr "Aumentar/diminuir a área de edição" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sequência" @@ -5067,14 +5082,14 @@ msgid "Select Plate" msgstr "Selecione a placa" msgid "Change camera perspective" -msgstr "" +msgstr "Alterar a perspectiva da câmera" msgid "Go to Wiki" msgstr "Ir para Wiki" #, boost-format msgid "Current assembly rate: %1%%%, volume rate: %2%%%" -msgstr "" +msgstr "Taxa de montagem atual: %1%%%, taxa de volume: %2%%%" msgctxt "Camera" msgid "Top" @@ -5136,7 +5151,7 @@ msgid "Size:" msgstr "Tamanho:" msgid "Isolated objects detected" -msgstr "" +msgstr "Objetos isolados detectados" msgid "Click to move them closer to the main body." msgstr "Clique para movê-los para mais perto do corpo principal." @@ -5339,6 +5354,9 @@ msgstr "Vários dispositivos" msgid "Project" msgstr "Projeto" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Sim" @@ -5481,6 +5499,9 @@ msgstr "Vista direita" msgid "Isometric View" msgstr "Visão isométrica" +msgid "Fit Camera" +msgstr "Ajustar câmera" + msgid "Start a new window" msgstr "Iniciar uma nova janela" @@ -5505,9 +5526,6 @@ msgstr "Salvar projeto atual em arquivo" msgid "Save Project as" msgstr "Salvar projeto como" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Salvar projeto atual como" @@ -6623,6 +6641,18 @@ msgstr "%s aviso" msgid "%s has a warning" msgstr "%s tem um aviso" +msgid "Collapse" +msgstr "Recolher" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Executar" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s informações" @@ -6916,10 +6946,10 @@ msgid "Checks for any objects on the build plate at the start of a print to avoi msgstr "Verifica se há objetos sobre a mesa de impressão no início da impressão para evitar colisões." msgid "Printed Part Displacement Detection" -msgstr "" +msgstr "Detecção de deslocamento de peças impressas" msgid "Monitors the printed part during printing and alerts immediately if it shifts or collapses." -msgstr "" +msgstr "Monitora a peça impressa durante o processo de impressão e emite um alerta imediato caso ela se desloque ou sofra algum colapso." msgid "Ensures the build plate type and placement are correct." msgstr "Garante que o tipo e o posicionamento da mesa de construção estejam corretos." @@ -7103,7 +7133,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Filamentos com alta taxa de retração detectados: %s. Esses materiais podem causar desvios dimensionais após o resfriamento. Se o seu modelo exigir encaixe ou montagem precisos, consulte o guia da Wiki para testes de retração." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "A impressão com filamento de cores misturadas em uma impressora de extrusão única exige trocas frequentes de filamento e limpeza do sistema, o que pode aumentar significativamente o desperdício e o risco de entupimento do bico/duto de descarte." #, boost-format msgid " plate %1%: " @@ -7248,13 +7278,13 @@ msgid "Remove last mixed filament" msgstr "Remova o último filamento misto" msgid "Mixed filament has invalid or mismatched components. Please re-edit affected entries." -msgstr "" +msgstr "A mistura de filamentos contém componentes inválidos ou incompatíveis. Por favor, edite novamente as entradas afetadas." msgid "Search plate, object and part." msgstr "Placa de busca, objeto e peça." msgid "The target mixed filament uses this physical filament as a component. Merging will remove this physical filament and may invalidate the mixed filament. Continue?" -msgstr "" +msgstr "O filamento misto alvo utiliza este filamento físico como componente. A fusão removerá este filamento físico e poderá invalidar o filamento misto. Continuar?" #, c-format, boost-format msgid "After completing your operation, %s project will be closed and create a new project." @@ -7280,7 +7310,7 @@ msgid "Mixed filament has broken component references" msgstr "Filamento misto possui referências de componentes quebradas" msgid "Edit / Delete / Merge" -msgstr "" +msgstr "Editar / Excluir / Mesclar" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -7302,9 +7332,6 @@ msgstr "" msgid "Restore" msgstr "Restaurar" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "Existe um script G-code presente no arquivo 3mf atual; verifique o conteúdo do script." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "A temperatura atual da cama quente é relativamente alta. O bocal pode ficar entupido ao imprimir esse filamento em um compartimento fechado. Abra a porta frontal e/ou remova o vidro superior." @@ -7384,6 +7411,12 @@ msgstr "O nome dos componentes dentro do arquivo de etapas não está no formato msgid "The name may show garbage characters!" msgstr "O nome pode mostrar caracteres inúteis!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Falha ao carregar o arquivo \"%1%”. Foi encontrada uma configuração inválida." @@ -7924,9 +7957,11 @@ msgid "" "Failed to export the sliced file.\n" "Please check whether the file is occupied by another program or if there is enough disk space." msgstr "" +"Falha ao exportar o arquivo fatiado.\n" +"Verifique se o arquivo está sendo usado por outro programa ou se há espaço suficiente em disco." msgid "Export sliced file" -msgstr "Export Sliced File" +msgstr "Exportar arquivo fatiado" #, c-format, boost-format msgid "The file %s has been sent to the printer's storage space and can be viewed on the printer." @@ -7960,9 +7995,14 @@ msgstr "Motivo: \"%1%\" e outra parte não tem interseção." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Peças negativas detectadas. Gostaria de executar a malha booleana antes de exportar?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." -msgstr "" +msgstr "O filamento de calibração está atualmente atribuído a uma extrusora diferente da selecionada na caixa de diálogo de Calibração de PA (%s). Isso pode levar a resultados de calibração incorretos. Você pode alterar a atribuição nas configurações de agrupamento de filamentos." msgid "It is not recommended to use PVA filaments with 0.2mm nozzles." msgstr "Não é recomendado usar filamentos de PVA com bicos de 0,2 mm." @@ -8021,6 +8061,11 @@ msgstr "Número inválido" msgid "Plate Settings" msgstr "Configurações da placa" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Torre de purga" @@ -8282,7 +8327,7 @@ msgid "When enabled, the last used color scheme (e.g., Line Type, Speed) will be msgstr "Quando habilitado, o último esquema de cores usado (por exemplo, Tipo de Linha, Velocidade) será aplicado automaticamente na próxima inicialização." msgid "Display overview" -msgstr "" +msgstr "Visão geral da exibição" msgid "Show assembly BVH primary bounds" msgstr "Mostrar limites primários da BVH da montagem" @@ -8634,7 +8679,7 @@ msgid "First layer filament sequence" msgstr "Sequência de filamentos da primeira camada" msgid "The filament list contains mixed filaments. Custom filament sequence will not take effect." -msgstr "" +msgstr "A lista de filamentos contém filamentos mistos. A sequência de filamentos personalizada não terá efeito." msgid "Same as Global Bed Type" msgstr "Igual ao Global Plate Type" @@ -8873,6 +8918,10 @@ msgstr "Código de erro" msgid "Recommended filament arrangement saves %s->" msgstr "A disposição recomendada dos filamentos economiza %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "O filamento %s não corresponde ao filamento no slot AMS. %s Atualize o firmware da impressora para suportar a atribuição de slots AMS." @@ -9044,7 +9093,7 @@ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file msgstr "O diâmetro atual do bico (%.1fmm) não corresponde ao arquivo de fatiamento (%.1fmm). Certifique-se de que o bico instalado corresponde às configurações na impressora e, em seguida, defina a predefinição da impressora correspondente ao fatiar." msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." -msgstr "" +msgstr "O interruptor de rastreamento de filamento instalado na impressora não corresponde ao arquivo de fatiamento. Por favor, fatie novamente para evitar problemas de qualidade de impressão." msgid "This print requires a Filament Track Switch. Please install it first." msgstr "Esta impressão requer um interruptor de rastreamento de filamento. Instale-o primeiro." @@ -9159,9 +9208,6 @@ msgstr "Defina a calibração dinâmica do fluxo como 'OFF' para ativar o valor msgid "This printer does not support printing all plates" msgstr "Esta impressora não suporta a impressão de todas as chapas" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "O firmware atual suporta no máximo 16 materiais. Você pode reduzir o número de materiais para 16 ou menos na Página de Preparação ou tentar atualizar o firmware. Se ainda houver restrições após a atualização, aguarde o suporte do firmware subsequente." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Por favor, verifique se o diâmetro do bico e a taxa de fluxo necessários correspondem à exibição atual." @@ -9423,7 +9469,7 @@ msgstr "" #, c-format, boost-format msgid "When using %s to support %s, We recommend the following settings:" -msgstr "" +msgstr "Ao usar %s para dar suporte a %s, recomendamos as seguintes configurações:" msgid "When using PLA to support TPU, We recommend the following settings:" msgstr "Ao usar PLA para dar suporte ao TPU, recomendamos as seguintes configurações:" @@ -10494,6 +10540,9 @@ msgstr "Visão da câmera - Direita" msgid "Camera view - Isometric" msgstr "Visão da câmera - Isométrica" +msgid "Camera view - Fit to scene or selection" +msgstr "Visão da câmera - Ajustar à cena ou à seleção" + msgid "Shift+E" msgstr "" @@ -12675,6 +12724,12 @@ msgstr "O volume de material necessário para priming do extrusor na torre, excl msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "O volume de material necessário para preparar o extrusor para uma troca do hotend na torre." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Resfriamento da torre de limpeza" @@ -14972,7 +15027,7 @@ msgstr "" "- Diferentes marcas e famílias de filament (Marca = Bambu, Família = Básico, Fosco)\n" msgid "(Aux) does not support automatic flow calibration." -msgstr "" +msgstr "(Aux) não suporta calibração automática de fluxo." msgid "- Note: The hotend's number is tied to the holder. When the hotend is moved to a new holder, its number will update automatically.\n" msgstr "- Nota: O número do hotend está vinculado ao suporte. Quando o hotend é movido para um novo suporte, seu número será atualizado automaticamente.\n" @@ -15116,7 +15171,7 @@ msgid "PA Calibration" msgstr "Calibração PA" msgid "Extruder type" -msgstr "" +msgstr "Tipo de extrusora" msgid "PA Tower" msgstr "Torre PA" @@ -15350,9 +15405,6 @@ msgstr "Peças Selecionadas" msgid "Keep original models" msgstr "Manter modelos originais" -msgid "Execute" -msgstr "Executar" - msgid "Entity Only" msgstr "Somente Entidade" @@ -15875,9 +15927,6 @@ msgstr "Editar receita" msgid "For more information, please check out Wiki" msgstr "Para obter mais informações, consulte o Wiki" -msgid "Collapse" -msgstr "Recolher" - msgid "Daily Tips" msgstr "Dicas diárias" @@ -16524,12 +16573,6 @@ msgstr "Agrupamento de filamentos" msgid "Fila Saving" msgstr "Salvando Arquivos" -msgid "Don't remind me again" -msgstr "Não me lembre novamente" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Nenhum outro pop-up aparecerá. Você pode reabri-lo em 'Preferências'" - msgid "Filament-Saving Mode" msgstr "Modo de economia de filamento" @@ -16587,9 +16630,6 @@ msgstr " para definir a contagem de bicos" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Gera agrupamento de filamentos para %s e %s com base na qualidade das impressões, priorizando a qualidade de impressão em detrimento da economia de filamento." -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "O método de agrupamento de filamentos para a placa atual é determinado pela opção suspensa no botão de placa de corte." - msgid "Skip Objects" msgstr "Ignorar objetos" @@ -16971,59 +17011,59 @@ msgid "Print Outcome: " msgstr "Resultado da impressão: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Editar Filamento Misto" msgid "Effect Preview" -msgstr "" +msgstr "Pré-visualização de efeito" msgid "Select Mixed Materials" -msgstr "" +msgstr "Selecione Materiais Mistos" msgid "+ Add Material" -msgstr "" +msgstr "+ Adicionar material" msgid "- Delete Material" -msgstr "" +msgstr "- Excluir material" msgid "Ratio" -msgstr "" +msgstr "Razão" msgid "Gradient Effect" -msgstr "" +msgstr "Efeito de gradiente" msgid "Mixing Recommendations" -msgstr "" +msgstr "Recomendações de mistura" msgid "-- Select --" -msgstr "" +msgstr "-- Selecionar --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "O efeito de gradiente requer que a opção 'Subcamada de cores mistas' esteja ativada. Deseja ativá-la agora?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Subcamada de Cor Mista" #, c-format, boost-format msgid "Slot %s (%s)" msgstr "" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "não podem ser misturados. Por favor, selecione o mesmo tipo de filamento." msgid "Please select a filament for all components" -msgstr "" +msgstr "Selecione um filamento para todos os componentes" msgid "Cannot mix different filament types" -msgstr "" +msgstr "Não é possível misturar diferentes tipos de filamento." msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Máximo de 3 materiais para misturar" msgid "Maximum number of components reached" -msgstr "" +msgstr "Número máximo de componentes atingido" msgid "Remove the third material" -msgstr "" +msgstr "Remover o terceiro material" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17313,6 +17353,24 @@ msgstr "" "Confiabilidade na Primeira Tentativa\n" "Menos supervisão, saída mais previsível. Exemplo: uma pequena fazenda produzindo peças de PETG evita surpresas de \"falha na hora 6\" e mantém os lotes no cronograma." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "Existe um script G-code presente no arquivo 3mf atual; verifique o conteúdo do script." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "O firmware atual suporta no máximo 16 materiais. Você pode reduzir o número de materiais para 16 ou menos na Página de Preparação ou tentar atualizar o firmware. Se ainda houver restrições após a atualização, aguarde o suporte do firmware subsequente." + +#~ msgid "Don't remind me again" +#~ msgstr "Não me lembre novamente" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Nenhum outro pop-up aparecerá. Você pode reabri-lo em 'Preferências'" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "O método de agrupamento de filamentos para a placa atual é determinado pela opção suspensa no botão de placa de corte." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Esquerda" diff --git a/bbl/i18n/ru/BambuStudio_ru.po b/bbl/i18n/ru/BambuStudio_ru.po index 43122b713b..8c29e113d3 100644 --- a/bbl/i18n/ru/BambuStudio_ru.po +++ b/bbl/i18n/ru/BambuStudio_ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio 2.0.2 Public Release\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: 2025-04-22 16:37+0700\n" "Last-Translator: \n" "Language-Team: Andylg \n" @@ -3242,12 +3242,12 @@ msgstr "Ориентация" msgid "Filling" msgstr "Заполнение стола" -msgid "Bed filling canceled." -msgstr "Заполнение стола отменено." - msgid "Bed filling done." msgstr "Заполнение стола закончено." +msgid "Bed filling canceled." +msgstr "Заполнение стола отменено." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3936,6 +3936,9 @@ msgstr "Переполнение стека" msgid "Running post-processing scripts" msgstr "Запуск скриптов постобработки" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "Скрипт постобработки успешно выполнен." @@ -4670,6 +4673,9 @@ msgstr "Ширина экструзии" msgid "Fan Speed" msgstr "Скорость вентилятора" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Поток" @@ -4747,6 +4753,9 @@ msgstr "Скорость (мм/с)" msgid "Fan Speed (%)" msgstr "Скорость вентилятора (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Температура (°C)" @@ -4907,6 +4916,9 @@ msgstr "Время печати слоя: " msgid "Fan Speed: " msgstr "Скорость вентилятора: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Температура: " @@ -4990,6 +5002,9 @@ msgstr "Колесо мыши:" msgid "Increase/decrease edit area" msgstr "Увелич. /уменьш. области редактирования" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Последовательность" @@ -5415,6 +5430,9 @@ msgstr "Принтеры" msgid "Project" msgstr "Проект" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Да" @@ -5556,6 +5574,9 @@ msgstr "Вид справа" msgid "Isometric View" msgstr "" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "Открыть новое окно" @@ -5580,9 +5601,6 @@ msgstr "Сохранить текущий проект в файл" msgid "Save Project as" msgstr "Сохранить проект как" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Сохранить текущий проект как" @@ -6713,6 +6731,18 @@ msgstr "Предупреждение %s" msgid "%s has a warning" msgstr "Предупреждение %s" +msgid "Collapse" +msgstr "Свернуть " + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "Информация %s" @@ -7404,9 +7434,6 @@ msgstr "" msgid "Restore" msgstr "Восстановить" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "Текущая температура стола довольно высока. При печати этим материалом в закрытом корпусе возможно засорение сопла. Откройте переднюю дверцу и/или верхнюю крышку принтера." @@ -7486,6 +7513,12 @@ msgstr "Имена компонентов внутри step файла не в msgid "The name may show garbage characters!" msgstr "В названии могут присутствовать ненужные символы!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Не удалось загрузить файл \"%1%\". Обнаружена недопустимая конфигурация." @@ -8044,6 +8077,11 @@ msgstr "Причина: \"%1%\" и другая часть не пересека msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Обнаружены отрицательные части. Хотите выполнить булевую проверку сетки перед экспортом?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -8108,6 +8146,11 @@ msgstr "Неправильное числовое значение" msgid "Plate Settings" msgstr "Настройки печатной пластины" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Черновая башня:" @@ -8991,6 +9034,10 @@ msgstr "Код ошибки" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Материал %s не соответствует материалу в слоте %s АСПП. Обновите прошивку принтера, чтобы получить поддержку функции назначения слотов АСПП." @@ -9282,9 +9329,6 @@ msgstr "Чтобы задать пользовательское значени msgid "This printer does not support printing all plates" msgstr "Данный принтер не поддерживает печать на всех типах печатных пластин." -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "" @@ -10650,6 +10694,9 @@ msgstr "" msgid "Camera view - Isometric" msgstr "" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12824,6 +12871,12 @@ msgstr "" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "" @@ -15539,9 +15592,6 @@ msgstr "" msgid "Keep original models" msgstr "" -msgid "Execute" -msgstr "" - msgid "Entity Only" msgstr "" @@ -16080,9 +16130,6 @@ msgstr "Изменить профиль" msgid "For more information, please check out Wiki" msgstr "Более подробно читайте на сайте -> " -msgid "Collapse" -msgstr "Свернуть " - msgid "Daily Tips" msgstr "Ежедневные советы " @@ -16729,12 +16776,6 @@ msgstr "Группировка материала" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "Больше не напоминать" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Больше всплывающее окно не появится. Вы можете включить это обратно в параметрах программы." - # Режим экономии материала msgid "Filament-Saving Mode" msgstr "Режим экономии" @@ -16795,9 +16836,6 @@ msgstr "" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Метод группировки пластиковых нитей для текущей пластины устанавливается через выпадающее меню на кнопке «Нарезать стол»." - msgid "Skip Objects" msgstr "" @@ -17497,6 +17535,18 @@ msgid "" "Less babysitting, more predictable output. Example: a small farm running PETG parts avoids 'fail at hour 6' surprises and keeps batches on schedule." msgstr "" +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "Don't remind me again" +#~ msgstr "Больше не напоминать" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Больше всплывающее окно не появится. Вы можете включить это обратно в параметрах программы." + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Метод группировки пластиковых нитей для текущей пластины устанавливается через выпадающее меню на кнопке «Нарезать стол»." + #, c-format, boost-format #~ msgid "Left nozzle: %smm" #~ msgstr "Левое сопло: %s мм" diff --git a/bbl/i18n/sv/BambuStudio_sv.po b/bbl/i18n/sv/BambuStudio_sv.po index 8d64a694d0..0b7cd7791d 100644 --- a/bbl/i18n/sv/BambuStudio_sv.po +++ b/bbl/i18n/sv/BambuStudio_sv.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -189,7 +189,7 @@ msgid "How to feed TPU filament." msgstr "Hur man matar TPU filament." msgid "How to feed TPU filament on X2D." -msgstr "" +msgstr "Hur man matar TPU filament på X2D." msgid "Using non-bambu filament may have printing quality issues." msgstr "Användning av icke bambu filament kan ha problem med utskriftskvaliteten." @@ -2654,7 +2654,7 @@ msgid "Assembly" msgstr "Montering" msgid "Using variable layer height together with mixed color sublayer may result in poor color mixing quality." -msgstr "" +msgstr "Att använda variabel lagerhöjd tillsammans med ett underlager med blandade färger kan resultera i dålig färgblandnings kvalitet." msgid "Cut Connectors information" msgstr "Information om kontakter" @@ -3177,12 +3177,12 @@ msgstr "Placerar" msgid "Filling" msgstr "Fyllnad" -msgid "Bed filling canceled." -msgstr "Byggplattans fyllning avbruten." - msgid "Bed filling done." msgstr "Byggplattans fyllning utförd." +msgid "Bed filling canceled." +msgstr "Byggplattans fyllning avbruten." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3859,6 +3859,9 @@ msgstr "Lagra överflöde" msgid "Running post-processing scripts" msgstr "Kör efterbearbetnings skript" +msgid "Updating preview with post-processed G-code" +msgstr "Uppdaterar förhandsgranskning med efterbearbetad G kod" + msgid "Successfully executed post-processing script" msgstr "Framgångsrikt utfört efterbehandlingsskript" @@ -4606,6 +4609,9 @@ msgstr "Linjebredd" msgid "Fan Speed" msgstr "Fläkt Hastighet" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Flöde" @@ -4681,6 +4687,9 @@ msgstr "Hastighet (mm/s)" msgid "Fan Speed (%)" msgstr "Fläkt hastighet (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Temperatur (°C)" @@ -4834,6 +4843,9 @@ msgstr "Lager Tid: " msgid "Fan Speed: " msgstr "Fläkthastighet: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Temperatur: " @@ -4917,6 +4929,9 @@ msgstr "Mus hjul:" msgid "Increase/decrease edit area" msgstr "Öka/minska redigeringsområdet" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sekvens" @@ -5333,6 +5348,9 @@ msgstr "Flera enheter" msgid "Project" msgstr "Projekt" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Ja" @@ -5475,6 +5493,9 @@ msgstr "Vy Höger" msgid "Isometric View" msgstr "Isometrisk vy" +msgid "Fit Camera" +msgstr "Anpassa kamera" + msgid "Start a new window" msgstr "Starta ett nytt fönster" @@ -5499,9 +5520,6 @@ msgstr "Spara nuvarande projekt till fil" msgid "Save Project as" msgstr "Spara Projekt som" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Spara nuvarande projekt som" @@ -6617,6 +6635,18 @@ msgstr "%s varning" msgid "%s has a warning" msgstr "%s har en varning" +msgid "Collapse" +msgstr "Komprimera" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Utför" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s info" @@ -7097,7 +7127,7 @@ msgid "High-shrinkage filament(s) detected: %s. These materials may cause dimens msgstr "Detekterat filament med hög krympning: %s. Dessa material kan orsaka dimensionsavvikelser efter kylning. Om din modell kräver exakt passform eller montering, se Wiki-guiden för krympningstestning." msgid "Printing mixed-color filament on a single-extruder printer requires frequent filament changes and flushing, which may significantly increase waste and the risk of nozzle / waste-chute clogging." -msgstr "" +msgstr "Att skriva ut blandfärgade filament på en printer med en extruder kräver frekventa filament byten och rensning, vilket kan öka spill och risken för igensättning av nozzle/avfallsrännan avsevärt." #, boost-format msgid " plate %1%: " @@ -7294,9 +7324,6 @@ msgstr "" msgid "Restore" msgstr "Återställ" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "Det finns ett G-kod skript i den aktuella 3mf filen, verifiera innehållet i skriptet." - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass." @@ -7376,6 +7403,12 @@ msgstr "Komponent namnet i step filen är inte UTF8 format!" msgid "The name may show garbage characters!" msgstr "Namnet kan visa skräptecken!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Laddning av fil misslyckades \"%1%\". En ogiltlig konfiguration hittades." @@ -7954,6 +7987,11 @@ msgstr "Orsak: \"%1%\" och en annan del har ingen korsning." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Negativa delar upptäckta. Vill du utföra boolean av mesh före export?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "Kalibrerings filamentet är för närvarande tilldelat en annan extruder än den som valts i PA kalibrerings dialogrutan (%s). Detta kan leda till felaktiga kalibrerings resultat. Du kan ändra tilldelningen i inställningarna för filament gruppering." @@ -8015,6 +8053,11 @@ msgstr "Ogiltligt nummer" msgid "Plate Settings" msgstr "Inställningar för platta" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "" @@ -8867,6 +8910,10 @@ msgstr "Felkod" msgid "Recommended filament arrangement saves %s->" msgstr "Rekommenderat filament arrangemang sparar %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Filamentet %s matchar inte filamentet i AMS-facket %s. Uppdatera skrivarens programvara för att stödja tilldelning av AMS-fack." @@ -9155,9 +9202,6 @@ msgstr "Ställ in dynamiskt flödes kalibrering till \"OFF\" för att aktivera a msgid "This printer does not support printing all plates" msgstr "Den här skrivaren stöder inte utskrift av alla byggplattor" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Nuvarande firmware stöder maximalt 16 material. Du kan antingen minska antalet material till 16 eller färre på Berednings sidan eller prova att uppdatera firmware. Om du fortfarande är begränsad efter uppdateringen, vänta på följande stöd i firmware." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "Kontrollera om den erforderlig nozzle diameter och flödeshastighet matchar aktuell visning." @@ -10490,6 +10534,9 @@ msgstr "Kamera vy - Höger" msgid "Camera view - Isometric" msgstr "Kamera vy - Isometrisk" +msgid "Camera view - Fit to scene or selection" +msgstr "Kamera vy - Anpassa till scen eller markering" + msgid "Shift+E" msgstr "" @@ -12671,6 +12718,12 @@ msgstr "Den materialvolym som krävs för att prima extrudern på tower, exklusi msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "Volymen av material som krävs för att prima extrudern för en hotend förändring på tower." +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "Wipe Tower kylning" @@ -15351,9 +15404,6 @@ msgstr "Valda delar" msgid "Keep original models" msgstr "Behåll original modellerna" -msgid "Execute" -msgstr "Utför" - msgid "Entity Only" msgstr "Endast enhet" @@ -15876,9 +15926,6 @@ msgstr "Redigera inställningar" msgid "For more information, please check out Wiki" msgstr "For more information, please check out our Wiki" -msgid "Collapse" -msgstr "Komprimera" - msgid "Daily Tips" msgstr "Dagliga tips" @@ -16521,12 +16568,6 @@ msgstr "Filament gruppering" msgid "Fila Saving" msgstr "Filament besparing" -msgid "Don't remind me again" -msgstr "Påminn mig inte igen" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Inget ytterligare popup-fönster kommer att visas. Du kan uppdatera detta i \"Inställningar\"" - msgid "Filament-Saving Mode" msgstr "Filament sparande läge" @@ -16584,9 +16625,6 @@ msgstr " för att ange antal nozzle" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "Genererar filament gruppering för %s och %s baserat på utskrifternas kvalitet, med prioritet för utskriftskvalitet framför filament besparing" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Grupperings metoden för filament för plattan bestäms av rullgardins alternativet vid beredning plattan knappen." - msgid "Skip Objects" msgstr "Hoppa över objekt" @@ -16968,59 +17006,59 @@ msgid "Print Outcome: " msgstr "Utskrifts resultat: " msgid "Edit Mixed Filament" -msgstr "" +msgstr "Redigera blandat filament" msgid "Effect Preview" -msgstr "" +msgstr "Förhandsgranska effekt" msgid "Select Mixed Materials" -msgstr "" +msgstr "Välj blandade material" msgid "+ Add Material" -msgstr "" +msgstr "+ Lägg till material" msgid "- Delete Material" -msgstr "" +msgstr "- Ta bort material" msgid "Ratio" -msgstr "" +msgstr "Förhållande" msgid "Gradient Effect" -msgstr "" +msgstr "Gradient effekt" msgid "Mixing Recommendations" -msgstr "" +msgstr "Blandnings rekommendationer" msgid "-- Select --" -msgstr "" +msgstr "-- Välj --" msgid "Gradient effect requires 'Mixed color sublayer' to be enabled. Enable it now?" -msgstr "" +msgstr "För att kunna använda gradient effekten måste \"Underlager med blandade färger\" vara aktiverat. Vill du aktivera det nu?" msgid "Mixed Color Sublayer" -msgstr "" +msgstr "Blandade färger i underlager" #, c-format, boost-format msgid "Slot %s (%s)" -msgstr "" +msgstr "Fack %s (%s)" msgid "cannot be mixed. Please select the same filament type." -msgstr "" +msgstr "kan inte blandas. Välj samma filament typ." msgid "Please select a filament for all components" -msgstr "" +msgstr "Välj ett filament för alla komponenter" msgid "Cannot mix different filament types" -msgstr "" +msgstr "Kan inte blanda olika filament typer" msgid "Maximum 3 materials for mixing" -msgstr "" +msgstr "Max 3 material för blandning" msgid "Maximum number of components reached" -msgstr "" +msgstr "Max antal komponenter uppnått" msgid "Remove the third material" -msgstr "" +msgstr "Ta bort det tredje materialet" #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -17310,6 +17348,24 @@ msgstr "" "Tillförlitlighet vid första försöket\n" "Mindre barnpassning, mer förutsägbar produktion. Exempel: en liten farm som kör PETG delar undviker överraskningar med \"fel vid timme 6\" och håller batcherna enligt schemat." +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "Det finns ett G-kod skript i den aktuella 3mf filen, verifiera innehållet i skriptet." + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Nuvarande firmware stöder maximalt 16 material. Du kan antingen minska antalet material till 16 eller färre på Berednings sidan eller prova att uppdatera firmware. Om du fortfarande är begränsad efter uppdateringen, vänta på följande stöd i firmware." + +#~ msgid "Don't remind me again" +#~ msgstr "Påminn mig inte igen" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Inget ytterligare popup-fönster kommer att visas. Du kan uppdatera detta i \"Inställningar\"" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Grupperings metoden för filament för plattan bestäms av rullgardins alternativet vid beredning plattan knappen." + #~ msgctxt "FilamentTrack" #~ msgid "Left" #~ msgstr "Vänster" diff --git a/bbl/i18n/tr/BambuStudio_tr.po b/bbl/i18n/tr/BambuStudio_tr.po index 177c017afb..09371bd484 100644 --- a/bbl/i18n/tr/BambuStudio_tr.po +++ b/bbl/i18n/tr/BambuStudio_tr.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: 2025-10-16 12:27+0300\n" "Last-Translator: Fatih AYDIN \n" "Language-Team: \n" @@ -3182,12 +3182,12 @@ msgstr "Yönlendiriliyor" msgid "Filling" msgstr "Dolduruluyor" -msgid "Bed filling canceled." -msgstr "Yatak dolumu iptal edildi." - msgid "Bed filling done." msgstr "Yatak doldurma işlemi tamamlandı." +msgid "Bed filling canceled." +msgstr "Yatak dolumu iptal edildi." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3864,6 +3864,9 @@ msgstr "Stack overflow" msgid "Running post-processing scripts" msgstr "İşlem sonrası komut dosyalarını çalıştırma" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "İşlem sonrası komut dosyası başarıyla yürütüldü" @@ -4598,6 +4601,9 @@ msgstr "Katman Genişliği" msgid "Fan Speed" msgstr "Fan hızı" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Akış" @@ -4673,6 +4679,9 @@ msgstr "Hız (mm/s)" msgid "Fan Speed (%)" msgstr "Fan hızı (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Sıcaklık (°C)" @@ -4826,6 +4835,9 @@ msgstr "Katman Süresi: " msgid "Fan Speed: " msgstr "Fan Hızı: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Sıcaklık: " @@ -4909,6 +4921,9 @@ msgstr "Fare tekerleği:" msgid "Increase/decrease edit area" msgstr "Düzenleme alanını artır/azalt" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Sekans" @@ -5325,6 +5340,9 @@ msgstr "Çoklu cihaz" msgid "Project" msgstr "Proje" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Evet" @@ -5463,6 +5481,9 @@ msgstr "Sağdan Görünüm" msgid "Isometric View" msgstr "İzometrik Görünüm" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "Yeni pencere" @@ -5487,9 +5508,6 @@ msgstr "Mevcut projeyi dosyaya kaydet" msgid "Save Project as" msgstr "Projeyi farklı kaydet" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Mevcut projeyi farklı kaydet" @@ -6603,6 +6621,18 @@ msgstr "%s uyarı" msgid "%s has a warning" msgstr "%s'de uyarı var" +msgid "Collapse" +msgstr "Daralt" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "Yürüt" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s bilgi" @@ -7282,9 +7312,6 @@ msgstr "" msgid "Restore" msgstr "Geri Yükleme" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "Mevcut sıcak yatak sıcaklığı oldukça yüksek. Bu filamenti kapalı bir muhafaza içinde bastırırken nozzle tıkanabilir. Lütfen ön kapağı açın ve/veya üst camı çıkarın." @@ -7364,6 +7391,12 @@ msgstr "Adım dosyasındaki bileşenlerin adı UTF8 formatında değil!" msgid "The name may show garbage characters!" msgstr "İsimde çöp karakterler görünebilir!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "\"%1%\" dosyası yüklenemedi. Geçersiz bir yapılandırma bulundu." @@ -7918,6 +7951,11 @@ msgstr "Sebep: \"%1%\" ve başka bir parçanın kesişimi yoktur." msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Negatif parçalar tespit edildi. Dışa aktarmadan önce mesh boolean yapmak ister misiniz?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -7979,6 +8017,11 @@ msgstr "Geçersiz numara" msgid "Plate Settings" msgstr "Plaka Ayarları" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Prime Kulesi:" @@ -8827,6 +8870,10 @@ msgstr "Hata kodu" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "%s filamenti, %s AMS yuvasındaki filamentle eşleşmiyor. AMS yuvası atamasını desteklemek için lütfen yazıcının ürün yazılımını güncelleyin." @@ -9109,9 +9156,6 @@ msgstr "Özel dinamik akış değerini etkinleştirmek için dinamik akış kali msgid "This printer does not support printing all plates" msgstr "Bu yazıcı tüm kalıpların yazdırılmasını desteklemiyor" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "Mevcut ürün yazılımı en fazla 16 malzemeyi desteklemektedir. Hazırlık Sayfasında malzeme sayısını 16'ya veya daha azına düşürebilir ya da ürün yazılımını güncellemeyi deneyebilirsiniz. Güncellemeden sonra da kısıtlama devam ederse, lütfen sonraki ürün yazılımı desteğini bekleyin." - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "" @@ -10439,6 +10483,9 @@ msgstr "Kamera görüntüsü - Sağ" msgid "Camera view - Isometric" msgstr "Kamera görünümü - İzometrik" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12588,6 +12635,12 @@ msgstr "" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "" @@ -15250,9 +15303,6 @@ msgstr "Seçilmiş Parçalar" msgid "Keep original models" msgstr "Orijinal modellerini muhafaza et" -msgid "Execute" -msgstr "Yürüt" - msgid "Entity Only" msgstr "Sadece Nesne" @@ -15775,9 +15825,6 @@ msgstr "Ön Ayarı Düzenle" msgid "For more information, please check out Wiki" msgstr "Daha fazla bilgi için lütfen Wiki'ye göz atın" -msgid "Collapse" -msgstr "Daralt" - msgid "Daily Tips" msgstr "Günlük İpuçları" @@ -16420,12 +16467,6 @@ msgstr "Filament gruplama" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "Bir daha anımsatma" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "Başka bir açılır pencere görünmeyecektir. 'Tercihler'den yeniden açabilirsiniz" - msgid "Filament-Saving Mode" msgstr "Filament Tasarruf Modu" @@ -16483,9 +16524,6 @@ msgstr "" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "Mevcut plaka için filament gruplama yöntemi, dilimleme plakası düğmesindeki açılır seçenek tarafından belirlenir." - msgid "Skip Objects" msgstr "Nesneleri Atla" @@ -17185,6 +17223,21 @@ msgid "" "Less babysitting, more predictable output. Example: a small farm running PETG parts avoids 'fail at hour 6' surprises and keeps batches on schedule." msgstr "" +#~ msgid "Shift+" +#~ msgstr "Shift+" + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "Mevcut ürün yazılımı en fazla 16 malzemeyi desteklemektedir. Hazırlık Sayfasında malzeme sayısını 16'ya veya daha azına düşürebilir ya da ürün yazılımını güncellemeyi deneyebilirsiniz. Güncellemeden sonra da kısıtlama devam ederse, lütfen sonraki ürün yazılımı desteğini bekleyin." + +#~ msgid "Don't remind me again" +#~ msgstr "Bir daha anımsatma" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "Başka bir açılır pencere görünmeyecektir. 'Tercihler'den yeniden açabilirsiniz" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "Mevcut plaka için filament gruplama yöntemi, dilimleme plakası düğmesindeki açılır seçenek tarafından belirlenir." + #, c-format, boost-format #~ msgid "Left nozzle: %smm" #~ msgstr "Sol nozul: %smm" diff --git a/bbl/i18n/uk/BambuStudio_uk.po b/bbl/i18n/uk/BambuStudio_uk.po index b1ddbe95f9..ea71082990 100644 --- a/bbl/i18n/uk/BambuStudio_uk.po +++ b/bbl/i18n/uk/BambuStudio_uk.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: BambuLab Україна\n" @@ -3174,12 +3174,12 @@ msgstr "Орієнтація" msgid "Filling" msgstr "Заповнення" -msgid "Bed filling canceled." -msgstr "Заповнення ліжка скасоване." - msgid "Bed filling done." msgstr "Заповнення ліжка виконане." +msgid "Bed filling canceled." +msgstr "Заповнення ліжка скасоване." + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3862,6 +3862,9 @@ msgstr "Переповнення стека" msgid "Running post-processing scripts" msgstr "Запуск скриптів постобробки" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "Скрипт післяобробки успішно виконаний" @@ -4590,6 +4593,9 @@ msgstr "Ширина лінії" msgid "Fan Speed" msgstr "Швидкість вентилятора" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "Потік" @@ -4665,6 +4671,9 @@ msgstr "Швидкість (мм/с)" msgid "Fan Speed (%)" msgstr "Швидкість вентилятора (%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "Температура (°С)" @@ -4818,6 +4827,9 @@ msgstr "Час шару: " msgid "Fan Speed: " msgstr "Швидкість вентилятора: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "Температура: " @@ -4899,6 +4911,9 @@ msgstr "Кольця миші:" msgid "Increase/decrease edit area" msgstr "Збільшення/зменшення області редагування" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "Послідовність" @@ -5311,6 +5326,9 @@ msgstr "Багато пристроїв" msgid "Project" msgstr "Проєкт" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "Так" @@ -5449,6 +5467,9 @@ msgstr "Вигляд справа" msgid "Isometric View" msgstr "" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "Почати нове вікно" @@ -5473,9 +5494,6 @@ msgstr "Зберегти поточний проєкт у файл" msgid "Save Project as" msgstr "Зберегти проєкт як" -msgid "Shift+" -msgstr "Shift+" - msgid "Save current project as" msgstr "Зберегти поточний проєкт як" @@ -6590,6 +6608,18 @@ msgstr "%s попередження" msgid "%s has a warning" msgstr "%s має попередження" +msgid "Collapse" +msgstr "Згорнути" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s інфо" @@ -7266,9 +7296,6 @@ msgstr "" msgid "Restore" msgstr "Відновити" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "Поточна температура гарячого ложа висока. При друку цим філаментом в закритому приміщенні може статися забивання сопла. Будь ласка, відкрийте передню дверцю та/або видаліть верхнє скло." @@ -7351,6 +7378,12 @@ msgstr "Ім'я компонентів всередині крокового ф msgid "The name may show garbage characters!" msgstr "Через не підтримуване кодування тексту можуть з'явитися неправильні символи!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Не вдалося завантажити файл \\%1%\\. Виявлено неприпустиму конфігурацію." @@ -7898,6 +7931,11 @@ msgstr "Причина: “%1%” та інша частина не мають msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "Виявлено від’ємні частини. Бажаєте виконати булеву операцію з сітками перед експортом?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -7959,6 +7997,11 @@ msgstr "Неправильний номер" msgid "Plate Settings" msgstr "Налаштування столу" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "Башта стабілізації:" @@ -8795,6 +8838,10 @@ msgstr "Код помилки" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "Філамент %s не відповідає філаменту в слоті AMS %s. Будь ласка, оновіть Прошивка принтера для підтримки призначення слотів AMS." @@ -9077,9 +9124,6 @@ msgstr "" msgid "This printer does not support printing all plates" msgstr "Цей принтер не підтримує друк всіх пластин" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "" @@ -10395,6 +10439,9 @@ msgstr "" msgid "Camera view - Isometric" msgstr "" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12552,6 +12599,12 @@ msgstr "" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "" @@ -15195,9 +15248,6 @@ msgstr "" msgid "Keep original models" msgstr "" -msgid "Execute" -msgstr "" - msgid "Entity Only" msgstr "" @@ -15720,9 +15770,6 @@ msgstr "Редагувати налаштування" msgid "For more information, please check out Wiki" msgstr "Для отримання додаткової інформації, будь ласка, перевірте Вікі" -msgid "Collapse" -msgstr "Згорнути" - msgid "Daily Tips" msgstr "Щоденні поради" @@ -16357,12 +16404,6 @@ msgstr "" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "" - msgid "Filament-Saving Mode" msgstr "" @@ -16420,9 +16461,6 @@ msgstr "" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "" - msgid "Skip Objects" msgstr "Пропустити об'єкти" @@ -17123,6 +17161,9 @@ msgid "" "Less babysitting, more predictable output. Example: a small farm running PETG parts avoids 'fail at hour 6' surprises and keeps batches on schedule." msgstr "" +#~ msgid "Shift+" +#~ msgstr "Shift+" + #, c-format, boost-format #~ msgid "Left nozzle: %smm" #~ msgstr "Ліве сопло: %sмм" diff --git a/bbl/i18n/zh_CN/BambuStudio_zh_CN.po b/bbl/i18n/zh_CN/BambuStudio_zh_CN.po index 9cd3d9ea0c..d70793e74a 100644 --- a/bbl/i18n/zh_CN/BambuStudio_zh_CN.po +++ b/bbl/i18n/zh_CN/BambuStudio_zh_CN.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: 2025-02-20 20:32+0800\n" "Last-Translator: Jiang Yue \n" "Language-Team: \n" @@ -3167,12 +3167,12 @@ msgstr "自动朝向中..." msgid "Filling" msgstr "正在填充" -msgid "Bed filling canceled." -msgstr "填充热床已取消。" - msgid "Bed filling done." msgstr "填充热床已完成。" +msgid "Bed filling canceled." +msgstr "填充热床已取消。" + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3847,6 +3847,9 @@ msgstr "栈溢出" msgid "Running post-processing scripts" msgstr "运行后处理脚本" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "成功执行后处理脚本" @@ -4579,6 +4582,9 @@ msgstr "线宽" msgid "Fan Speed" msgstr "风扇速度" +msgid "AUX Fan Speed" +msgstr "辅助风扇速度" + msgid "Flow" msgstr "流量" @@ -4654,6 +4660,9 @@ msgstr "速度(mm/s)" msgid "Fan Speed (%)" msgstr "风扇速度(%)" +msgid "AUX Fan Speed (%)" +msgstr "辅助风扇速度(%)" + msgid "Temperature (°C)" msgstr "温度(℃)" @@ -4807,6 +4816,9 @@ msgstr "层时间: " msgid "Fan Speed: " msgstr "风扇速度: " +msgid "AUX Fan Speed: " +msgstr "风扇速度: " + msgid "Temperature: " msgstr "温度: " @@ -4888,6 +4900,9 @@ msgstr "鼠标滚轮:" msgid "Increase/decrease edit area" msgstr "增加/减小编辑区域" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "可变层高曲线超出了当前喷嘴允许的层高限制,可变层高曲线已重置" + msgid "Sequence" msgstr "顺序" @@ -5305,6 +5320,9 @@ msgstr "多设备" msgid "Project" msgstr "项目" +msgid "Filament Manager" +msgstr "耗材管理" + msgid "Yes" msgstr "是" @@ -5447,6 +5465,9 @@ msgstr "右视图" msgid "Isometric View" msgstr "等轴测视图" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "打开新窗口" @@ -5471,9 +5492,6 @@ msgstr "保存当前项目到文件" msgid "Save Project as" msgstr "项目另存为" -msgid "Shift+" -msgstr "" - msgid "Save current project as" msgstr "项目另存为" @@ -6577,6 +6595,18 @@ msgstr "%s 警告" msgid "%s has a warning" msgstr "%s 有一个警告" +msgid "Collapse" +msgstr "收起" + +msgid "View details" +msgstr "查看详情" + +msgid "Execute" +msgstr "执行" + +msgid "Do not execute" +msgstr "不执行" + #, c-format, boost-format msgid "%s info" msgstr "%s 信息" @@ -7250,9 +7280,6 @@ msgstr "" msgid "Restore" msgstr "恢复" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "当前 3mf 文件中存在 G-code 脚本,请核实脚本内容。" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "当前热床温度相对较高。在封闭式外壳中打印这种丝可能会导致喷嘴堵塞。请打开前门和/或取下上部玻璃。" @@ -7332,6 +7359,12 @@ msgstr "step 文件中的部件名称包含非UTF8格式的字符!" msgid "The name may show garbage characters!" msgstr "此名称可能显示乱码字符!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "加载文件“%1%”失败。发现无效配置。" @@ -7903,6 +7936,13 @@ msgstr "原因:零件\"%1%\"与另一个零件没有交集。" msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "检测到负零件。在导出前,您是否想执行网格布尔运算?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" +"安全提示:该 3MF 文件包含后处理脚本命令,切片时会自动执行,可能存在安全风险!\n" +"请确认文件来源及脚本内容后再继续。" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "当前校准耗材分配到的挤出机与 PA 校准对话框 (%s) 中选择的挤出机不同。这可能会导致校准结果不准确。您可以在耗材分组设置中更改分配情况。" @@ -7964,6 +8004,11 @@ msgstr "无效数字" msgid "Plate Settings" msgstr "盘参数设置" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "擦料塔:" @@ -8816,6 +8861,10 @@ msgstr "错误代码" msgid "Recommended filament arrangement saves %s->" msgstr "如果按照推荐摆料可省 %s->" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "当前固件最多支持%s种材料。您可以在准备页将材料数量减少至%s种及以下,或尝试更新固件。若更新后仍受限,请等待后续固件支持。" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "材料编号%s和AMS槽位%s中的耗材丝材质不匹配,请更新打印机固件以支持AMS槽位映射功能" @@ -9102,9 +9151,6 @@ msgstr "您可以将动态流量校准设置为'关闭'来启用自定义的动 msgid "This printer does not support printing all plates" msgstr "该打印机不支持打印所有盘" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "当前固件最多支持 16 种材料。您可以在准备页将材料数量减少至 16 种及以下,或尝试更新固件。若更新后仍受限,请等待后续固件支持。" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "请确认所需喷嘴直径和流量是否和当前显示一致。" @@ -10426,6 +10472,9 @@ msgstr "" msgid "Camera view - Isometric" msgstr "摄像机视角 - 等轴测" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12607,6 +12656,12 @@ msgstr "除了换热端外的擦拭塔上的清理量。" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "换热端所需的擦料塔上的清理量。" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "擦料塔冷却" @@ -15282,9 +15337,6 @@ msgstr "已选择的零件" msgid "Keep original models" msgstr "保留原模型" -msgid "Execute" -msgstr "执行" - msgid "Entity Only" msgstr "仅实体" @@ -15799,9 +15851,6 @@ msgstr "编辑预设" msgid "For more information, please check out Wiki" msgstr "了解更多信息,请参阅Wiki" -msgid "Collapse" -msgstr "收起" - msgid "Daily Tips" msgstr "每日贴士" @@ -16435,12 +16484,6 @@ msgstr "耗材分组" msgid "Fila Saving" msgstr "省料" -msgid "Don't remind me again" -msgstr "不再提醒" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "不再弹窗提醒。您可以在“偏好设置”中重新打开。" - msgid "Filament-Saving Mode" msgstr "省料模式" @@ -16498,9 +16541,6 @@ msgstr "设置喷嘴数量" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "基于打印质量最佳的原则, 生成%s/%s节省耗材的分组方案" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "当前盘的耗材分组方式由切片按钮处的下拉选项决定。" - msgid "Skip Objects" msgstr "零件跳过" @@ -17224,6 +17264,21 @@ msgstr "" "一次成功的可靠性\n" "更少盯机,更可预测的产出。例如:小型打印农场打印 PETG 零件可降低意外失败的概率,让批次按计划推进。" +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "当前 3mf 文件中存在 G-code 脚本,请核实脚本内容。" + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "当前固件最多支持 16 种材料。您可以在准备页将材料数量减少至 16 种及以下,或尝试更新固件。若更新后仍受限,请等待后续固件支持。" + +#~ msgid "Don't remind me again" +#~ msgstr "不再提醒" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "不再弹窗提醒。您可以在“偏好设置”中重新打开。" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "当前盘的耗材分组方式由切片按钮处的下拉选项决定。" + #, boost-format #~ msgid "Since it is unassembled, %1% extends beyond the main body, so the thumbnail can't be rendered." #~ msgstr "因其未被组装, %1% 超出了主体,因此无法渲染到缩略图。" diff --git a/bbl/i18n/zh_TW/BambuStudio_zh_TW.po b/bbl/i18n/zh_TW/BambuStudio_zh_TW.po index 51974dd068..b1a6eac46b 100644 --- a/bbl/i18n/zh_TW/BambuStudio_zh_TW.po +++ b/bbl/i18n/zh_TW/BambuStudio_zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-14 19:58+0800\n" +"POT-Creation-Date: 2026-04-28 17:39+0800\n" "PO-Revision-Date: 2025-02-20 20:32+0800\n" "Last-Translator: Jiang Yue \n" "Language-Team: \n" @@ -3168,12 +3168,12 @@ msgstr "自動朝向中..." msgid "Filling" msgstr "正在填充" -msgid "Bed filling canceled." -msgstr "填充熱床已取消。" - msgid "Bed filling done." msgstr "填充熱床已完成。" +msgid "Bed filling canceled." +msgstr "填充熱床已取消。" + #. TRN: This is the title of the action appearing in undo/redo stack. #. It is same for Text and SVG. msgid "Emboss attribute change" @@ -3848,6 +3848,9 @@ msgstr "棧溢位" msgid "Running post-processing scripts" msgstr "執行後處理指令碼" +msgid "Updating preview with post-processed G-code" +msgstr "" + msgid "Successfully executed post-processing script" msgstr "成功執行後處理指令碼" @@ -4573,6 +4576,9 @@ msgstr "線寬" msgid "Fan Speed" msgstr "風扇速度" +msgid "AUX Fan Speed" +msgstr "" + msgid "Flow" msgstr "流量" @@ -4648,6 +4654,9 @@ msgstr "速度(mm/s)" msgid "Fan Speed (%)" msgstr "風扇速度(%)" +msgid "AUX Fan Speed (%)" +msgstr "" + msgid "Temperature (°C)" msgstr "溫度(℃)" @@ -4801,6 +4810,9 @@ msgstr "層時間: " msgid "Fan Speed: " msgstr "風扇速度: " +msgid "AUX Fan Speed: " +msgstr "" + msgid "Temperature: " msgstr "溫度: " @@ -4882,6 +4894,9 @@ msgstr "滑鼠滾輪:" msgid "Increase/decrease edit area" msgstr "增加/減小編輯區域" +msgid "The variable layer height profile has been reset because some layer heights exceed the allowed range of the current nozzle." +msgstr "" + msgid "Sequence" msgstr "順序" @@ -5299,6 +5314,9 @@ msgstr "多裝置" msgid "Project" msgstr "專案" +msgid "Filament Manager" +msgstr "" + msgid "Yes" msgstr "是" @@ -5441,6 +5459,9 @@ msgstr "右檢視" msgid "Isometric View" msgstr "等軸測檢視" +msgid "Fit Camera" +msgstr "" + msgid "Start a new window" msgstr "開啟新視窗" @@ -5465,9 +5486,6 @@ msgstr "儲存當前專案到檔案" msgid "Save Project as" msgstr "專案另存為" -msgid "Shift+" -msgstr "" - msgid "Save current project as" msgstr "專案另存為" @@ -6571,6 +6589,18 @@ msgstr "%s 警告" msgid "%s has a warning" msgstr "%s 有一個警告" +msgid "Collapse" +msgstr "收起" + +msgid "View details" +msgstr "" + +msgid "Execute" +msgstr "執行" + +msgid "Do not execute" +msgstr "" + #, c-format, boost-format msgid "%s info" msgstr "%s 資訊" @@ -7244,9 +7274,6 @@ msgstr "" msgid "Restore" msgstr "恢復" -msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." -msgstr "當前 3mf 檔案中存在 G-code 指令碼,請核實指令碼內容。" - msgid "The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass." msgstr "當前熱床溫度相對較高。在封閉式外殼中列印這種絲可能會導致噴嘴堵塞。請開啟前門和/或取下上部玻璃。" @@ -7326,6 +7353,12 @@ msgstr "step 檔案中的部件名稱包含非UTF8格式的字元!" msgid "The name may show garbage characters!" msgstr "此名稱可能顯示亂碼字元!" +msgid "The following shells are not closed and may cause issues:" +msgstr "" + +msgid "Unclosed Shell Warning" +msgstr "" + #, boost-format msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "載入檔案“%1%”失敗。發現無效配置。" @@ -7890,6 +7923,11 @@ msgstr "原因:零件\"%1%\"與另一個零件沒有交集。" msgid "Negative parts detected. Would you like to perform mesh boolean before exporting?" msgstr "檢測到負零件。在匯出前,您是否想執行網格布林運算?" +msgid "" +"Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\n" +"Please verify the file source and script contents before continuing." +msgstr "" + #, c-format, boost-format msgid "The calibration filament is currently assigned to a different extruder than the one selected in the PA Calibration dialog (%s). This may lead to incorrect calibration results. You can change the assignment in the filament grouping settings." msgstr "" @@ -7951,6 +7989,11 @@ msgstr "無效數字" msgid "Plate Settings" msgstr "盤引數設定" +msgid "" +"While printing by Object, the extruder may collide skirt.\n" +"Thus, it is recommended to reset the skirt layer to 1 to avoid that." +msgstr "" + msgid "Prime Tower:" msgstr "擦料塔:" @@ -8803,6 +8846,10 @@ msgstr "錯誤程式碼" msgid "Recommended filament arrangement saves %s->" msgstr "" +#, c-format, boost-format +msgid "The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +msgstr "" + #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." msgstr "材料編號%s和AMS槽位%s中的耗材絲材質不匹配,請更新印表機韌體以支援AMS槽位對映功能" @@ -9089,9 +9136,6 @@ msgstr "您可以將動態流量校準設定為'關閉'來啟用自定義的動 msgid "This printer does not support printing all plates" msgstr "該印表機不支援列印所有盤" -msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." -msgstr "當前韌體最多支援 16 種材料。您可以在準備頁將材料數量減少至 16 種及以下,或嘗試更新韌體。若更新後仍受限,請等待後續韌體支援。" - msgid "Please check if the required nozzle diameter and flow rate match the current display." msgstr "請確認所需噴嘴直徑和流量是否和當前顯示一致。" @@ -10413,6 +10457,9 @@ msgstr "" msgid "Camera view - Isometric" msgstr "攝像機視角 - 等軸測" +msgid "Camera view - Fit to scene or selection" +msgstr "" + msgid "Shift+E" msgstr "" @@ -12592,6 +12639,12 @@ msgstr "除了換熱端外的擦拭塔上的清理量。" msgid "The volume of material required to prime the extruder for a hotend change on the tower." msgstr "換熱端所需的擦料塔上的清理量。" +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Wipe tower cooling" msgstr "擦料塔冷卻" @@ -15257,9 +15310,6 @@ msgstr "已選擇的零件" msgid "Keep original models" msgstr "保留原模型" -msgid "Execute" -msgstr "執行" - msgid "Entity Only" msgstr "僅實體" @@ -15774,9 +15824,6 @@ msgstr "編輯預設" msgid "For more information, please check out Wiki" msgstr "瞭解更多資訊,請參閱Wiki" -msgid "Collapse" -msgstr "收起" - msgid "Daily Tips" msgstr "每日貼士" @@ -16410,12 +16457,6 @@ msgstr "耗材分組" msgid "Fila Saving" msgstr "" -msgid "Don't remind me again" -msgstr "不再提醒" - -msgid "No further pop-up will appear. You can reopen it in 'Preferences'" -msgstr "不再彈窗提醒。您可以在“偏好設定”中重新開啟。" - msgid "Filament-Saving Mode" msgstr "省料模式" @@ -16473,9 +16514,6 @@ msgstr "設定噴嘴數量" msgid "Generates filament grouping for the %s and %s based on the quality of prints, prioritizing print quality over filament saving" msgstr "" -msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." -msgstr "當前盤的耗材分組方式由切片按鈕處的下拉選項決定。" - msgid "Skip Objects" msgstr "零件跳過" @@ -17199,6 +17237,21 @@ msgstr "" "一次成功的可靠性\n" "更少盯機,更可預測的產出。例如:小型列印農場列印 PETG 零件可降低意外失敗的機率,讓批次按計劃推進。" +#~ msgid "There is a G-code script present in the current 3mf file, please verify the content of the script." +#~ msgstr "當前 3mf 檔案中存在 G-code 指令碼,請核實指令碼內容。" + +#~ msgid "The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support." +#~ msgstr "當前韌體最多支援 16 種材料。您可以在準備頁將材料數量減少至 16 種及以下,或嘗試更新韌體。若更新後仍受限,請等待後續韌體支援。" + +#~ msgid "Don't remind me again" +#~ msgstr "不再提醒" + +#~ msgid "No further pop-up will appear. You can reopen it in 'Preferences'" +#~ msgstr "不再彈窗提醒。您可以在“偏好設定”中重新開啟。" + +#~ msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." +#~ msgstr "當前盤的耗材分組方式由切片按鈕處的下拉選項決定。" + #, c-format, boost-format #~ msgid "Left nozzle: %smm" #~ msgstr "左噴嘴:%smm" diff --git a/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/design.md b/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/design.md new file mode 100644 index 0000000000..f14a1acbc8 --- /dev/null +++ b/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/design.md @@ -0,0 +1,40 @@ +## Context + +主界面使用 `Tabbook`(自定义 wxNotebook)管理多个 tab 页面。`TabPosition` 枚举为每个 tab 分配了硬编码索引(0-10)。但部分 tab 是条件添加的(如 Multi-device 仅在 `is_enable_multi_machine()` 时添加),导致实际运行时的 tab 索引与枚举值不一致。 + +当前校准任务发送完成后,`Plater::send_calibration_job_finished()` 调用 `request_select_tab(tpCalibration)`(索引 6),在 Multi-device 未启用时实际跳转到了 Filament Manager(实际索引 6)。 + +项目中已有安全的页面切换方法 `select_tab(wxPanel* panel)`,内部通过 `FindPage` 动态查找面板的实际索引,不依赖硬编码值。 + +## Goals / Non-Goals + +**Goals:** +- 修复校准发送完成后跳转到错误页面的 bug +- 使用已有的指针查找方式替代硬编码索引跳转 + +**Non-Goals:** +- 不重构整个 `TabPosition` 枚举系统(影响范围过大) +- 不修改其他非校准相关的 `request_select_tab` 调用(需单独评估) +- 不改变校准流程的业务逻辑(发送成功后跳回校准页面仍是预期行为) + +## Decisions + +### Decision 1: 用 `select_tab(wxPanel*)` 替代 `request_select_tab(TabPosition)` + +**选择**:将 `Plater.cpp:19180` 的 `request_select_tab(tpCalibration)` 改为 `select_tab(m_calibration)` + +**替代方案**: +- A) 根据 `is_enable_multi_machine()` 动态计算偏移量 → 脆弱,未来增删 tab 会再次打破 +- B) 重构 `TabPosition` 枚举为动态查找系统 → 正确但影响范围过大,不适合 bug 修复 +- C) 在 `request_select_tab` 中改用 `FindPage` → 可行但需要传入 panel 指针,接口变动大 + +**理由**:方案最小化改动,复用已有的安全方法,且 `select_tab(wxPanel*)` 在项目中已被广泛使用(`MainFrame.cpp:3927`)。 + +### Decision 2: 需要注意线程安全 + +`select_tab(wxPanel*)` 是同步调用,而原来的 `request_select_tab` 通过 `wxQueueEvent` 异步投递事件。校准发送完成回调 `send_calibration_job_finished` 是在主线程(通过 `EVT_SEND_CALIBRATION_FINISHED` wxEvent 触发)中执行的,所以直接调用 `select_tab` 是安全的。 + +## Risks / Trade-offs + +- **[极低] 行为微变**:原来是异步切换(`wxQueueEvent`),改为同步切换(直接调用)。由于已经在主线程 UI 事件回调中,实际无差异 → 不需要额外处理 +- **[低] 其他调用点可能有同类问题**:项目中还有 `print_job_finished` 等地方也用 `request_select_tab(tpMonitor)`,`tpMonitor = 3` 在任何配置下都是固定的(之前没有条件 tab),暂不受影响 → 后续可统一排查 diff --git a/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/proposal.md b/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/proposal.md new file mode 100644 index 0000000000..11dea7d72a --- /dev/null +++ b/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/proposal.md @@ -0,0 +1,24 @@ +## Why + +校准任务发送成功后,页面会错误地跳转到"耗材管理"页面,而非预期的"校准"页面。根因是 `TabPosition` 枚举使用硬编码索引(`tpCalibration = 6`),但 Multi-device tab 是条件添加的——未启用时所有后续 tab 的实际索引比枚举值少 1,导致索引 6 指向了 Filament Manager 而非 Calibration。 + +## What Changes + +- 将 `Plater::send_calibration_job_finished()` 中的 `request_select_tab(tpCalibration)` 改为通过面板指针查找的 `select_tab(m_calibration)`,避免硬编码索引偏移问题 +- 排查项目中其他使用 `request_select_tab` 或硬编码 `TabPosition` 枚举进行页面切换的调用点,评估是否存在同类问题 + +## Capabilities + +### New Capabilities + +(无新增能力) + +### Modified Capabilities + +(无规格级别的行为变更——这是一个实现层面的 bug 修复,不涉及需求变更) + +## Impact + +- **受影响代码**:`src/slic3r/GUI/Plater.cpp` 中的 `send_calibration_job_finished()`,以及可能的其他 `request_select_tab` 调用点 +- **受影响功能**:校准流程中"发送成功后跳转"的页面导航 +- **风险**:极低,改用已有的 `select_tab(wxPanel*)` 方法,该方法内部通过 `FindPage` 查找实际索引,已在其他地方广泛使用 diff --git a/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/tasks.md b/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/tasks.md new file mode 100644 index 0000000000..de6644c9cf --- /dev/null +++ b/openspec/changes/archive/2026-04-27-fix-calibration-tab-switch-bug/tasks.md @@ -0,0 +1,8 @@ +## 1. 修复校准页面跳转 + +- [x] 1.1 将 `src/slic3r/GUI/Plater.cpp:19180` 的 `p->main_frame->request_select_tab(MainFrame::TabPosition::tpCalibration)` 改为 `p->main_frame->select_tab(p->main_frame->m_calibration)` + +## 2. 验证 + +- [x] 2.1 确认 `select_tab(wxPanel*)` 方法在 `send_calibration_job_finished` 的调用上下文中可正常工作(主线程、m_calibration 非空) +- [x] 2.2 排查项目中其他 `request_select_tab` 调用点,确认是否存在同类索引偏移问题(记录结果,本次不修改) diff --git a/resources/i18n/cs/BambuStudio.mo b/resources/i18n/cs/BambuStudio.mo index 14ac569908..29bb337836 100644 Binary files a/resources/i18n/cs/BambuStudio.mo and b/resources/i18n/cs/BambuStudio.mo differ diff --git a/resources/i18n/de/BambuStudio.mo b/resources/i18n/de/BambuStudio.mo index a614a1025c..cdc5003ccd 100644 Binary files a/resources/i18n/de/BambuStudio.mo and b/resources/i18n/de/BambuStudio.mo differ diff --git a/resources/i18n/en/BambuStudio.mo b/resources/i18n/en/BambuStudio.mo index 5db1f06933..cb3f3e365f 100644 Binary files a/resources/i18n/en/BambuStudio.mo and b/resources/i18n/en/BambuStudio.mo differ diff --git a/resources/i18n/es/BambuStudio.mo b/resources/i18n/es/BambuStudio.mo index 5fe7e225c1..c16cbbdf8a 100644 Binary files a/resources/i18n/es/BambuStudio.mo and b/resources/i18n/es/BambuStudio.mo differ diff --git a/resources/i18n/fr/BambuStudio.mo b/resources/i18n/fr/BambuStudio.mo index 403fec75ac..6e14e35794 100644 Binary files a/resources/i18n/fr/BambuStudio.mo and b/resources/i18n/fr/BambuStudio.mo differ diff --git a/resources/i18n/hu/BambuStudio.mo b/resources/i18n/hu/BambuStudio.mo index d496cf571f..7fe9c5640b 100644 Binary files a/resources/i18n/hu/BambuStudio.mo and b/resources/i18n/hu/BambuStudio.mo differ diff --git a/resources/i18n/it/BambuStudio.mo b/resources/i18n/it/BambuStudio.mo index 7278bc8676..7d98eaf631 100644 Binary files a/resources/i18n/it/BambuStudio.mo and b/resources/i18n/it/BambuStudio.mo differ diff --git a/resources/i18n/ja/BambuStudio.mo b/resources/i18n/ja/BambuStudio.mo index 69f8560c31..5bef6f20e4 100644 Binary files a/resources/i18n/ja/BambuStudio.mo and b/resources/i18n/ja/BambuStudio.mo differ diff --git a/resources/i18n/ko/BambuStudio.mo b/resources/i18n/ko/BambuStudio.mo index b831b4e931..88f27f81fb 100644 Binary files a/resources/i18n/ko/BambuStudio.mo and b/resources/i18n/ko/BambuStudio.mo differ diff --git a/resources/i18n/nl/BambuStudio.mo b/resources/i18n/nl/BambuStudio.mo index 69d54fc9e7..c5a8df481d 100644 Binary files a/resources/i18n/nl/BambuStudio.mo and b/resources/i18n/nl/BambuStudio.mo differ diff --git a/resources/i18n/pl/BambuStudio.mo b/resources/i18n/pl/BambuStudio.mo index cbd46258e7..2900f0e725 100644 Binary files a/resources/i18n/pl/BambuStudio.mo and b/resources/i18n/pl/BambuStudio.mo differ diff --git a/resources/i18n/pt_BR/BambuStudio.mo b/resources/i18n/pt_BR/BambuStudio.mo index 08c7aadacf..93c720234a 100644 Binary files a/resources/i18n/pt_BR/BambuStudio.mo and b/resources/i18n/pt_BR/BambuStudio.mo differ diff --git a/resources/i18n/ru/BambuStudio.mo b/resources/i18n/ru/BambuStudio.mo index aac87f5bd1..a93e9e144c 100644 Binary files a/resources/i18n/ru/BambuStudio.mo and b/resources/i18n/ru/BambuStudio.mo differ diff --git a/resources/i18n/sv/BambuStudio.mo b/resources/i18n/sv/BambuStudio.mo index d36ff09091..2d23815347 100644 Binary files a/resources/i18n/sv/BambuStudio.mo and b/resources/i18n/sv/BambuStudio.mo differ diff --git a/resources/i18n/tr/BambuStudio.mo b/resources/i18n/tr/BambuStudio.mo index 0882cbc38c..a73867314c 100644 Binary files a/resources/i18n/tr/BambuStudio.mo and b/resources/i18n/tr/BambuStudio.mo differ diff --git a/resources/i18n/uk/BambuStudio.mo b/resources/i18n/uk/BambuStudio.mo index c13519d343..d95d559ace 100644 Binary files a/resources/i18n/uk/BambuStudio.mo and b/resources/i18n/uk/BambuStudio.mo differ diff --git a/resources/i18n/zh_CN/BambuStudio.mo b/resources/i18n/zh_CN/BambuStudio.mo index 76c96c18af..68df773d8a 100644 Binary files a/resources/i18n/zh_CN/BambuStudio.mo and b/resources/i18n/zh_CN/BambuStudio.mo differ diff --git a/resources/i18n/zh_TW/BambuStudio.mo b/resources/i18n/zh_TW/BambuStudio.mo index 89cd9538cd..501f2946d7 100644 Binary files a/resources/i18n/zh_TW/BambuStudio.mo and b/resources/i18n/zh_TW/BambuStudio.mo differ diff --git a/resources/images/extruder_badge_both_selected_dark.svg b/resources/images/extruder_badge_both_selected_dark.svg new file mode 100644 index 0000000000..76049161da --- /dev/null +++ b/resources/images/extruder_badge_both_selected_dark.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_left_selected_dark.svg b/resources/images/extruder_badge_left_selected_dark.svg new file mode 100644 index 0000000000..fdd69b311c --- /dev/null +++ b/resources/images/extruder_badge_left_selected_dark.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_left_selected_single_dark.svg b/resources/images/extruder_badge_left_selected_single_dark.svg new file mode 100644 index 0000000000..5dc9090544 --- /dev/null +++ b/resources/images/extruder_badge_left_selected_single_dark.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_none_selected_dark.svg b/resources/images/extruder_badge_none_selected_dark.svg new file mode 100644 index 0000000000..00c7e7fe8c --- /dev/null +++ b/resources/images/extruder_badge_none_selected_dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_none_selected_single_dark.svg b/resources/images/extruder_badge_none_selected_single_dark.svg new file mode 100644 index 0000000000..f0079099db --- /dev/null +++ b/resources/images/extruder_badge_none_selected_single_dark.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_right_selected_dark.svg b/resources/images/extruder_badge_right_selected_dark.svg new file mode 100644 index 0000000000..84393a2d07 --- /dev/null +++ b/resources/images/extruder_badge_right_selected_dark.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/tab_filament_active.svg b/resources/images/tab_filament_active.svg new file mode 100644 index 0000000000..2efa2e0b29 --- /dev/null +++ b/resources/images/tab_filament_active.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index ada24c3db9..eb4949517e 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "02.06.00.01", + "version": "02.06.00.03", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json index 42c1c71e89..fd561c9b02 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json @@ -73,6 +73,10 @@ "hole_limit_min": [ "0.1119" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json index 59c6aaa136..2b0ad4db67 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json @@ -90,6 +90,10 @@ "hole_limit_min": [ "0.1119" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json index de5ef843c1..7fd3b25a7e 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json @@ -90,6 +90,10 @@ "hole_limit_min": [ "0.1119" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json index b487d6e723..037ef7e0c4 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json @@ -90,6 +90,10 @@ "hole_limit_min": [ "0.1119" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json index 608c5ec2a9..afb7d2af99 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "2", "2" diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json index fd9785460b..c03b539fe8 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json @@ -11,10 +11,18 @@ "fan_max_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -31,10 +39,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json index d34ed07eb3..5f5a3435d7 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json @@ -11,10 +11,18 @@ "fan_max_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -31,10 +39,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json index 5813921f5f..69f51c5143 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json @@ -11,10 +11,18 @@ "fan_max_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "20", "30" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -31,10 +39,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json index 50a29e0852..e461c5d2d1 100644 --- a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json @@ -43,6 +43,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json index 9a0d5f966a..f4d6eb6c25 100644 --- a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json @@ -43,6 +43,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2DP.json index c10fc0ba94..fbb310bb0c 100644 --- a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "12", "12" diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json index 4dea956573..d219538b6d 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json @@ -67,6 +67,10 @@ "hole_limit_min": [ "0.1261" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json index 1022b85566..24ea981618 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json @@ -87,6 +87,10 @@ "hole_limit_min": [ "0.1261" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json index f91fe564c2..9e423a7cd8 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json @@ -87,6 +87,10 @@ "hole_limit_min": [ "0.1261" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json index c25fce22b6..67d3aecd1e 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json @@ -87,6 +87,10 @@ "hole_limit_min": [ "0.1261" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.2 nozzle.json index 64de2d6fd1..1225a33407 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "65" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "2", "2" diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.4 nozzle.json index 2a59d61db7..c0811fc231 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.4 nozzle.json @@ -17,10 +17,18 @@ "counter_limit_max": [ "0.1" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "20", "30" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -37,22 +45,18 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.006" ], "hole_coef_3": [ "0.25" ], - "hole_limit_min": [ - "-0.088" - ], "hole_limit_max": [ "0.14" ], + "hole_limit_min": [ + "-0.088" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.6 nozzle.json index 9b5523fb11..08ad9cb31a 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.6 nozzle.json @@ -8,10 +8,18 @@ "chamber_temperatures": [ "65" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -28,10 +36,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.8 nozzle.json index b5a10eb55f..9fb3fc0ddc 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2DP 0.8 nozzle.json @@ -8,10 +8,18 @@ "chamber_temperatures": [ "65" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -28,10 +36,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json index 31ef413fdc..f378d3fc97 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json @@ -67,6 +67,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json index 11f7b00a39..9e1040892f 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json @@ -67,6 +67,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2DP.json index 0e724baf31..2b4239fd68 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.52", "0.52" diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json index 867fbaeb80..8720f027e3 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json index d8ed65bc45..d764aec4f2 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.4 nozzle.json index 9fc4d93d83..3de622cd49 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.4 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp": [ "90" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.9", "0.9" diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.6 nozzle.json index 2b60dcb277..d05755ce63 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2DP 0.6 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.9", "0.9" diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json index d0bdc0c6f8..7cb0d74bc0 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json index 8a8aba1ebe..e0a4bb4ac6 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2DP.json index 88116d5481..760fc62815 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json index e44302deae..8df61425b9 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json @@ -71,6 +71,10 @@ "hole_limit_min": [ "0.092" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json index 2fe38eae58..fc51a3dbb0 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json @@ -71,6 +71,10 @@ "hole_limit_min": [ "0.092" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2DP.json index 7f624d5eee..349dcccc2f 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2DP.json @@ -17,6 +17,10 @@ "counter_limit_max": [ "0.03" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json index b958c200cc..df90b6ac61 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json index 6b5e42aead..5eafb28f8d 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2DP.json index 7ce4f18d12..1b07db3f0f 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json index 6d5b0894d6..aa12b027e2 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json @@ -71,6 +71,10 @@ "hole_limit_min": [ "0.1686" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json index cb270e8d19..c171567438 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json @@ -71,6 +71,10 @@ "hole_limit_min": [ "0.1686" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2DP.json index f32656a237..7798903ff9 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2DP.json @@ -17,6 +17,10 @@ "counter_limit_max": [ "0.03" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json index 7907e51812..a3ba75304a 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json @@ -74,6 +74,10 @@ "hole_limit_min": [ "0.0725" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json index e9ef039997..43d4dc8b5d 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json @@ -90,6 +90,10 @@ "hole_limit_min": [ "0.0725" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json index 430010182c..f4f455a8b2 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json @@ -90,6 +90,10 @@ "hole_limit_min": [ "0.0725" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json index 69e6ef3008..98bc37e1f0 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json @@ -90,6 +90,10 @@ "hole_limit_min": [ "0.0725" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json index d9d49b4d9e..55575cee0b 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json index 8ccae8ec4b..1b93557f96 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" @@ -19,6 +23,10 @@ "20", "30" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json index 9a57a15829..d8e188da9a 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" @@ -19,6 +23,10 @@ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json index 01ab69f44a..01f3c1431f 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" @@ -19,6 +23,10 @@ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json index a09450ec58..ffde022ea3 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json index 512e8b42d4..31c453844c 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json @@ -66,6 +66,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json index 86e971d44e..ced62f8268 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json @@ -66,6 +66,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json index 7e679a10da..d61c1da460 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json index f86ba626c2..8902b0bd27 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json index e40928b5ea..0ba2dc14ed 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json index a32f0d4a86..1b1768ef51 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json index 3493571b86..d208abf041 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json @@ -77,6 +77,10 @@ "hole_limit_min": [ "0.167" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json index c86f02b995..e18368169a 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json @@ -80,6 +80,10 @@ "hole_limit_min": [ "0.167" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json index 5cd0a68d0e..6e2b48ce81 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json @@ -20,6 +20,10 @@ "eng_plate_temp_initial_layer": [ "100" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json index a230703b7c..1767dc81c5 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json @@ -47,6 +47,10 @@ "filament_tower_ironing_area": [ "8" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json index 03222ca513..06be00489b 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json @@ -70,6 +70,10 @@ "Spiral Lift", "Spiral Lift" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json index 2cd5d0b100..52c3e787c2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json @@ -71,6 +71,10 @@ "filament_tower_ironing_area": [ "8" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json index 17546ad3a9..36bb96bd39 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flush_volumetric_speed": [ "3", "3" diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json index 87ce98e0af..42718be332 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json @@ -11,6 +11,10 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "18", "21" diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json index c264137a2e..5895958827 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json @@ -8,14 +8,25 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "21", "28" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" ], + "filament_tower_ironing_area": [ + "8" + ], "filament_wipe": [ "1", "1" @@ -32,13 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_tower_ironing_area": [ - "8" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json index b357414245..0fbf4068cb 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json @@ -70,6 +70,10 @@ "hole_limit_min": [ "0.09" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json index e576289ff6..15a84ac190 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json @@ -94,6 +94,10 @@ "hole_limit_min": [ "0.09" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json index d31d045e6c..6be40ba26d 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json @@ -94,6 +94,10 @@ "hole_limit_min": [ "0.09" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json index b45ca271c2..fb89b46f64 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json @@ -94,6 +94,10 @@ "hole_limit_min": [ "0.09" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json index 3dd511f9a5..e0eaa5b1f4 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "1", "1" @@ -39,12 +43,6 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "60" - ], - "supertack_plate_temp_initial_layer": [ - "60" - ], "slow_down_layer_time": [ "10" ], @@ -52,6 +50,12 @@ "20", "20" ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json index d7c8b74a92..e7f37923e7 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json @@ -20,14 +20,25 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" ], + "filament_tower_ironing_area": [ + "8" + ], "filament_wipe": [ "1", "1" @@ -40,13 +51,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_tower_ironing_area": [ - "8" - ], "hole_coef_2": [ "-0.006" ], @@ -73,12 +77,6 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "60" - ], - "supertack_plate_temp_initial_layer": [ - "60" - ], "slow_down_layer_time": [ "10" ], @@ -86,6 +84,12 @@ "20", "20" ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json index 575f8d179b..fcdf6ebf6f 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json @@ -11,14 +11,25 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "30", "40" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" ], + "filament_tower_ironing_area": [ + "8" + ], "filament_wipe": [ "1", "1" @@ -35,13 +46,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_tower_ironing_area": [ - "8" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -59,12 +63,6 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "60" - ], - "supertack_plate_temp_initial_layer": [ - "60" - ], "slow_down_layer_time": [ "10" ], @@ -72,6 +70,12 @@ "20", "20" ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json index 354be5b294..d4f215c1f2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json @@ -11,14 +11,25 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "30", "40" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" ], + "filament_tower_ironing_area": [ + "8" + ], "filament_wipe": [ "1", "1" @@ -35,13 +46,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_tower_ironing_area": [ - "8" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -59,12 +63,6 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "60" - ], - "supertack_plate_temp_initial_layer": [ - "60" - ], "slow_down_layer_time": [ "10" ], @@ -72,6 +70,12 @@ "20", "20" ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json index f6e9b618c7..8676d31a7e 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json index b503b9bb4f..92975bb8ef 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json @@ -64,6 +64,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json index aa4e605e81..44485b62c0 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json @@ -70,6 +70,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.2 nozzle.json index 9ea3233d3d..507f540dbb 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.2 nozzle.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG01_18", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.4 nozzle.json index afd6164e2b..adc6d5bce6 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.4 nozzle.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG01_16", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "6", "6" diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json index 8cb9d8c558..fa7ddc9285 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json @@ -11,6 +11,10 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "16", "16" diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json index a750df1f5d..72f8882f70 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "hole_limit_min": [ "0.075" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json index d3fc772433..6563a1f594 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json @@ -73,6 +73,10 @@ "hole_limit_min": [ "0.075" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json index a7fbb19486..845a707c64 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json @@ -23,6 +23,10 @@ "fan_min_speed": [ "5" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "11.5", "11.5" diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json index 4ccca6512e..aae4388a36 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json @@ -14,6 +14,10 @@ "fan_min_speed": [ "5" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "11.5", "11.5" diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json index c24a16b023..f45467d04b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json index ed32363c4e..1c82185834 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json index 581fcfe62b..4f30395743 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json @@ -14,6 +14,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.6", "0.6" diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json index d268113119..07ee98f7e6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json @@ -84,6 +84,10 @@ "hole_limit_min": [ "0.05" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json index 4903eb9ff5..31a2d12e8f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json @@ -100,6 +100,10 @@ "hole_limit_min": [ "0.05" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json index 270e28058e..a8f668860c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json @@ -100,6 +100,10 @@ "hole_limit_min": [ "0.05" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json index bc513f9629..3621e07963 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json @@ -100,6 +100,10 @@ "hole_limit_min": [ "0.05" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json index 57d23d5f8c..9c49c6d367 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json @@ -20,6 +20,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -46,16 +50,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json index 7966c82a4f..082574bd82 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json @@ -29,6 +29,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,6 +41,10 @@ "30", "40" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -53,10 +61,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_3": [ "0.18" ], @@ -74,16 +78,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json index d003594c7e..ded3b4e3d9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json @@ -20,6 +20,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -28,6 +32,10 @@ "30", "40" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -44,10 +52,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -62,16 +66,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json index 112c7f84dc..7744bcf792 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json @@ -29,6 +29,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,6 +41,10 @@ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -53,10 +61,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_3": [ "0.18" ], @@ -74,16 +78,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json index 26c98d019a..31708faa3f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json index a7d06d2d86..5572a30c6c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json index 19a1d71f9d..c2bec3f783 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.2 nozzle.json index 73b0a5fe84..bff31010ae 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.8 nozzle.json index 9c80781772..cf17ea5af0 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP.json index e7d6792349..32df6b69fd 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json index 4a379e781d..d7d9738881 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json index 464a905652..9d42d63c20 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json index f9a2af87e3..79f754c61b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.2 nozzle.json index 74f9874a8b..d3db19b02b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.8 nozzle.json index bb49113ba9..19f76bd953 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP.json index 687e172c42..e4f3c42060 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json index 0879968ec0..2556d17580 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json index d667fabf6e..7c80bb47ce 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP 0.2 nozzle.json index 9f3eccf53a..0faa39a293 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "18", "18" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP.json index 0e4920744c..f8edcb3f46 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "18", "18" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json index ae7dae38a7..b81d029825 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json @@ -1,7 +1,7 @@ { "type": "filament", "name": "Bambu PLA Glow @BBL X2D 0.2 nozzle", - "inherits": "Bambu PLA Glow @BBL X1C", + "inherits": "Bambu PLA Glow @base", "from": "system", "setting_id": "GFSA12_22", "instantiation": "true", @@ -12,48 +12,115 @@ "55" ], "filament_cooling_before_tower": [ + "10", + "10", "10", "10" ], "filament_deretraction_speed": [ "nil", - "nil" + "nil", + "50", + "50" ], "filament_extruder_compatibility": [ - "9" + "8" + ], + "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98" ], "filament_flush_volumetric_speed": [ + "3", + "3", "3", "3" ], "filament_max_volumetric_speed": [ "2", - "2" + "2", + "0.5", + "0.5" ], "filament_printable": [ "0" ], + "filament_ramming_travel_time": [ + "0", + "0", + "0", + "0" + ], "filament_retraction_distances_when_cut": [ + "10", + "10", "10", "10" ], "filament_retraction_length": [ "nil", - "nil" + "nil", + "5", + "5" ], "filament_retraction_speed": [ "nil", - "nil" + "nil", + "50", + "50" ], "filament_tower_interface_print_temp": [ "220" ], + "filament_wipe": [ + "nil", + "nil", + "1", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "1", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "Spiral Lift", + "nil" + ], "first_x_layer_fan_speed": [ "40" ], + "include": [ + "fdm_filament_template_direct_bowden" + ], + "nozzle_temperature": [ + "220", + "220", + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220", + "220", + "220" + ], "retraction_distances_when_ec": [ "3", - "3" + "3", + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20", + "20", + "20" ], "compatible_printers": [ "Bambu Lab X2D 0.2 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json index 0dea40bcdd..938f70ef5f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json @@ -69,6 +69,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json index 275e7d5ed6..d76010b7fc 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json @@ -100,6 +100,10 @@ "hole_coef_2": [ "-0.0081" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json index 52b98b8d19..04b43d8d0c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json @@ -100,6 +100,10 @@ "hole_coef_2": [ "-0.0081" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json index 7a3a2d49e0..3844c578ee 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json @@ -20,6 +20,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_cost": [ "24.99" ], @@ -56,16 +60,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json index 1568797ff5..a1c3711e9e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json @@ -14,12 +14,12 @@ "counter_coef_3": [ "-0.32" ], - "counter_limit_min": [ - "-0.4" - ], "counter_limit_max": [ "0.05" ], + "counter_limit_min": [ + "-0.4" + ], "eng_plate_temp": [ "55" ], @@ -32,6 +32,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_cost": [ "24.99" ], @@ -46,6 +50,10 @@ "20", "30" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -62,10 +70,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0081" ], @@ -83,16 +87,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json index b67f6e1fd8..b085e0d987 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json @@ -14,12 +14,12 @@ "counter_coef_3": [ "-0.32" ], - "counter_limit_min": [ - "-0.4" - ], "counter_limit_max": [ "0.05" ], + "counter_limit_min": [ + "-0.4" + ], "eng_plate_temp": [ "55" ], @@ -32,6 +32,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_cost": [ "24.99" ], @@ -46,6 +50,10 @@ "20", "30" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -62,10 +70,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0081" ], @@ -83,16 +87,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json index 14f1fb55a7..924d3416d2 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json @@ -20,6 +20,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_cost": [ "24.99" ], @@ -34,6 +38,10 @@ "20", "30" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -50,10 +58,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -68,16 +72,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json index d60383e980..29a784e20a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json index 582e8626dd..6eea866219 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2DP.json index ab5f70b640..a12b15a930 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "12", "12" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json index cf0f1c163c..8b970d07f2 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json @@ -84,6 +84,10 @@ "hole_limit_min": [ "0.046" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json index 78677a34c1..2d21adc510 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json @@ -100,6 +100,10 @@ "hole_limit_min": [ "0.046" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json index 850d10c5ba..9bcd43edb4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json @@ -100,6 +100,10 @@ "hole_limit_min": [ "0.046" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json index 4b911dd21d..59c9bd2677 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json @@ -100,6 +100,10 @@ "hole_limit_min": [ "0.046" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json index cb6cb8655d..f69cf85eca 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json @@ -20,6 +20,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -46,16 +50,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json index 1eed4272cf..632e465ea8 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json @@ -14,12 +14,12 @@ "counter_coef_3": [ "-0.32" ], - "counter_limit_min": [ - "-0.4" - ], "counter_limit_max": [ "0.05" ], + "counter_limit_min": [ + "-0.4" + ], "eng_plate_temp": [ "55" ], @@ -32,6 +32,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -40,6 +44,10 @@ "30", "40" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -56,10 +64,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0081" ], @@ -80,16 +84,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json index c398c1ae11..85a1fbcf4f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json @@ -20,6 +20,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -28,6 +32,10 @@ "30", "40" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -44,10 +52,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -62,16 +66,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json index 1371f7b413..364b46320b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json @@ -14,12 +14,12 @@ "counter_coef_3": [ "-0.32" ], - "counter_limit_min": [ - "-0.4" - ], "counter_limit_max": [ "0.05" ], + "counter_limit_min": [ + "-0.4" + ], "eng_plate_temp": [ "55" ], @@ -32,6 +32,10 @@ "fan_min_speed": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -40,6 +44,10 @@ "25", "35" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -56,10 +64,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0081" ], @@ -80,16 +84,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json index a017e39df1..d500051bb1 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json index 28c1ddad53..7a39073469 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json index 0419478d11..7476f54129 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP 0.2 nozzle.json index 5a9f83e173..c3d438baa2 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP.json index cbdc10d23c..87e11db490 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json index ff2a83bfd4..5f6ac11da9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json @@ -81,6 +81,10 @@ "hole_limit_min": [ "0.0336" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json index 07cbb2778a..a11705a696 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json @@ -97,6 +97,10 @@ "hole_limit_min": [ "0.0336" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json index 10e290f8ee..681ba29bc9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json @@ -97,6 +97,10 @@ "hole_limit_min": [ "0.0336" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json index e566fb94cf..7a619beb01 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json @@ -14,6 +14,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json index f12e97abfe..3a26b9d69e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json @@ -14,18 +14,22 @@ "counter_coef_3": [ "-0.01" ], - "counter_limit_min": [ - "-0.05" - ], "counter_limit_max": [ "0.05" ], + "counter_limit_min": [ + "-0.05" + ], "eng_plate_temp": [ "55" ], "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -34,6 +38,10 @@ "12", "12" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -50,10 +58,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0081" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json index 7e318cabec..6d0f939e60 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json index 26fd68b90c..d5cf41c8a5 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json index b1b46146d5..e09cba9375 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json index 2c3a223852..6ef42bcf5f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json @@ -14,6 +14,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -40,12 +44,6 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "35" - ], - "supertack_plate_temp_initial_layer": [ - "35" - ], "slow_down_layer_time": [ "6" ], @@ -53,6 +51,12 @@ "20", "20" ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json index cdcb0b0a65..90bf2f5a90 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json @@ -14,6 +14,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -22,6 +26,10 @@ "12", "12" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -38,10 +46,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -56,12 +60,6 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "35" - ], - "supertack_plate_temp_initial_layer": [ - "35" - ], "slow_down_layer_time": [ "6" ], @@ -69,6 +67,12 @@ "20", "20" ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json index cdaa7b9f49..4932aa6756 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json index 6a406fd1c7..5f18530fb3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2DP.json index 5cc43d1f10..8339de1440 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "12", "12" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json index 3bb6a80c9e..afc18f86e9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json index e6324c6273..4cd0f748a5 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json @@ -91,6 +91,10 @@ "hole_limit_min": [ "0.08" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json index 202c1e64f3..a211aa7b06 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json @@ -91,6 +91,10 @@ "hole_limit_min": [ "0.08" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP 0.2 nozzle.json index eb92ecc2e1..18b446e8db 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP.json index 3617d9aec9..3b89d63f14 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2DP.json @@ -20,6 +20,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -28,6 +32,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -44,10 +52,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0081" ], @@ -71,16 +75,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json index 7957ba5fce..4dddeede4f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json index 376fce74fa..1c25c29fd9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json @@ -79,6 +79,10 @@ "hole_coef_3": [ "0.18" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json index bda79d23a0..e1c4a1853f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json @@ -79,6 +79,10 @@ "hole_coef_3": [ "0.18" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json index eca6578b7a..ef42d0eef3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json @@ -79,6 +79,10 @@ "hole_coef_3": [ "0.18" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.2 nozzle.json index 214a7f7a2e..c8c5f19e1c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.6 nozzle.json index 33e6b27eac..b8e2751822 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.6 nozzle.json @@ -20,6 +20,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -28,6 +32,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -44,10 +52,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_3": [ "0.18" ], @@ -65,16 +69,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.8 nozzle.json index 22166caeda..d35ab9dd0c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP.json index c54528bfd6..a3cdeebf8e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2DP.json @@ -20,6 +20,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -28,6 +32,10 @@ "21", "21" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -44,10 +52,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_3": [ "0.18" ], @@ -65,16 +69,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json index 5dbff6b43b..743a5d09aa 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json index a131fd1b08..a492f29e87 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.2 nozzle.json index b30603a9bd..4463cff56e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -34,16 +38,16 @@ "220", "220" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.8 nozzle.json index a3dfbd8b84..9e5735329e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "12", "12" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -50,16 +54,16 @@ "220", "220" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle", "Bambu Lab H2D Pro 0.8 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP.json index bcc0fbcd61..eead289e04 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "12", "12" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -50,16 +54,16 @@ "220", "220" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json index 59607fdfd2..734542a160 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json index cf39af09ee..71b8ba261f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP 0.8 nozzle.json index 48ba5c8101..5fb03cf144 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP 0.8 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "18", "18" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP.json index 57e75693ef..da0d1f7d95 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "18", "18" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], @@ -53,16 +57,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json index cd74dae322..fd17705077 100644 --- a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json @@ -78,6 +78,10 @@ "hole_limit_min": [ "0.048" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json index 3a729926ff..7ac82f8007 100644 --- a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json @@ -78,6 +78,10 @@ "hole_limit_min": [ "0.048" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.4 nozzle.json index 1495cee6d8..6dd87ded4b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.4 nozzle.json @@ -20,6 +20,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -28,6 +32,10 @@ "15", "15" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -44,10 +52,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "hole_coef_2": [ "-0.0103" ], diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.6 nozzle.json index 818a02e9d5..767e62c8e4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2DP 0.6 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" @@ -19,6 +23,10 @@ "18", "18" ], + "filament_ramming_travel_time": [ + "0", + "0" + ], "filament_retraction_length": [ "0.4", "0.4" @@ -35,10 +43,6 @@ "Spiral Lift", "Spiral Lift" ], - "filament_ramming_travel_time": [ - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json index 3d90bfd845..0aa0c392e5 100644 --- a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json @@ -74,6 +74,10 @@ "hole_limit_min": [ "0.04" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json index cdaab2e55e..0b5d17d816 100644 --- a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json @@ -74,6 +74,10 @@ "hole_limit_min": [ "0.04" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2DP.json index 4e2d94c36b..6e1e7d2e3e 100644 --- a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json index ee26aa0646..5617e721a8 100644 --- a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json @@ -74,6 +74,10 @@ "hole_limit_min": [ "0.035" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json index 19a3084bfb..03bfd48d8e 100644 --- a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json @@ -74,6 +74,10 @@ "hole_limit_min": [ "0.035" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2DP.json index 61ecf49b51..a18c42afc6 100644 --- a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2DP.json @@ -17,6 +17,10 @@ "counter_limit_max": [ "0.03" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json index 08198375e9..d073cc80fb 100644 --- a/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json index 307b8116f7..fc578d6c51 100644 --- a/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PVA @BBL H2DP.json index 78c0cbcb9c..46a782b151 100644 --- a/resources/profiles/BBL/filament/Bambu PVA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json index 203b6f1705..ab93afc059 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json index 2b609771e2..30b91c3f61 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2DP.json index 9216d78cbd..e1a428af28 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json index f1169ff592..50022ade4b 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json @@ -60,6 +60,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json index da73d6d3c4..ea71c7c280 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json @@ -60,6 +60,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json index 23c8f86343..d11ac69ad8 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json @@ -60,6 +60,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json index 0a4974b639..6d3d64f4e4 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json @@ -17,6 +17,10 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -43,16 +47,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json index 1497033f3e..967667d7b6 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json @@ -17,6 +17,10 @@ "fan_min_speed": [ "20" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -43,16 +47,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json index e968881647..00c26d3422 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json @@ -54,6 +54,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json index df068704fd..f66d54e59d 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json @@ -54,6 +54,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json index 82c005b412..447840ce17 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json @@ -54,6 +54,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP 0.2 nozzle.json index 85be239d9f..ca040b0b4b 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -37,13 +41,13 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "0" - ], "slow_down_min_speed": [ "20", "20" ], + "supertack_plate_temp": [ + "0" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP.json index 67aecbda50..f2a885ec7b 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -37,13 +41,13 @@ "pre_start_fan_time": [ "2" ], - "supertack_plate_temp": [ - "0" - ], "slow_down_min_speed": [ "20", "20" ], + "supertack_plate_temp": [ + "0" + ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json index 1826ce95a0..ff144a06c1 100644 --- a/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json index 3eda01ddb0..ae9fcbf3ae 100644 --- a/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support G @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support G @BBL H2DP.json index 843df8eede..b95357fd32 100644 --- a/resources/profiles/BBL/filament/Bambu Support G @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support G @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json index 91a289356d..f2a1dd4faa 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json @@ -54,6 +54,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json index ebbee7442f..40d3f32a08 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json @@ -54,6 +54,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json index a0374411a7..9bb7f95dfb 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json @@ -54,6 +54,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP 0.2 nozzle.json index b700863f6b..5d2410e4c4 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.2 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP.json index c21165ef4d..82807fa583 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -37,16 +41,16 @@ "pre_start_fan_time": [ "2" ], + "slow_down_min_speed": [ + "20", + "20" + ], "supertack_plate_temp": [ "40" ], "supertack_plate_temp_initial_layer": [ "40" ], - "slow_down_min_speed": [ - "20", - "20" - ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json index 3dc10f8fc4..f803973b8d 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json @@ -43,6 +43,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json index be547aeb85..5bf5a3d023 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json @@ -43,6 +43,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2DP.json index 4bfa4dabb1..36e7e75f51 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "6", "6" diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json index bcd081b4f6..0952288d0a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json @@ -93,6 +93,10 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json index dec11bd556..38c42295d8 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json @@ -190,6 +190,11 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json index 48f4aebaf0..5afdd55df6 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json @@ -25,9 +25,9 @@ "25" ], "filament_cooling_before_tower": [ - "0", - "0", - "0" + "10", + "10", + "10" ], "filament_deretraction_speed": [ "10", @@ -190,6 +190,11 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json index 81f6ab984a..3db87e503a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json @@ -90,6 +90,10 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json index 70b59a954c..2be532b774 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json @@ -90,6 +90,10 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json index 332db4a9c6..81fd1e0ba7 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json @@ -190,6 +190,11 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json index 001732478d..5fdaa02777 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json @@ -187,6 +187,11 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json index ad7d06beee..cb24fbdbdd 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json @@ -14,11 +14,21 @@ "eng_plate_temp_initial_layer": [ "35" ], - "filament_cooling_before_tower": [ + "filament_adaptive_volumetric_speed": [ "0", "0", "0" ], + "filament_bridge_speed": [ + "25", + "25", + "30" + ], + "filament_cooling_before_tower": [ + "10", + "10", + "10" + ], "filament_density": [ "1.22" ], @@ -27,6 +37,16 @@ "25", "30" ], + "filament_enable_overhang_speed": [ + "1", + "1", + "1" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], "filament_flow_ratio": [ "1.05", "1.05", @@ -52,6 +72,51 @@ "2.8", "5.6" ], + "filament_overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "filament_overhang_2_4_speed": [ + "50", + "50", + "30" + ], + "filament_overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "filament_overhang_4_4_speed": [ + "10", + "10", + "30" + ], + "filament_overhang_totally_speed": [ + "10", + "10", + "30" + ], + "filament_pre_cooling_temperature": [ + "195", + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0", + "0" + ], + "filament_ramming_travel_time": [ + "20", + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0", + "0" + ], "filament_ramming_volumetric_speed": [ "0.7", "0.7", @@ -67,6 +132,11 @@ "nil", "nil" ], + "filament_retract_length_nc": [ + "14", + "14", + "14" + ], "filament_retract_restart_extra": [ "nil", "nil", @@ -117,78 +187,13 @@ "Spiral Lift", "Spiral Lift" ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow", - "Direct Drive TPU High Flow" - ], - "filament_pre_cooling_temperature": [ - "195", - "195", - "195" - ], - "filament_pre_cooling_temperature_nc": [ - "0", - "0", - "0" - ], - "filament_ramming_travel_time": [ - "20", - "20", - "20" - ], - "filament_ramming_travel_time_nc": [ - "0", - "0", - "0" - ], - "filament_retract_length_nc": [ - "14", - "14", - "14" - ], - "filament_enable_overhang_speed": [ - "1", - "1", - "1" - ], - "filament_overhang_1_4_speed": [ - "0", - "0", - "0" - ], - "filament_overhang_2_4_speed": [ - "50", - "50", - "30" - ], - "filament_overhang_3_4_speed": [ - "30", - "30", - "30" - ], - "filament_overhang_4_4_speed": [ - "10", - "10", - "30" + "impact_strength_z": [ + "88.7" ], - "filament_overhang_totally_speed": [ + "filament_preheat_temperature_delta": [ "10", "10", - "30" - ], - "filament_bridge_speed": [ - "25", - "25", - "30" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0", - "0" - ], - "impact_strength_z": [ - "88.7" + "10" ], "include": [ "fdm_filament_template_direct_dual" @@ -198,9 +203,6 @@ "1", "1" ], - "nozzle_temperature_range_high": [ - "250" - ], "nozzle_temperature": [ "225", "225", @@ -211,6 +213,9 @@ "225", "220" ], + "nozzle_temperature_range_high": [ + "250" + ], "override_process_overhang_speed": [ "0", "0", diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json index 46376f7c05..6f8fc61c4e 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json @@ -14,6 +14,10 @@ "eng_plate_temp_initial_layer": [ "35" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_density": [ "1.22" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json index 761f731036..20635a2ab5 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json @@ -25,9 +25,9 @@ "30" ], "filament_cooling_before_tower": [ - "0", - "0", - "0" + "10", + "10", + "10" ], "filament_deretraction_speed": [ "25", @@ -187,6 +187,11 @@ "impact_strength_z": [ "88.7" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json index 92b8ed61e8..7365e27731 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json @@ -81,6 +81,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json index c6923dbfc5..a512831aec 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json @@ -81,6 +81,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json index 82ca37850d..ecda1425d6 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json @@ -184,6 +184,11 @@ "0", "0" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json index c73668fb4f..b2c79b2b94 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json @@ -14,16 +14,36 @@ "eng_plate_temp_initial_layer": [ "35" ], - "filament_cooling_before_tower": [ + "filament_adaptive_volumetric_speed": [ "0", "0", "0" ], + "filament_bridge_speed": [ + "25", + "25", + "25" + ], + "filament_cooling_before_tower": [ + "10", + "10", + "10" + ], "filament_deretraction_speed": [ "10", "10", "10" ], + "filament_enable_overhang_speed": [ + "1", + "1", + "1" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], "filament_flow_ratio": [ "1", "1", @@ -49,6 +69,51 @@ "3.6", "3.6" ], + "filament_overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "filament_overhang_2_4_speed": [ + "50", + "50", + "50" + ], + "filament_overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "filament_overhang_4_4_speed": [ + "10", + "10", + "10" + ], + "filament_overhang_totally_speed": [ + "10", + "10", + "10" + ], + "filament_pre_cooling_temperature": [ + "200", + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0", + "0" + ], + "filament_ramming_travel_time": [ + "20", + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0", + "0" + ], "filament_ramming_volumetric_speed": [ "0.9", "0.9", @@ -64,6 +129,11 @@ "nil", "nil" ], + "filament_retract_length_nc": [ + "14", + "14", + "14" + ], "filament_retract_restart_extra": [ "nil", "nil", @@ -114,76 +184,11 @@ "nil", "nil" ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow", - "Direct Drive TPU High Flow" - ], - "filament_pre_cooling_temperature": [ - "200", - "200", - "200" - ], - "filament_pre_cooling_temperature_nc": [ - "0", - "0", - "0" - ], - "filament_ramming_travel_time": [ - "20", - "20", - "20" - ], - "filament_ramming_travel_time_nc": [ - "0", - "0", - "0" - ], - "filament_retract_length_nc": [ - "14", - "14", - "14" - ], - "filament_enable_overhang_speed": [ - "1", - "1", - "1" - ], - "filament_overhang_1_4_speed": [ - "0", - "0", - "0" - ], - "filament_overhang_2_4_speed": [ - "50", - "50", - "50" - ], - "filament_overhang_3_4_speed": [ - "30", - "30", - "30" - ], - "filament_overhang_4_4_speed": [ + "filament_preheat_temperature_delta": [ "10", "10", "10" ], - "filament_overhang_totally_speed": [ - "10", - "10", - "10" - ], - "filament_bridge_speed": [ - "25", - "25", - "25" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json index 160867a846..6ef6fefb4a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json @@ -81,6 +81,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json index b1e5cd39b0..bdfb7575dc 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json @@ -81,6 +81,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json index a679bb2c0f..8f7628fe1a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json @@ -184,6 +184,11 @@ "0", "0" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json index 0d20ac7460..721fae1b45 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json @@ -5,29 +5,14 @@ "from": "system", "setting_id": "GFSU00_21", "instantiation": "true", - "filament_deretraction_speed": [ - "10", - "10", + "filament_bridge_speed": [ + "25", + "25", "50" ], - "filament_wipe": [ - "nil", - "nil", - "1" - ], - "filament_overhang_3_4_speed": [ - "30", - "30", - "25" - ], - "filament_overhang_4_4_speed": [ + "filament_deretraction_speed": [ "10", "10", - "25" - ], - "filament_bridge_speed": [ - "25", - "25", "50" ], "filament_max_volumetric_speed": [ @@ -35,51 +20,31 @@ "12", "16" ], - "filament_z_hop_types": [ - "nil", - "nil", - "Slope Lift" + "filament_retraction_length": [ + "2", + "2", + "0.8" ], "filament_retraction_speed": [ "10", "10", "50" ], - "filament_overhang_2_4_speed": [ - "50", - "50", - "25" - ], - "filament_overhang_totally_speed": [ - "10", - "10", - "25" - ], - "filament_retraction_length": [ - "2", - "2", - "0.8" - ], - "filament_wipe_distance": [ + "filament_z_hop_types": [ "nil", "nil", - "1" + "Slope Lift" ], - "nozzle_temperature_initial_layer": [ + "nozzle_temperature": [ "230", "230", "240" ], - "nozzle_temperature": [ + "nozzle_temperature_initial_layer": [ "230", "230", "240" ], - "override_process_overhang_speed": [ - "0", - "0", - "1" - ], "slow_down_min_speed": [ "10", "10", diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json index 3fa693d660..f426804042 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json @@ -14,16 +14,36 @@ "eng_plate_temp_initial_layer": [ "35" ], - "filament_cooling_before_tower": [ + "filament_adaptive_volumetric_speed": [ "0", "0", "0" ], + "filament_bridge_speed": [ + "25", + "25", + "25" + ], + "filament_cooling_before_tower": [ + "10", + "10", + "10" + ], "filament_deretraction_speed": [ "10", "10", "40" ], + "filament_enable_overhang_speed": [ + "1", + "1", + "1" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], "filament_flow_ratio": [ "1", "1", @@ -49,6 +69,51 @@ "12", "12" ], + "filament_overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "filament_overhang_2_4_speed": [ + "50", + "50", + "25" + ], + "filament_overhang_3_4_speed": [ + "30", + "30", + "25" + ], + "filament_overhang_4_4_speed": [ + "10", + "10", + "25" + ], + "filament_overhang_totally_speed": [ + "10", + "10", + "25" + ], + "filament_pre_cooling_temperature": [ + "200", + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0", + "0" + ], + "filament_ramming_travel_time": [ + "20", + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0", + "0" + ], "filament_ramming_volumetric_speed": [ "3.0", "3.0", @@ -64,6 +129,11 @@ "nil", "nil" ], + "filament_retract_length_nc": [ + "14", + "14", + "14" + ], "filament_retract_restart_extra": [ "nil", "nil", @@ -114,75 +184,10 @@ "nil", "Spiral Lift" ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow", - "Direct Drive TPU High Flow" - ], - "filament_pre_cooling_temperature": [ - "200", - "200", - "200" - ], - "filament_pre_cooling_temperature_nc": [ - "0", - "0", - "0" - ], - "filament_ramming_travel_time": [ - "20", - "20", - "20" - ], - "filament_ramming_travel_time_nc": [ - "0", - "0", - "0" - ], - "filament_retract_length_nc": [ - "14", - "14", - "14" - ], - "filament_enable_overhang_speed": [ - "1", - "1", - "1" - ], - "filament_overhang_1_4_speed": [ - "0", - "0", - "0" - ], - "filament_overhang_2_4_speed": [ - "50", - "50", - "25" - ], - "filament_overhang_3_4_speed": [ - "30", - "30", - "25" - ], - "filament_overhang_4_4_speed": [ - "10", + "filament_preheat_temperature_delta": [ "10", - "25" - ], - "filament_overhang_totally_speed": [ "10", - "10", - "25" - ], - "filament_bridge_speed": [ - "25", - "25", - "25" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0", - "0" + "10" ], "include": [ "fdm_filament_template_direct_dual" diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json index d56bfdcc65..5fb3035c63 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json @@ -72,6 +72,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json index cd33ee8119..869301016f 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json @@ -72,6 +72,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json index b0de474925..22089f6fe1 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json @@ -17,6 +17,10 @@ "fan_max_speed": [ "40" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.97", "0.97" @@ -25,14 +29,6 @@ "12", "12" ], - "filament_ramming_volumetric_speed": [ - "4.5", - "4.5" - ], - "filament_retraction_length": [ - "0.4", - "0.4" - ], "filament_pre_cooling_temperature": [ "200", "200" @@ -41,6 +37,14 @@ "20", "20" ], + "filament_ramming_volumetric_speed": [ + "4.5", + "4.5" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json index e0a0a971b0..a95f8b7000 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json @@ -49,6 +49,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json index 531c2f7483..ad05c962a4 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json @@ -63,6 +63,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json index 06093b3245..71efcfab86 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json @@ -63,6 +63,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2DP 0.2 nozzle.json index 2cf093f9b6..034c767566 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "2", "2" diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2DP.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2DP.json index d524eb6f91..808befc013 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "15", "15" diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json index 0786744651..54194fbb21 100644 --- a/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json @@ -43,6 +43,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json index 2f6b142a40..1d5e480bf4 100644 --- a/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json @@ -63,6 +63,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json index b1f921f792..14291358fe 100644 --- a/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json @@ -63,6 +63,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2DP 0.2 nozzle.json index c20241f437..d18f10b86c 100644 --- a/resources/profiles/BBL/filament/Generic ASA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "2", "2" diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2DP.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2DP.json index be62b6e751..cf40a83df7 100644 --- a/resources/profiles/BBL/filament/Generic ASA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "12", "12" diff --git a/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json index 2e3b70a231..990c10b478 100644 --- a/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json index 821c7a34a0..a4c6f0be96 100644 --- a/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic BVOH @BBL H2DP.json b/resources/profiles/BBL/filament/Generic BVOH @BBL H2DP.json index bec0adad9f..0e0c3a994b 100644 --- a/resources/profiles/BBL/filament/Generic BVOH @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic BVOH @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json index ee0b3afcd8..99d1020fcb 100644 --- a/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json b/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json index f16ab64929..cbf8716f82 100644 --- a/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic EVA @BBL H2DP.json b/resources/profiles/BBL/filament/Generic EVA @BBL H2DP.json index cafb090334..1a845320ad 100644 --- a/resources/profiles/BBL/filament/Generic EVA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic EVA @BBL H2DP.json @@ -12,6 +12,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json index 182d0a9b55..bf887ab1a9 100644 --- a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json index 641633766a..4665d466d3 100644 --- a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json index b32517a93f..f073ffc1e2 100644 --- a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP 0.2 nozzle.json index da28e0ed9f..c27f7b5a17 100644 --- a/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP 0.2 nozzle.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSS98_11", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP.json index b2eba3fc9e..a534eca8c3 100644 --- a/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSS98_10", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json index 3f82c49631..135c09af95 100644 --- a/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PA @BBL H2C.json index e512a6cbe0..f1c082e264 100644 --- a/resources/profiles/BBL/filament/Generic PA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PA @BBL H2C.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PA @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PA @BBL H2DP.json index 38745c5d5d..dbaee5f823 100644 --- a/resources/profiles/BBL/filament/Generic PA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PA @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSN99_03", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json index e6e58c31f6..949f213db1 100644 --- a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json index 190ca5fbb2..e45072ec52 100644 --- a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2DP.json index d8910089aa..c4a8fbb2c8 100644 --- a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json index f870c19c38..a8ed1fae09 100644 --- a/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json index 0a918a325f..8ed4c849e2 100644 --- a/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json @@ -63,6 +63,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2C.json b/resources/profiles/BBL/filament/Generic PC @BBL H2C.json index d780b44456..cf385a54d9 100644 --- a/resources/profiles/BBL/filament/Generic PC @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2C.json @@ -63,6 +63,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PC @BBL H2DP 0.2 nozzle.json index 68d0e436b6..68becb1906 100644 --- a/resources/profiles/BBL/filament/Generic PC @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PC @BBL H2DP.json index e57f8e7737..8b75dc13d4 100644 --- a/resources/profiles/BBL/filament/Generic PC @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.94", "0.94" diff --git a/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json index da05b779bd..0fb17404d3 100644 --- a/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json @@ -40,6 +40,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json index f160931699..1f446ba0fa 100644 --- a/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json @@ -40,6 +40,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PCTG @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PCTG @BBL H2DP.json index 3eed06013f..2fba98ad14 100644 --- a/resources/profiles/BBL/filament/Generic PCTG @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PCTG @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG97_05", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "6", "6" diff --git a/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json index 1e47931eb4..a0242b1ed9 100644 --- a/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PE @BBL H2C.json b/resources/profiles/BBL/filament/Generic PE @BBL H2C.json index a315fbd5df..90663faa1c 100644 --- a/resources/profiles/BBL/filament/Generic PE @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PE @BBL H2C.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PE @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PE @BBL H2DP.json index 0d32133e49..0764a31a50 100644 --- a/resources/profiles/BBL/filament/Generic PE @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PE @BBL H2DP.json @@ -12,6 +12,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json index 9a7d3dd3f0..25c43bf109 100644 --- a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json index d031c14bd7..8279e2f523 100644 --- a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2DP.json index aee9030c74..455af49506 100644 --- a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json index 5169e53b10..fb92858690 100644 --- a/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json index 188e36f968..ebb502db13 100644 --- a/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json @@ -64,6 +64,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json index 383031ead1..86d79a6690 100644 --- a/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json @@ -64,6 +64,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2DP 0.2 nozzle.json index 7c9526766b..9b3db34823 100644 --- a/resources/profiles/BBL/filament/Generic PETG @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2DP 0.2 nozzle.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG99_14", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2DP.json index e562e5a7bb..6cbef8f4ce 100644 --- a/resources/profiles/BBL/filament/Generic PETG @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG99_13", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "12", "12" diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json index 65ba23b2b7..bd018277f2 100644 --- a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json index 68bc60174a..59a4ac2985 100644 --- a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json @@ -64,6 +64,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json index e070ba25a3..be560f4615 100644 --- a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json @@ -64,6 +64,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP 0.2 nozzle.json index 2c532aea35..fd48dad992 100644 --- a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP 0.2 nozzle.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG96_13", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP.json index 76f817c1e5..00943fdd36 100644 --- a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2DP.json @@ -5,18 +5,22 @@ "from": "system", "setting_id": "GFSG96_12", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "16", "16" ], - "filament_retraction_length": [ - "0.4", - "0.4" - ], "filament_ramming_travel_time": [ "0", "0" ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json index 915c13e0d1..1f8b7c187b 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json @@ -49,6 +49,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json index 08f0aec38e..84d5995e56 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json @@ -49,6 +49,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json index 08d31c6fa4..d0e4ff8752 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json @@ -14,6 +14,10 @@ "fan_min_speed": [ "5" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "11.5", "11.5" diff --git a/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json index b8e01ae8f0..02dedb5a4b 100644 --- a/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json index 38b670e9d3..92b91b53d9 100644 --- a/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PHA @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PHA @BBL H2DP.json index c4eecbc44f..373ff783a0 100644 --- a/resources/profiles/BBL/filament/Generic PHA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PHA @BBL H2DP.json @@ -12,6 +12,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json index 87a2e3b776..634dc781c4 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json index dd5d48f201..cb11890de6 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json index 1ea2806f22..1c75fa6506 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2DP 0.2 nozzle.json index 7e9110ad77..7fec3e7924 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2DP.json index c36a2096d1..86f0e63424 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json index 8450af7a0d..736f9d5b73 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json @@ -57,6 +57,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json index 96d61cff5a..d5df660072 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json index 319105c73d..14fbe51106 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP 0.2 nozzle.json index 72c9201979..6420060c97 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP.json index ba05263fbb..04df3f4e6f 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json index 32d75cab4d..de0ef15aee 100644 --- a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json index 32e97105fa..ea92c0b932 100644 --- a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json @@ -73,6 +73,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2DP.json index 69315a2618..dbbc13a500 100644 --- a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json index dcca32ab47..101e575ab8 100644 --- a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json index b6d8b80fd9..d9e4f6302f 100644 --- a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2DP.json index 9aeaca5f3d..25176e2b10 100644 --- a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "12", "12" diff --git a/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json index 984d3f4da3..996e2d290c 100644 --- a/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PP @BBL H2C.json b/resources/profiles/BBL/filament/Generic PP @BBL H2C.json index 2a22e0c011..e126ec42e5 100644 --- a/resources/profiles/BBL/filament/Generic PP @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PP @BBL H2C.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PP @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PP @BBL H2DP.json index 6ceb66bfb4..b88298b5eb 100644 --- a/resources/profiles/BBL/filament/Generic PP @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PP @BBL H2DP.json @@ -12,6 +12,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json index cd8baa308e..fa058c88c2 100644 --- a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json index 989b29e5f3..8ffd3ead5b 100644 --- a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2DP.json index 6e6132b264..c34bcd9070 100644 --- a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2DP.json @@ -12,6 +12,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json index 4886afb085..d2fd22d48a 100644 --- a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json index f75c67da71..e8ba9c2bca 100644 --- a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json @@ -51,6 +51,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2DP.json index dfab74d3f4..e82993c8d3 100644 --- a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2DP.json @@ -12,6 +12,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json index 2b6b7ba633..06fb08f9ef 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json @@ -50,6 +50,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json index f6ba629909..71995c8491 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json @@ -53,6 +53,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json index da1b7e3b04..ab2c95d6ec 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json @@ -11,6 +11,10 @@ "fan_max_speed": [ "35" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json index 5c4e63a472..e6c91df1b1 100644 --- a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json index 8b76d2db52..8bc09282ac 100644 --- a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2DP.json index fe195d6cfa..490edf6139 100644 --- a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json index a6cf209b1a..d550bb842d 100644 --- a/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json index 8a6a6fdc8c..9d4796ffaa 100644 --- a/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPS @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PPS @BBL H2DP.json index 5cf65c55ce..8b260eb50d 100644 --- a/resources/profiles/BBL/filament/Generic PPS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PPS @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFST97_02", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json index f107c61802..839577bca9 100644 --- a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json @@ -44,6 +44,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json index 54074dd93c..105a2484c4 100644 --- a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json @@ -47,6 +47,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2DP.json index fea72eab14..1b93a87945 100644 --- a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFST98_02", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.96", "0.96" diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json index 137e9c641e..353ade784e 100644 --- a/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json @@ -46,6 +46,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json index 87d38509d1..22b232a25a 100644 --- a/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json @@ -46,6 +46,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json index eece4c7b0a..a5041db61f 100644 --- a/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json @@ -46,6 +46,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2DP.json index 887080e2d8..cac607510c 100644 --- a/resources/profiles/BBL/filament/Generic PVA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "16", "16" diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json index 777e612ff3..d631f0e174 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json @@ -72,6 +72,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json index abe69a37bc..df205a1936 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json @@ -72,6 +72,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json index a285d962fd..e462b7242f 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json @@ -187,6 +187,11 @@ "0", "0" ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json index 79bfcb6df0..456941431d 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json @@ -14,16 +14,36 @@ "eng_plate_temp_initial_layer": [ "35" ], - "filament_cooling_before_tower": [ + "filament_adaptive_volumetric_speed": [ "0", "0", "0" ], + "filament_bridge_speed": [ + "25", + "25", + "25" + ], + "filament_cooling_before_tower": [ + "10", + "10", + "10" + ], "filament_deretraction_speed": [ "nil", "nil", "nil" ], + "filament_enable_overhang_speed": [ + "1", + "1", + "1" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], "filament_flow_ratio": [ "1", "1", @@ -49,6 +69,54 @@ "3.2", "3.2" ], + "filament_overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "filament_overhang_2_4_speed": [ + "50", + "50", + "50" + ], + "filament_overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "filament_overhang_4_4_speed": [ + "10", + "10", + "10" + ], + "filament_overhang_totally_speed": [ + "10", + "10", + "10" + ], + "filament_pre_cooling_temperature": [ + "210", + "210", + "210" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0", + "0" + ], + "filament_printable": [ + "2" + ], + "filament_ramming_travel_time": [ + "20", + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0", + "0" + ], "filament_ramming_volumetric_speed": [ "0.8", "0.8", @@ -59,14 +127,16 @@ "-1", "-1" ], - "filament_printable": [ - "2" - ], "filament_retract_before_wipe": [ "nil", "nil", "nil" ], + "filament_retract_length_nc": [ + "14", + "14", + "14" + ], "filament_retract_restart_extra": [ "nil", "nil", @@ -117,76 +187,11 @@ "nil", "nil" ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow", - "Direct Drive TPU High Flow" - ], - "filament_pre_cooling_temperature": [ - "210", - "210", - "210" - ], - "filament_pre_cooling_temperature_nc": [ - "0", - "0", - "0" - ], - "filament_ramming_travel_time": [ - "20", - "20", - "20" - ], - "filament_ramming_travel_time_nc": [ - "0", - "0", - "0" - ], - "filament_retract_length_nc": [ - "14", - "14", - "14" - ], - "filament_enable_overhang_speed": [ - "1", - "1", - "1" - ], - "filament_overhang_1_4_speed": [ - "0", - "0", - "0" - ], - "filament_overhang_2_4_speed": [ - "50", - "50", - "50" - ], - "filament_overhang_3_4_speed": [ - "30", - "30", - "30" - ], - "filament_overhang_4_4_speed": [ + "filament_preheat_temperature_delta": [ "10", "10", "10" ], - "filament_overhang_totally_speed": [ - "10", - "10", - "10" - ], - "filament_bridge_speed": [ - "25", - "25", - "25" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0", - "0" - ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json index 8136372a6c..4f43457a68 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json @@ -74,6 +74,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json index 337e28343b..f718408da4 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json @@ -74,6 +74,10 @@ "filament_change_length_nc": [ "4" ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json index ec5f9844a8..42f65f4680 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json @@ -23,6 +23,10 @@ "fan_min_speed": [ "10" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "1", "1" @@ -31,10 +35,6 @@ "10.5", "10.5" ], - "filament_ramming_volumetric_speed": [ - "2.625", - "2.625" - ], "filament_pre_cooling_temperature": [ "200", "200" @@ -43,6 +43,10 @@ "20", "20" ], + "filament_ramming_volumetric_speed": [ + "2.625", + "2.625" + ], "include": [ "fdm_filament_template_direct_dual" ], diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP 0.2 nozzle.json index 397b69ede6..3dbd87ec38 100644 --- a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP.json index 3433333375..a7bc9fd687 100644 --- a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture PLA @BBL H2DP 0.2 nozzle.json index db1dc2f73f..36c80d8888 100644 --- a/resources/profiles/BBL/filament/Overture PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Overture PLA @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL H2DP.json b/resources/profiles/BBL/filament/Overture PLA @BBL H2DP.json index 60360dd97c..7d5dd1217c 100644 --- a/resources/profiles/BBL/filament/Overture PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Overture PLA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP 0.2 nozzle.json index 3851131d44..e46a562702 100644 --- a/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "2", "2" diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP.json index f461f48000..198c6f733a 100644 --- a/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "15", "15" diff --git a/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP 0.2 nozzle.json index 52726545db..a7d2f4c0cf 100644 --- a/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP 0.2 nozzle.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "2", "2" diff --git a/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP.json b/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP.json index 41a600ba06..c783391392 100644 --- a/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/PolyLite ASA @BBL H2DP.json @@ -8,6 +8,10 @@ "chamber_temperatures": [ "60" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "13", "13" diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP 0.2 nozzle.json index bc86d84be1..ff8daffd6e 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP 0.2 nozzle.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG60_15", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "1", "1" diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json index 2ff948fac7..24fcafab4f 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json @@ -5,6 +5,10 @@ "from": "system", "setting_id": "GFSG60_14", "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "11.5", "11.5" @@ -16,9 +20,6 @@ "include": [ "fdm_filament_template_direct_dual" ], - "nozzle_temperature_range_high": [ - "270" - ], "nozzle_temperature": [ "255", "255" @@ -27,6 +28,9 @@ "255", "255" ], + "nozzle_temperature_range_high": [ + "270" + ], "slow_down_min_speed": [ "20", "20" diff --git a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP 0.2 nozzle.json index 262251224a..40cc6c44ff 100644 --- a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "1.6", "1.6" diff --git a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP.json b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP.json index 649ec52308..221400c275 100644 --- a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_max_volumetric_speed": [ "15", "15" diff --git a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP 0.2 nozzle.json index c53ec8858a..a6b996fa3d 100644 --- a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP.json b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP.json index d57b84a26b..f9923d5ca0 100644 --- a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP 0.2 nozzle.json index 3e55407ac4..e9c9c8caa5 100644 --- a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP 0.2 nozzle.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP.json b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP.json index 8d5821809f..0b1ef208ab 100644 --- a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP.json +++ b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2DP.json @@ -11,6 +11,10 @@ "eng_plate_temp_initial_layer": [ "55" ], + "filament_cooling_before_tower": [ + "10", + "10" + ], "filament_flow_ratio": [ "0.98", "0.98" diff --git a/resources/profiles/BBL/filament/fdm_filament_common.json b/resources/profiles/BBL/filament/fdm_filament_common.json index 2dd096db9d..7330434519 100644 --- a/resources/profiles/BBL/filament/fdm_filament_common.json +++ b/resources/profiles/BBL/filament/fdm_filament_common.json @@ -72,12 +72,12 @@ "filament_extruder_compatibility": [ "0" ], - "filament_change_length": [ - "10" - ], "filament_cooling_before_tower": [ "0" ], + "filament_preheat_temperature_delta":[ + "0" + ], "filament_tower_interface_pre_extrusion_dist": [ "10" ], @@ -180,9 +180,6 @@ "filament_printable": [ "3" ], - "filament_ramming_travel_time": [ - "0" - ], "filament_ramming_travel_time_nc": [ "0" ], @@ -195,9 +192,6 @@ "filament_retract_before_wipe": [ "nil" ], - "filament_retract_length_nc": [ - "14" - ], "filament_retract_restart_extra": [ "nil" ], @@ -219,15 +213,6 @@ "filament_retraction_speed": [ "nil" ], - "filament_scarf_gap": [ - "0%" - ], - "filament_scarf_height": [ - "10%" - ], - "filament_scarf_length": [ - "10" - ], "filament_scarf_seam_type": [ "none" ], @@ -240,27 +225,9 @@ "filament_soluble": [ "0" ], - "filament_tower_interface_pre_extrusion_dist": [ - "10" - ], - "filament_tower_interface_pre_extrusion_length": [ - "0" - ], - "filament_tower_interface_print_temp": [ - "-1" - ], - "filament_tower_interface_purge_volume": [ - "20" - ], - "filament_tower_ironing_area": [ - "4" - ], "filament_type": [ "PLA" ], - "filament_velocity_adaptation_factor": [ - "1" - ], "filament_vendor": [ "Generic" ], @@ -282,12 +249,6 @@ "additional_fan_full_speed_layer": [ "0" ], - "filament_extruder_variant": [ - "Direct Drive Standard" - ], - "filament_scarf_seam_type": [ - "none" - ], "filament_scarf_height": [ "10%" ], @@ -297,21 +258,9 @@ "filament_scarf_length": [ "10" ], - "filament_shrink": [ - "100%" - ], - "filament_pre_cooling_temperature": [ - "0" - ], - "filament_pre_cooling_temperature_nc": [ - "0" - ], "filament_ramming_travel_time": [ "0" ], - "filament_ramming_travel_time_nc": [ - "0" - ], "filament_retract_length_nc": [ "14" ], @@ -342,9 +291,6 @@ "filament_velocity_adaptation_factor": [ "1" ], - "filament_adaptive_volumetric_speed": [ - "0" - ], "hot_plate_temp": [ "60" ], @@ -366,12 +312,6 @@ "hole_limit_min": [ "0.088" ], - "hot_plate_temp": [ - "60" - ], - "hot_plate_temp_initial_layer": [ - "60" - ], "impact_strength_z": [ "10" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_template_direct_bowden.json b/resources/profiles/BBL/filament/fdm_filament_template_direct_bowden.json index 7f3b1cd6f9..152b0ade59 100644 --- a/resources/profiles/BBL/filament/fdm_filament_template_direct_bowden.json +++ b/resources/profiles/BBL/filament/fdm_filament_template_direct_bowden.json @@ -15,6 +15,12 @@ "0", "0" ], + "filament_preheat_temperature_delta":[ + "10", + "10", + "10", + "10" + ], "filament_deretraction_speed": [ "nil", "nil", diff --git a/resources/profiles/BBL/filament/fdm_filament_template_direct_dual.json b/resources/profiles/BBL/filament/fdm_filament_template_direct_dual.json index df85e6c29e..ab15ee0842 100644 --- a/resources/profiles/BBL/filament/fdm_filament_template_direct_dual.json +++ b/resources/profiles/BBL/filament/fdm_filament_template_direct_dual.json @@ -11,6 +11,10 @@ "0", "0" ], + "filament_preheat_temperature_delta":[ + "10", + "10" + ], "filament_deretraction_speed": [ "nil", "nil" diff --git a/resources/profiles/BBL/machine/Bambu Lab A1 mini.json b/resources/profiles/BBL/machine/Bambu Lab A1 mini.json index 63936e999a..f49601ed6a 100644 --- a/resources/profiles/BBL/machine/Bambu Lab A1 mini.json +++ b/resources/profiles/BBL/machine/Bambu Lab A1 mini.json @@ -8,6 +8,7 @@ "default_bed_type": "Textured PEI Plate", "image_bed_type": "mini", "not_support_bed_type": "Cool Plate;Engineering Plate", + "support_side_panel_fan": "false", "family": "BBL-3DP", "machine_tech": "FFF", "model_id": "N1", diff --git a/resources/profiles/BBL/machine/Bambu Lab A1.json b/resources/profiles/BBL/machine/Bambu Lab A1.json index d818efa48b..9fd1a4c37f 100644 --- a/resources/profiles/BBL/machine/Bambu Lab A1.json +++ b/resources/profiles/BBL/machine/Bambu Lab A1.json @@ -6,6 +6,7 @@ "bed_model": "bbl-3dp-X1.stl", "bed_texture": "bbl-3dp-logo.svg", "default_bed_type": "Textured PEI Plate", + "support_side_panel_fan": "false", "family": "BBL-3DP", "machine_tech": "FFF", "model_id": "N2S", diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template change_filament_gcode.json b/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template change_filament_gcode.json index 22bfe72f52..49f287b5d6 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template change_filament_gcode.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template change_filament_gcode.json @@ -1,5 +1,5 @@ { "name": "Bambu Lab H2C 0.4 nozzle template change_filament_gcode", "instantiation": "false", - "change_filament_gcode": ";======== H2C filament_change ========\n;===== 20260409 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 O{toolchange_count + 1}\nM620 S[next_extruder]A H[next_hotend]\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if wipe_tower_center_pos_valid}\n M620.14 X[wipe_tower_center_pos_x] Y[wipe_tower_center_pos_y]\n{else}\n M620.14 X95.5 Y336\n{endif}\n\n{if ((filament_type[current_extruder] == \"PLA\") || (filament_type[current_extruder] == \"PLA-CF\") || (filament_type[current_extruder] == \"PETG\")) && (nozzle_diameter[current_extruder] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 I[current_extruder] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] B[current_hotend] E0\n{endif}\n\n\nM620.15 P[filament_pre_cooling_temperature_nc[next_extruder]]\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}\nM620.11 O1 T[filament_retract_length_nc]\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] B[current_hotend] R0\n{endif}\n\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}\n\nM628 S1\n{if filament_type[current_extruder] == \"TPU\"}\nM620.11 S0 L0 I[current_extruder] B[current_hotend] E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_extruder] == \"PA\") || (filament_type[current_extruder] == \"PA-GF\")}\nM620.11 S1 L0 I[current_extruder] B[current_hotend] R4 D2 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_extruder] B[current_hotend] R10 D8 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if (filament_type[current_extruder] == \"TPU\" || filament_type[next_extruder] == \"TPU\") && (old_extruder_variant != \"Direct Drive TPU High Flow\")}\n;M620.11 H2 C331 TODO:add区分左右顶料\n{else}\n;M620.11 H0\n{endif}\n\n{if filament_type[next_extruder] == \"TPU\" }\n;ct:{filament_type[current_extruder]} nt:{filament_type[next_extruder]} \n;debug log pe:{previous_extruder} ce:{current_extruder} ne:{next_extruder} oev: {old_extruder_variant} nev:{new_extruder_variant}\n;debug fm-curr:{filament_map[current_extruder]} fm-next:{filament_map[next_extruder]}\n;sw from R2L&TPU kit, travel run a distance for sketch TPU\nG1 X30 Y30 F5000\nM400\nG1 X300 Y30 F5000\nM400\n{endif}\n\nT[next_extruder] H[next_hotend]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if (filament_type[next_extruder] == \"PA\") || (filament_type[next_extruder] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; compensate for heating and cooling\n{if flush_length > 0}\n{if flush_temperatures[next_extruder] > new_filament_temp}\nSYNC T{(flush_temperatures[next_extruder]-(new_filament_temp - filament_cooling_before_tower[next_extruder]))/hotend_cooling_rate[filament_map[next_extruder]-1]}\nSYNC T{(flush_temperatures[next_extruder]-(new_filament_temp - filament_cooling_before_tower[next_extruder]))/hotend_heating_rate[filament_map[next_extruder]-1]}\n{else}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_extruder] -flush_temperatures[next_extruder])/hotend_cooling_rate[filament_map[next_extruder]-1]}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_extruder] -flush_temperatures[next_extruder])/hotend_heating_rate[filament_map[next_extruder]-1]}\n{endif}\n{endif}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\n\nM620.10 R{new_extruder_retracted_length}\n\n{if (print_sequence == \"by object\" && !has_wipe_tower)}\nM628 S0 F1 L10.0\n; VFLUSH_START\n;VG1 E10 F[new_filament_e_feedrate]\n; VFLUSH_END\n{else}\nM628 S0\n{endif}\n;VM109 S[new_filament_temp]\n\nM629\nM400\n\n;prime_tower_interface\n{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}\nG150.1\nM620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0\n{endif}\n;prime_tower_interface\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{new_extruder_retracted_length}\n\n\nM400\n{if wipe_avoid_perimeter}\nG387 Y320 J1 F10000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG387 Y295 J1 F30000\nG387 Y265 J1 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM622.1 S0 ;for prev version, default skip\nM1002 judge_flag powerloss_resume_flag\nM622 J1\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{new_extruder_retracted_length}\nM400\n{if wipe_avoid_perimeter}\nG387 Y320 J1 F10000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG387 Y295 J1 F30000\nG387 Y265 J1 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\nM1002 set_flag powerloss_resume_flag=0\nM623\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] H[next_hotend] W1 ;enable ams air printing detect\nM620 O{toolchange_count + 1}\nM1002 gcode_claim_action : 0" + "change_filament_gcode": ";======== H2C filament_change ========\n;===== 20260413 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_extruder]A H[next_hotend]\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if wipe_tower_center_pos_valid}\n M620.14 X[wipe_tower_center_pos_x] Y[wipe_tower_center_pos_y]\n{else}\n M620.14 X95.5 Y336\n{endif}\n\n{if ((filament_type[current_extruder] == \"PLA\") || (filament_type[current_extruder] == \"PLA-CF\") || (filament_type[current_extruder] == \"PETG\")) && (nozzle_diameter[current_extruder] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 I[current_extruder] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] B[current_hotend] E0\n{endif}\n\n\nM620.15 P[filament_pre_cooling_temperature_nc[next_extruder]]\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}\nM620.11 O1 T[filament_retract_length_nc]\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] B[current_hotend] R0\n{endif}\n\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}\n\nM628 S1\n{if filament_type[current_extruder] == \"TPU\"}\nM620.11 S0 L0 I[current_extruder] B[current_hotend] E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_extruder] == \"PA\") || (filament_type[current_extruder] == \"PA-GF\")}\nM620.11 S1 L0 I[current_extruder] B[current_hotend] R4 D2 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_extruder] B[current_hotend] R10 D8 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if (filament_type[current_extruder] == \"TPU\") && (filament_map[current_extruder] == 2) && (old_extruder_variant != \"Direct Drive TPU High Flow\")}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\n{if (old_extruder_variant == \"Direct Drive TPU High Flow\") && (filament_map[current_extruder] == 2) && (filament_map[next_extruder] == 1)}\n;debug log pe:{previous_extruder} ce:{current_extruder} ne:{next_extruder} oev: {old_extruder_variant} nev:{new_extruder_variant}\n;debug fm-curr:{filament_map[current_extruder]} fm-next:{filament_map[next_extruder]}\n;sw from R2L&TPU kit, travel run a distance for sketch TPU\nG1 X30 Y30 F5000\nM400\nG1 X300 Y30 F5000\nM400\n{endif}\n\nT[next_extruder] H[next_hotend]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if (filament_type[next_extruder] == \"PA\") || (filament_type[next_extruder] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; compensate for heating and cooling\n{if flush_length > 0}\n{if flush_temperatures[next_extruder] > new_filament_temp}\nSYNC T{(flush_temperatures[next_extruder]-(new_filament_temp - filament_cooling_before_tower[next_extruder]))/hotend_cooling_rate[filament_map[next_extruder]-1]}\nSYNC T{(flush_temperatures[next_extruder]-(new_filament_temp - filament_cooling_before_tower[next_extruder]))/hotend_heating_rate[filament_map[next_extruder]-1]}\n{else}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_extruder] -flush_temperatures[next_extruder])/hotend_cooling_rate[filament_map[next_extruder]-1]}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_extruder] -flush_temperatures[next_extruder])/hotend_heating_rate[filament_map[next_extruder]-1]}\n{endif}\n{endif}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\n\nM620.10 R{new_extruder_retracted_length}\n\n{if (print_sequence == \"by object\" && !has_wipe_tower)}\nM628 S0 F1 L10.0\n; VFLUSH_START\n;VG1 E10 F[new_filament_e_feedrate]\n; VFLUSH_END\n{else}\nM628 S0\n{endif}\n;VM109 S[new_filament_temp]\n\nM629\nM400\n\n;prime_tower_interface\n{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}\nG150.1\nM620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0\n{endif}\n;prime_tower_interface\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{new_extruder_retracted_length}\n\n\nM400\n{if wipe_avoid_perimeter}\nG387 Y320 J1 F10000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG387 Y295 J1 F30000\nG387 Y265 J1 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM622.1 S0 ;for prev version, default skip\nM1002 judge_flag powerloss_resume_flag\nM622 J1\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{new_extruder_retracted_length}\nM400\n{if wipe_avoid_perimeter}\nG387 Y320 J1 F10000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG387 Y295 J1 F30000\nG387 Y265 J1 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\nM1002 set_flag powerloss_resume_flag=0\nM623\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] H[next_hotend] W1 ;enable ams air printing detect\nM620 O{toolchange_count + 1}\nM1002 gcode_claim_action : 0" } \ No newline at end of file diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template machine_start_gcode.json b/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template machine_start_gcode.json index 2042ebdc0f..28dd0077a4 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template machine_start_gcode.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle template machine_start_gcode.json @@ -1,5 +1,5 @@ { "name": "Bambu Lab H2C 0.4 nozzle template machine_start_gcode", "instantiation": "false", - "machine_start_gcode": ";===== machine: H2C =========================\n;===== date: 20260409 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\nM960 S10 P1 ; ext fan led\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\nG28.140 D0; reset pre-extrude z pos\n;===== reset machine status =================\n\nM620 M ;enable remap\nM620 N ;enable hotend remap\nM620 T0 ;print tmpr\nM620 T1 ;sn -> pos\nM620 T2 ;filament_id\n\n;===== start to heat heatbed & hotend==========\n\n M104 O-80 A\n M140 D[bed_temperature_initial_layer_single]\n\n;===== start to heat heatbead & hotend==========\n\n;===== avoid end stop =================\nG91\nG380 S2 Z42 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{if(cooling_filter_enabled)}\nM145.2 P0 F0\n{else}\nM145.2 P0 F1\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nM640 S\nM640.1 R\nM641\nG28 X T300\nT1000\n\nG150.3\nM972 S24 P0 T2000 ; live-view camera foolproof\nM972 S46 P0 T5000 ; vortek anti-collision\nM640.1 S\nM640.4\n{if (first_non_support_filaments[0] != -1)}\nM640 S\nM640.8 T A{first_non_support_filaments[0]} H{first_non_support_hotend[0]}\nM640.7 L\nM641\n{endif}\n\n\n{if wipe_tower_center_pos_valid}\n M620.14 X[wipe_tower_center_pos_x] Y[wipe_tower_center_pos_y]\n{else}\n M620.14 X95.5 Y336\n{endif}\n\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\n\nM1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\nM104 S0\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM972 S41 P0 T5000 ; trash can anti-collision\n\nM1009 Q1 L1\nG91\nG380 S2 Z30 F1200 ; lower heatbed to move toolhead\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n\n;===== first homing end =====\n\n;===== detection start =====\n \nM1002 judge_flag build_plate_detect_flag\nM104 S0\nM622 S1\n ;M1002 gcode_claim_action : 11 ; Indentifying build plate type\n M972 S19 P0 C0 ; heatbed presence detection\n M972 S31 P0 T5000 ; toolhead camera dirty detection\n ;M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 T5000 ; heatbed plate offset detection\nM623\n\nM1002 gcode_claim_action : 72 ; Hotend Type Detection\nT1001\nM972 S14 P0 T5000 ; nozzle type detection\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} T{filament_map[initial_no_support_extruder] % 2} ; rise temp in advance\n\nG151 P{filament_map[initial_no_support_extruder] % 2} M ; plug the heat nozzle\n\n{if max_print_z >= 145}\nM1002 gcode_claim_action : 75 ; Heatbed underside foreign object detection\nG3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n{endif}\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n\nM620.11 P1 I[initial_no_support_extruder] B[initial_no_support_hotend] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_extruder] B[initial_no_support_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_extruder] B[initial_no_support_hotend] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_extruder] == \"PA\") || (filament_type[initial_no_support_extruder] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] R4 D2 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] R10 D8 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_extruder]A H[initial_no_support_hotend] ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder] H[initial_no_support_hotend]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG91\nG1 Y-16 F60000\nG90\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\n\nM400\n;M73 P99\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J2\n M1002 gcode_claim_action : 54\n M190 D[bed_temperature_initial_layer_single]\n \n M1002 gcode_claim_action : 39\n M620 D[initial_no_support_hotend]\n G383.3 U140 L{initial_no_support_extruder}\nM623\n\nM622 J1\n M1002 gcode_claim_action : 54\n M190 D[bed_temperature_initial_layer_single]\n\n M1002 gcode_claim_action : 39\n M620 D[initial_no_support_hotend]\n G383 O2 U140 L{initial_no_support_extruder}\nM623\n\n;===== xy ofst cali end =====\n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n G150.3\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_extruder]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\nM622 J0\n G91\n G1 Z5 F1200\n G90\n M1012.7\n G383.7 U140 J0\nM623\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z10 F1200\n{if (first_non_support_filaments[0] != -1)}\nM640 S\nM83\nG1 E-3 F1500\nM640.7 U\nM640.7 L\nM640.2 R1\nM641\n{endif}\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R \n M400\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\nM623\n\nM622 J0\n G28 R\nM623\n\n;===== bed leveling end ================================\n\nG39.1 ; cali nozzle wrapped detection pos\n\nG90\nG1 Z5 F1200\nG1 X270 Y-0.5 F60000\nG28.140 S0 ; cali pre-extrude z pos\n\n;============switch again==================\nM620 O1\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM620 S[initial_no_support_extruder]A H[initial_no_support_hotend]\nM400\nT[initial_no_support_extruder] H[initial_no_support_hotend]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_extruder]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X165 Y160 F20000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n\n M975 S1\n;===== mech mode sweep end =====\n\n;===== wait temperature reaching the reference value =======\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n ;==== set ext toodhead cooling fan ==== \n {if (min_vitrification_temperature <= 50)}\n M106 P9 S255\n {endif}\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n {if nozzle_diameter[initial_no_support_extruder] == 0.2}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n {else}\n {if nozzle_diameter[initial_no_support_extruder] == 0.2}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {endif}\n {endif}\nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14 R0\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n \n ========== record data ==========\n M1026\n M1012.8\n M1012.9\n G29.9\n ========== record data ==========\n \n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n{if nozzle_diameter[initial_no_support_extruder] == 0.8}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n{endif}\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n{endif}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 X290 E10 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] H[initial_no_support_hotend] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\nM1002 gcode_claim_action : 0\nM400\nM400 P50\nM500 D1\n" + "machine_start_gcode": ";===== machine: H2C =========================\n;===== date: 20260422 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\nM960 S10 P1 ; ext fan led\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\nG28.140 D0; reset pre-extrude z pos\n;===== reset machine status =================\n\nM620 M ;enable remap\nM620 N ;enable hotend remap\nM620 T0 ;print tmpr\nM620 T1 ;sn -> pos\nM620 T2 ;filament_id\n\n;===== start to heat heatbed & hotend==========\n\n M104 O-80 A\n M140 D[bed_temperature_initial_layer_single]\n\n;===== start to heat heatbead & hotend==========\n\n;===== avoid end stop =================\nG91\nG380 S2 Z42 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{if(cooling_filter_enabled)}\nM145.2 P0 F0\n{else}\nM145.2 P0 F1\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nM640 S\nM640.1 R\nM641\nG28 X T300\nT1000\n\nG150.3\nM972 S24 P0 T2000 ; live-view camera foolproof\nM972 S46 P0 T5000 ; vortek anti-collision\nM640.1 S\nM640.4\n{if (first_non_support_filaments[0] != -1)}\nM640 S\nM640.8 T A{first_non_support_filaments[0]} H{first_non_support_hotend[0]}\nM640.7 L\nM641\n{endif}\n\n\n{if wipe_tower_center_pos_valid}\n M620.14 X[wipe_tower_center_pos_x] Y[wipe_tower_center_pos_y]\n{else}\n M620.14 X95.5 Y336\n{endif}\n\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\n\nM1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\nM104 S0\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM972 S41 P0 T5000 ; trash can anti-collision\n\nM1009 Q1 L1\nG91\nG380 S2 Z30 F1200 ; lower heatbed to move toolhead\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n\n;===== first homing end =====\n\n;===== detection start =====\n \nM1002 judge_flag build_plate_detect_flag\nM104 S0\nM622 S1\n ;M1002 gcode_claim_action : 11 ; Indentifying build plate type\n M972 S19 P0 C0 ; heatbed presence detection\n M972 S31 P0 T5000 ; toolhead camera dirty detection\n ;M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 T5000 ; heatbed plate offset detection\nM623\n\nM1002 gcode_claim_action : 72 ; Hotend Type Detection\nT1001\nM972 S14 P0 T5000 ; nozzle type detection\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} T{filament_map[initial_no_support_extruder] % 2} ; rise temp in advance\n\nG151 P{filament_map[initial_no_support_extruder] % 2} M ; plug the heat nozzle\n\n{if max_print_z >= 145}\nM1002 gcode_claim_action : 75 ; Heatbed underside foreign object detection\nG3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n{endif}\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n\nM620.11 P1 I[initial_no_support_extruder] B[initial_no_support_hotend] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_extruder] B[initial_no_support_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_extruder] B[initial_no_support_hotend] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_extruder] == \"PA\") || (filament_type[initial_no_support_extruder] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] R4 D2 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] R10 D8 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_extruder]A H[initial_no_support_hotend] ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder] H[initial_no_support_hotend]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG91\nG1 Y-16 F60000\nG90\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\n\nM400\n;M73 P99\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J2\n M1002 gcode_claim_action : 54\n M190 D[bed_temperature_initial_layer_single]\n \n M1002 gcode_claim_action : 39\n M620 D[initial_no_support_hotend]\n G383.3 U140 L{initial_no_support_extruder}\nM623\n\nM622 J1\n M1002 gcode_claim_action : 54\n M190 D[bed_temperature_initial_layer_single]\n\n M1002 gcode_claim_action : 39\n M620 D[initial_no_support_hotend]\n G383 O2 U140 L{initial_no_support_extruder}\nM623\n\n;===== xy ofst cali end =====\n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n G150.3\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_extruder]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\nM622 J0\n G91\n G1 Z5 F1200\n G90\n M1012.7\n G383.7 U140 J0\nM623\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z10 F1200\n{if (first_non_support_filaments[0] != -1)}\nM640 S\nM83\nG1 E-3 F1500\nM640.7 U\nM640.7 L\nM640.2 R1\nM641\n{endif}\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R \n M400\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\nM623\n\nM622 J0\n G28 R\nM623\n\n;===== bed leveling end ================================\n\nG39.1 ; cali nozzle wrapped detection pos\n\nG90\nG1 Z5 F1200\nG1 X270 Y-0.5 F60000\nG28.140 S0 ; cali pre-extrude z pos\n\n;============switch again==================\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM620 S[initial_no_support_extruder]A H[initial_no_support_hotend]\nM400\nT[initial_no_support_extruder] H[initial_no_support_hotend]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_extruder]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X165 Y160 F20000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n\n M975 S1\n;===== mech mode sweep end =====\n\n;===== wait temperature reaching the reference value =======\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n ;==== set ext toodhead cooling fan ==== \n {if (min_vitrification_temperature <= 50)}\n M106 P9 S255\n {endif}\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n {if nozzle_diameter[initial_no_support_extruder] == 0.2}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n {else}\n {if nozzle_diameter[initial_no_support_extruder] == 0.2}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {endif}\n {endif}\nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14 R0\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n \n ========== record data ==========\n M1026\n M1012.8\n M1012.9\n G29.9\n ========== record data ==========\n \n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n{if nozzle_diameter[initial_no_support_extruder] == 0.8}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n{endif}\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n{endif}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 X290 E10 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] H[initial_no_support_hotend] W1 ;enable ams air printing detect\nM620 O1\n\nM211 Z1\nG29.99\nM1002 gcode_claim_action : 0\nM400\n" } \ No newline at end of file diff --git a/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle template machine_start_gcode.json b/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle template machine_start_gcode.json index 309e0df929..0a0e8f3233 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle template machine_start_gcode.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle template machine_start_gcode.json @@ -1,5 +1,5 @@ { "name": "Bambu Lab H2S 0.4 nozzle template machine_start_gcode", "instantiation": "false", - "machine_start_gcode": ";===== machine: H2S =========================\n;===== date: 2026/02/04 =====================\n\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\nG28.140 D0; reset pre-extrude z pos\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z32 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{if(cooling_filter_enabled)}\nM145.2 P0 F0\n{else}\nM145.2 P0 F1\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.3 F18000\nT1000 O0 ;Preventing 3D Print Misalignment After Laser Operations\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\nM1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\nM972 S41 P0 T5000; trash can anti-collision\n\nM1009 Q1 L1\nG91\nG380 S2 Z30 F1200 ; lower heatbed to move toolhead\nG90\nG1 X170 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\nM104 S0 T0 ; stop hotend heating before detection\nM562 P1 E0 B1\nM18 E\nM400 P200\nM1028 S1\n\nM1002 judge_flag build_plate_detect_flag\nM622 S1\n ;M1002 gcode_claim_action : 11 ; Indentifying build plate type\n M972 S19 P0 C0 ; heatbed detection\n \n M972 S31 P0 T5000; Toolhead camera detection\n \n ;M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 T5000; Plate offset detection\nM623\n\nM1028 S0\nM562 P1 E1 B1\nM17 D\n\n{if max_print_z >= 145}\nM1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\nG150.3\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise temp in advance\nG3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n{endif}\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n\nM620.11 P0 I[initial_no_support_extruder] E0\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_extruder]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X275 Y300 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\nG390.1 Z; cali nozzle wrapped detection pos\n\nG90\nG1 Z5 F1200\nG1 X270 Y-0.5 F60000\nG28.140 S0 ; cali pre-extrude z pos\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\nG29.9\n\nM1002 gcode_claim_action : 0\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14 R0\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\nM400 P50\nM500 D1\n" + "machine_start_gcode": ";===== machine: H2S =========================\n;===== date: 2026/04/21 =====================\n\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\nG28.140 D0; reset pre-extrude z pos\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z32 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{if(cooling_filter_enabled)}\nM145.2 P0 F0\n{else}\nM145.2 P0 F1\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.3 F18000\nT1000 O0 ;Preventing 3D Print Misalignment After Laser Operations\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\nM1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\nM972 S41 P0 T5000; trash can anti-collision\n\nM1009 Q1 L1\nG91\nG380 S2 Z30 F1200 ; lower heatbed to move toolhead\nG90\nG1 X170 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\nM104 S0 T0 ; stop hotend heating before detection\nM562 P1 E0 B1\nM18 E\nM400 P200\nM1028 S1\n\nM1002 judge_flag build_plate_detect_flag\nM622 S1\n ;M1002 gcode_claim_action : 11 ; Indentifying build plate type\n M972 S19 P0 C0 ; heatbed detection\n \n M972 S31 P0 T5000; Toolhead camera detection\n \n ;M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 T5000; Plate offset detection\nM623\n\nM1028 S0\nM562 P1 E1 B1\nM17 D\n\n{if max_print_z >= 145}\nM1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\nG150.3\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise temp in advance\nG3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n{endif}\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n\nM620.11 P0 I[initial_no_support_extruder] E0\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_extruder]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X275 Y300 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\nG390.1 Z; cali nozzle wrapped detection pos\n\nG90\nG1 Z5 F1200\nG1 X270 Y-0.5 F60000\nG28.140 S0 ; cali pre-extrude z pos\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\nG29.9\n\nM1002 gcode_claim_action : 0\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14 R0\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n" } \ No newline at end of file diff --git a/resources/profiles/BBL/machine/Bambu Lab P1P.json b/resources/profiles/BBL/machine/Bambu Lab P1P.json index ec860165ee..b2ead53812 100644 --- a/resources/profiles/BBL/machine/Bambu Lab P1P.json +++ b/resources/profiles/BBL/machine/Bambu Lab P1P.json @@ -6,6 +6,7 @@ "bed_model": "bbl-3dp-X1.stl", "bed_texture": "bbl-3dp-logo.svg", "default_bed_type": "Textured PEI Plate", + "support_side_panel_fan": "false", "family": "BBL-3DP", "machine_tech": "FFF", "model_id": "C11", diff --git a/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle template machine_start_gcode.json b/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle template machine_start_gcode.json index 2f03bdac6f..4c25cb1537 100644 --- a/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle template machine_start_gcode.json +++ b/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle template machine_start_gcode.json @@ -1,5 +1,5 @@ { "name": "Bambu Lab P2S 0.4 nozzle template machine_start_gcode", "instantiation": "false", - "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== P2S start gcode==========\n;===== 2026/02/26 =====\n \n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M620 M ;enable remap\n G389\n\n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n G90\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n M983.4 S0\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n;==== if Chamber Cooling is necessary ====\n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S255 ; turn on filter fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\n{else}\n{if (min_vitrification_temperature <= 50)}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n{else}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S127 ; turn on 50% filter fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PLA/TPU exhaust chamber autocooling\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M104 S140 A \n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M972 S26 P0 C0\n M972 S42 P0 T5000\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G90\n G1 X128 Y128 F30000\n G28 Z P0 T400\n M400\n;===== first homign end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n M972 S19 P0 T5000 ;plate type detection\n \n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise temp in advance\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] E0\n M620.11 K0 I[initial_no_support_extruder] R0\n \n M620 S[initial_no_support_extruder]A ; switch material if AMS exist\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n M1030 S1800 \n SYNC R0 T1800\n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n \n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n\n G91\n G1 Y-16 F12000 ; move away from the trash bin\n G90\n M400\n\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n \n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n;===== wipe left nozzle end =====\n\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M970.2 Q1 K1 W74 Z0.01\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M970.2 Q0 K1 W74 Z0.01\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M623\n\n M622 J0\n G28\n M623\n G29.2 S1\n G28\n;===== bed leveling end ================================\n\n M985.1 U0 E2\n M985.1 U1 E2\n\n M104 S[nozzle_temperature_initial_layer] A\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if bed_temperature_initial_layer_single > 89}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.0}\n {endif}\n {else}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.03}\n {endif}\n {endif}\n\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n ;G130 O0 X100 Y-0.4 Z0.8 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E20 D5\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\n G90\n M83\n G1 Z0.5\n M400\n;===== noozle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\") || \n(filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu, pla and petg clog detect\n{else}\nM1015.3 S0;disable clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM1010 Q0 B0.023 S0.01\nM1010 Q1 B0.005 S0.01\nM1010.1 S1\nM400 P50\nM500 D1\n" + "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== P2S start gcode==========\n;===== 2026/04/21 =====\n \n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M620 M ;enable remap\n G389\n\n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n G90\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n M983.4 S0\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n;==== if Chamber Cooling is necessary ====\n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S255 ; turn on filter fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\n{else}\n{if (min_vitrification_temperature <= 50)}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n{else}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S127 ; turn on 50% filter fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PLA/TPU exhaust chamber autocooling\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M104 S140 A \n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M972 S26 P0 C0\n M972 S42 P0 T5000\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G90\n G1 X128 Y128 F30000\n G28 Z P0 T400\n M400\n;===== first homign end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n M972 S19 P0 T5000 ;plate type detection\n \n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise temp in advance\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] E0\n M620.11 K0 I[initial_no_support_extruder] R0\n \n M620 S[initial_no_support_extruder]A ; switch material if AMS exist\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n M1030 S1800 \n SYNC R0 T1800\n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n \n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n\n G91\n G1 Y-16 F12000 ; move away from the trash bin\n G90\n M400\n\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n \n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n;===== wipe left nozzle end =====\n\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M970.2 Q1 K1 W74 Z0.01\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M970.2 Q0 K1 W74 Z0.01\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M623\n\n M622 J0\n G28\n M623\n G29.2 S1\n G28\n;===== bed leveling end ================================\n\n M985.1 U0 E2\n M985.1 U1 E2\n\n M104 S[nozzle_temperature_initial_layer] A\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if bed_temperature_initial_layer_single > 89}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.0}\n {endif}\n {else}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.03}\n {endif}\n {endif}\n\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n ;G130 O0 X100 Y-0.4 Z0.8 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E20 D5\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\n G90\n M83\n G1 Z1\n M400\n;===== noozle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\") || \n(filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu, pla and petg clog detect\n{else}\nM1015.3 S0;disable clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM1010 Q0 B0.023 S0.01\nM1010 Q1 B0.005 S0.01\nM1010.1 S1\n" } \ No newline at end of file diff --git a/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle template machine_start_gcode.json b/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle template machine_start_gcode.json index 5b31059f25..0a9d796d2c 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle template machine_start_gcode.json +++ b/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle template machine_start_gcode.json @@ -1,5 +1,5 @@ { "name": "Bambu Lab X2D 0.4 nozzle template machine_start_gcode", "instantiation": "false", - "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== X2D start gcode==========\n;===== 2026/03/26 =====\n\n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n ;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M1012.1 T1100\n M620 M ;enable remap\n M622.1 S0\n G383.4\n \n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S0 ; turn off auxiliary fan\nM106 P10 S255 ; turn on filter fan\n{else}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P10 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\n;M140 S0 ; stop heatbed from heating\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on auxiliary fan\nM106 P10 S102 ; turn on chamber fan\nM142 P6 R30 S40 U0.6 V0.8 ; set PLA/TPU/PETG exhaust chamber autocooling\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]} \n \n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n;===== set chamber temperature ==========\n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300 R\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n M972 S26 P0 C0\n G90\n M83\n G1 Y128 F30000\n G1 X128\n G28 Z P0 T400\n M400\n;===== first homign end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n\n M104 S0 T0\n M104 S0 T1\n M562 P1 E0 B1\n M562 P2 E0 B1\n M18 E\n M400 P200\n M1028 S1\n M972 S19 P0 ;heatbed detection\n M972 S31 P0 ;toolhead camera dirt detection\n M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 ;print plate deviation detection\n M1028 S0\n M562 P1 E1 B1\n M562 P2 E1 B1\n M17 D\n\n ;M400\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} T{filament_map[initial_no_support_extruder] % 2} ; rise temp in advance\n G151 P{filament_map[initial_no_support_extruder] % 2} M ; plug the heat nozzle\n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-40} A ; rise temp in advance\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] E0\n M620.11 K0 I[initial_no_support_extruder] B[initial_no_support_hotend] R0\n\n M620 S[initial_no_support_extruder]A H[initial_no_support_hotend] B ; switch material if AMS exist\n M620.22 I[initial_no_support_extruder] P1 ; enable remote extruder runout auto purge.\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A B\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n G150.3\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n {if overall_chamber_temperature < 40}\n M1030 S1200\n SYNC R0 T1200\n {else}\n M1030 S600\n SYNC R0 T600\n {endif} \n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n\n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n\n G91\n G1 Y-16 F12000 ; move away from the trash bin\n G90\n M400\n\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n;===== wipe left nozzle end =====\n\n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n M106 S0 ; turn off fan , too noisy\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n\n{if (overall_chamber_temperature >= 40)}\nM1002 gcode_claim_action : 49\nM191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\n;===== z ofst cali start =====\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n G383 O0 M1 T140\n M400\n;===== z ofst cali end =====\nG90\nM83\nG0 Y200 F18000\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n\n M622 J0\n G28 R\n M623\n G29.2 S1\n;===== bed leveling end ================================\n\n; cali eddy z pos\n;G383.13 T1 C1\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\nM104 S[nozzle_temperature_initial_layer] A\nG150.3\n;===== xy ofst cali start =====\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n M620 D[initial_no_support_hotend]\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n M620 D[initial_no_support_hotend]\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\n M104 S[nozzle_temperature_initial_layer] A\n\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M140 S[bed_temperature_initial_layer_single] \n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n M983.4 S0 ; turn off deformation compensation \n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A H[initial_no_support_hotend] B\n M620.22 I[initial_no_support_extruder] P1 ; enable remote extruder runout auto purge.\n M400\n T[initial_no_support_extruder] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A B\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.002} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.022}\n {endif}\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n ;G130 O0 X100 Y-0.4 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E20 D5\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\nG90\n G90\n M83\n G1 Z0.5\n M400\n;===== noozle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n;M993 A1 B1 C1 ; nozzle cam detection allowed.\n\nM620.6 I[initial_no_support_extruder] H[initial_no_support_hotend] W1 ;enable ams air printing detect\n\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\nM400 P50\nM500 D1\n" + "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== X2D start gcode==========\n;===== 2026/04/21 =====\n\n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n ;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M1012.1 T1100\n M620 M ;enable remap\n M622.1 S0\n G383.4\n \n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S0 ; turn off auxiliary fan\nM106 P10 S255 ; turn on filter fan\n{else}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P10 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\n;M140 S0 ; stop heatbed from heating\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on auxiliary fan\nM106 P10 S102 ; turn on chamber fan\nM142 P6 R30 S40 U0.6 V0.8 ; set PLA/TPU/PETG exhaust chamber autocooling\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]} \n \n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n;===== set chamber temperature ==========\n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300 R\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n M972 S26 P0 C0\n G90\n M83\n G1 Y128 F30000\n G1 X128\n G28 Z P0 T400\n M400\n;===== first homign end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n\n M104 S0 T0\n M104 S0 T1\n M562 P1 E0 B1\n M562 P2 E0 B1\n M18 E\n M400 P200\n M1028 S1\n M972 S19 P0 ;heatbed detection\n M972 S31 P0 ;toolhead camera dirt detection\n M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 ;print plate deviation detection\n M1028 S0\n M562 P1 E1 B1\n M562 P2 E1 B1\n M17 D\n\n ;M400\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} T{filament_map[initial_no_support_extruder] % 2} ; rise temp in advance\n G151 P{filament_map[initial_no_support_extruder] % 2} M ; plug the heat nozzle\n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-40} A ; rise temp in advance\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] E0\n M620.11 K0 I[initial_no_support_extruder] B[initial_no_support_hotend] R0\n\n M620 S[initial_no_support_extruder]A H[initial_no_support_hotend] B ; switch material if AMS exist\n M620.22 I[initial_no_support_extruder] P1 ; enable remote extruder runout auto purge.\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A B\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n G150.3\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n {if overall_chamber_temperature < 40}\n M1030 S1200\n SYNC R0 T1200\n {else}\n M1030 S600\n SYNC R0 T600\n {endif} \n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n\n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n\n G91\n G1 Y-16 F12000 ; move away from the trash bin\n G90\n M400\n\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n;===== wipe left nozzle end =====\n\n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n M106 S0 ; turn off fan , too noisy\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n\n{if (overall_chamber_temperature >= 40)}\nM1002 gcode_claim_action : 49\nM191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\n;===== z ofst cali start =====\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n G383 O0 M1 T140\n M400\n;===== z ofst cali end =====\nG90\nM83\nG0 Y200 F18000\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n\n M622 J0\n G28 R\n M623\n G29.2 S1\n;===== bed leveling end ================================\n\n; cali eddy z pos\n;G383.13 T1 C1\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\nM104 S[nozzle_temperature_initial_layer] A\nG150.3\nM400 P50\nM500 D1\nM400 S3\n;===== xy ofst cali start =====\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n M620 D[initial_no_support_hotend]\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n M620 D[initial_no_support_hotend]\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\n M104 S[nozzle_temperature_initial_layer] A\n\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M140 S[bed_temperature_initial_layer_single] \n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n M983.4 S0 ; turn off deformation compensation \n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A H[initial_no_support_hotend] B\n M620.22 I[initial_no_support_extruder] P1 ; enable remote extruder runout auto purge.\n M400\n T[initial_no_support_extruder] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A B\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.002} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.022}\n {endif}\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n ;G130 O0 X100 Y-0.4 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E20 D5\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\nG90\n G90\n M83\n G1 Z1\n M400\n;===== noozle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n;M993 A1 B1 C1 ; nozzle cam detection allowed.\n\nM620.6 I[initial_no_support_extruder] H[initial_no_support_hotend] W1 ;enable ams air printing detect\n\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\n" } \ No newline at end of file diff --git a/resources/profiles/BBL/machine/fdm_machine_common.json b/resources/profiles/BBL/machine/fdm_machine_common.json index 5663947850..051a93e05b 100644 --- a/resources/profiles/BBL/machine/fdm_machine_common.json +++ b/resources/profiles/BBL/machine/fdm_machine_common.json @@ -8,7 +8,6 @@ ], "printer_variant": "0.4", "auxiliary_fan": "1", - "fan_direction": "undefine", "best_object_pos": "0.5x0.5", "default_filament_profile": [], "default_print_profile": "0.16mm Optimal @BBL X1C", @@ -25,7 +24,6 @@ "enable_long_retraction_when_cut": "0", "enable_pre_heating": "0", "extruder_height_gap": "0", - "group_algo_with_time": "0", "extruder_offset": [ "0x0" ], diff --git a/resources/web/device_page/README.md b/resources/web/device_page/README.md new file mode 100644 index 0000000000..ec9f37522d --- /dev/null +++ b/resources/web/device_page/README.md @@ -0,0 +1,472 @@ +# Device Page - Web UI for Device Management + +Embedded in the desktop application via wxWebView, this React app provides device management, calibration, filament management, and other device-related features. + +> **Note:** The WebView loads the **compiled output** (`dist/index.html`) — a static HTML file bundled by Vite with all JS/CSS inlined. The React/TypeScript source code in `src/` is **not** executed directly; it must be built first via `npx vite build`. During development, the Vite dev server can serve the source directly for hot-reload (see [Development Workflow](#development-workflow-hot-reload)). + +## Tech Stack + +- **React 19** + **TypeScript** +- **TanStack Router** (file-based routing, hash history) +- **Zustand** (state management, slice pattern) +- **Tailwind CSS v4** +- **Radix UI** (dialog, popover, toggle) +- **i18next** + **react-i18next** (internationalization) +- **Vite** (build tool) +- **pnpm** (package manager) + +## Directory Structure + +``` +device_page/ +├── locales/ # Translation JSON files (17 languages) +├── public/img/ # Static assets (SVG icons) +├── dist/ # Build output (loaded by C++ webview) +├── src/ +│ ├── main.tsx # App entry (router + StrictMode) +│ ├── i18n.tsx # i18next configuration +│ ├── routes/ # File-based routes (TanStack Router) +│ │ ├── __root.tsx # Root layout (nav bar, conditional by route) +│ │ ├── index.tsx # / (home) +│ │ ├── calibration.tsx # /calibration +│ │ ├── filament.tsx # /filament +│ │ ├── webcalib.tsx # /webcalib +│ │ └── ... +│ ├── features/ # Feature modules +│ │ ├── calibration/ # PA calibration management +│ │ ├── filament/ # Filament management +│ │ ├── webcalib/ # Web calibration +│ │ ├── ams/ # AMS control +│ │ ├── control/ # Machine control (nozzle, heatbed, etc.) +│ │ └── ... +│ ├── hooks/ +│ │ └── Bridge.tsx # JS <-> C++ communication bridge +│ ├── store/ # Zustand store slices +│ │ ├── AppStore.tsx # Root store +│ │ ├── CalibrationSlice.tsx +│ │ └── ... +│ └── components/ # Shared UI components +├── vite.config.ts # Vite config (file:// compat plugin, @locales alias) +├── i18next-parser.config.js # Translation key extraction config +├── tsconfig.app.json # TypeScript config +└── package.json +``` + +## Development Environment Setup + +### Prerequisites + +| Tool | Version | Notes | +|------|---------|-------| +| **Node.js** | >= 18 | Required by Vite 6. Recommend LTS (20.x or 22.x) | +| **pnpm** | 10.12.1 | Pinned via `packageManager` in package.json. Install: `corepack enable && corepack prepare` | + +### Install Dependencies + +```bash +cd resources/web/device_page +pnpm install +``` + +## Quick Start + +```bash +# Dev server (hot reload, accessible at http://localhost:5173) +pnpm dev + +# Build for production (output to dist/) +pnpm build # tsc + vite build +npx vite build # skip tsc, vite only (faster, recommended during development) +``` + +## Loading Modes + +The C++ side (`WebDevicePage.cpp`) loads the web app in two modes: + +| Mode | URL | Use Case | +|------|-----|----------| +| **file://** (default) | `file://...resources/web/device_page/dist/index.html` | Production / normal use | +| **HTTP server** | `http://localhost:13628/index.html` | Development with hot-reload | + +In **debug builds** (non-release), HTTP server mode is auto-enabled via: + +```cpp +#if !BBL_RELEASE_TO_PUBLIC +#define DEVICE_USE_HTTP_SERVER +#endif +``` + +No manual changes needed — just build the C++ side in Debug configuration. + +### Development Workflow (Hot Reload) + +For the best development experience, use the C++ HTTP server + Vite dev server together: + +1. **Build & launch the desktop app** (Debug configuration) — the embedded HTTP server starts automatically on `localhost:13628`, serving files from `dist/` +2. **Run the Vite dev server** in a terminal: + ```bash + cd resources/web/device_page + pnpm dev + ``` + Vite runs on `http://localhost:5173` with HMR (Hot Module Replacement). +3. **In the desktop app**, click "Load App" in the debug toolbar — this navigates the WebView to `http://localhost:13628/index.html` +4. For **real-time hot reload**, type `http://localhost:5173` in the debug toolbar URL box and click "Go!" — changes you make in `src/` are reflected instantly + +The debug toolbar (visible only in debug builds) provides: + +| Button | Action | +|--------|--------| +| **Load App** | Navigate to `http://localhost:13628/index.html` (C++ HTTP server) | +| **Reload** | Hard-reload the current page in WebView | +| **URL box + Go!** | Navigate to any URL (e.g., Vite dev server `http://localhost:5173`) | + +### Production Build Workflow + +For testing with `file://` protocol (matches production behavior): + +```bash +npx vite build # Build to dist/ +# Then launch the desktop app in Release mode — it loads dist/index.html via file:// +``` + +## Multi-Tab Architecture + +One WebView instance serves multiple main app tabs. Tab switching triggers hash route navigation: + +``` +MainFrame Tab Bar + ├── Web Device → WebDevicePage → #/calibration + ├── Filament Manager → WebDevicePage → #/filament + └── Calibration → WebDevicePage → #/webcalib +``` + +All tabs share the same `WebDevicePage` (wxPanel). The C++ side calls `NavigateTo("/route")` on tab switch, which executes `window.location.hash = '#/route'` in the WebView. + +## Adding a New Page + +### 1. Create the route file + +``` +src/routes/myfeature.tsx +``` + +```tsx +import { createFileRoute } from '@tanstack/react-router'; +import { MyFeaturePage } from '../features/myfeature/MyFeaturePage'; + +export const Route = createFileRoute('/myfeature')({ + component: MyFeaturePage, +}); +``` + +### 2. Create the feature module + +``` +src/features/myfeature/MyFeaturePage.tsx +``` + +```tsx +import { useTranslation } from 'react-i18next'; + +export function MyFeaturePage() { + const { t } = useTranslation(); + return

{t("My Feature")}

; +} +``` + +### 3. Register C++ tab (if needed as a top-level tab) + +In `MainFrame.cpp` (`init_tabpanel`): + +```cpp +m_tabpanel->AddPage(m_web_device, _L("My Feature"), ...); +``` + +In the tab change handler, add routing: + +```cpp +else if (sel == tpMyFeature) + m_web_device->NavigateTo("/myfeature"); +``` + +### 4. Hide navigation bar (if full-screen page) + +In `src/routes/__root.tsx`, add the route to `hideNav`: + +```tsx +const hideNav = pathname === '/filament' || pathname === '/webcalib' || pathname === '/myfeature'; +``` + +### 5. Build and verify + +```bash +npx vite build +``` + +## Feature Module Structure + +Each page is backed by a **feature module** under `src/features/`. Taking `calibration` as a reference: + +``` +src/features/calibration/ +├── CalibrationPage.tsx # Page component (entry point, composes sub-components) +├── useCalibrationBridge.ts # Bridge hook (all C++ communication for this feature) +├── types.ts # TypeScript types (request/response payloads, data models) +├── PAHistoryTable.tsx # Sub-component: data table +├── PAEditModal.tsx # Sub-component: create/edit dialog +└── PADeleteConfirm.tsx # Sub-component: delete confirmation +``` + +### Step-by-step: Adding a sub-feature module + +Using "Filament Manager" as an example: + +#### 1. Define types (`types.ts`) + +```ts +// src/features/filament/types.ts +export interface FilamentItem { + id: string; + name: string; + material: string; + color: string; +} + +export interface BridgeResponseBody { + module: string; + resource: string; + action: string; + code: number; + message: string; + payload: Record; +} +``` + +#### 2. Create store slice (`store/FilamentSlice.tsx`) + +```tsx +import type { StateCreator } from 'zustand'; +import type { RootState } from './AppStore'; +import type { FilamentItem } from '../features/filament/types'; + +export interface FilamentSlice { + filament: { + items: FilamentItem[]; + isLoading: boolean; + error: string | null; + setItems: (items: FilamentItem[]) => void; + setLoading: (v: boolean) => void; + setError: (e: string | null) => void; + }; +} + +export const createFilamentSlice: StateCreator< + RootState, [['zustand/immer', never]], [], FilamentSlice +> = (set) => ({ + filament: { + items: [], + isLoading: false, + error: null, + setItems: (items) => set((s) => { s.filament.items = items; }), + setLoading: (v) => set((s) => { s.filament.isLoading = v; }), + setError: (e) => set((s) => { s.filament.error = e; }), + }, +}); +``` + +Then register in `AppStore.tsx`: + +```tsx +import { createFilamentSlice } from './FilamentSlice'; +import type { FilamentSlice } from './FilamentSlice'; + +export type RootState = ... & FilamentSlice; + +// Inside create(): +...createFilamentSlice(set, get, api), +``` + +#### 3. Create bridge hook (`useFilamentBridge.ts`) + +```ts +import { useCallback } from 'react'; +import { useDeviceBridge } from '../../hooks/Bridge'; +import useStore from '../../store/AppStore'; +import type { BridgeResponseBody, FilamentItem } from './types'; + +function makeBody(resource: string, action: string, payload?: Record) { + return { module: 'filament', resource, action, payload: payload ?? {} }; +} + +export function useFilamentBridge() { + const request = useDeviceBridge(); + const setItems = useStore((s) => s.filament.setItems); + const setLoading = useStore((s) => s.filament.setLoading); + const setError = useStore((s) => s.filament.setError); + + const fetchList = useCallback(async () => { + setLoading(true); + const res = await request, BridgeResponseBody>( + makeBody('filament_list', 'list') + ); + setLoading(false); + if (res.ok && res.value.code === 0) { + setItems((res.value.payload?.items as FilamentItem[]) ?? []); + } else { + setError(res.ok ? res.value.message : res.error); + } + }, [request, setItems, setLoading, setError]); + + return { fetchList }; +} +``` + +#### 4. Build the page component (`FilamentPage.tsx`) + +```tsx +import { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useFilamentBridge } from './useFilamentBridge'; +import useStore from '../../store/AppStore'; + +export function FilamentPage() { + const { t } = useTranslation(); + const { fetchList } = useFilamentBridge(); + const items = useStore((s) => s.filament.items); + const isLoading = useStore((s) => s.filament.isLoading); + + useEffect(() => { fetchList(); }, [fetchList]); + + return ( +
+

{t("Filament Manager")}

+ {isLoading ?

{t("Loading...")}

: ( +
    + {items.map((f) =>
  • {f.name}
  • )} +
+ )} +
+ ); +} +``` + +### Convention summary + +| File | Role | +|------|------| +| `types.ts` | Data models, request/response payload types | +| `use[Feature]Bridge.ts` | All C++ communication (request + report event subscription) | +| `store/[Feature]Slice.tsx` | Zustand state & actions for this feature | +| `[Feature]Page.tsx` | Page entry component, composes sub-components | +| `[SubComponent].tsx` | UI sub-components (tables, modals, forms) | + +## JS <-> C++ Communication + +Communication uses `useDeviceBridge()` hook (`src/hooks/Bridge.tsx`). + +### Frontend -> C++ (Request) + +```tsx +const request = useDeviceBridge(); + +const result = await request({ + module: "calibration", + resource: "pa_history", + action: "list", + payload: { nozzle_diameter: 0.4 } +}); + +if (result.ok) { + console.log(result.value); +} +``` + +### C++ -> Frontend (Report/Push) + +C++ sends state updates via `ReportMsg`, dispatched as `CustomEvent('cpp:device')` on `document`. Feature hooks subscribe to these events. + +### Adding a new ViewModel (C++ side) + +1. Create `src/slic3r/GUI/DeviceWeb/MyFeatureViewModel.hpp/cpp` +2. Implement `IViewModel` interface (`GetModule()`, `OnCommand()`, `ReportState()`) +3. Register in `WebDevicePage.cpp`: + ```cpp + m_device_web_mgr->Register(std::make_unique()); + ``` +4. Add files to `CMakeLists.txt` + +## Internationalization (i18n) + +### Usage in components + +```tsx +import { useTranslation } from 'react-i18next'; + +function MyComponent() { + const { t } = useTranslation(); + return ( + <> + {t("Confirm")} + {t("Loaded {{count}} items", { count: 5 })} + {t("Save", { context: "file" })} + + ); +} +``` + +- **Key = English original text** (readable in code) +- **Interpolation**: `{{variable}}` in key and translations +- **Context**: `t("key", { context: "ctx" })` looks up `key_ctx` in translation files + +### Translation files + +Located in `locales/`, one JSON per language. 17 languages matching the desktop app: + +``` +en, zh_CN, ja_JP, it_IT, fr_FR, de_DE, hu_HU, es_ES, +sv_SE, cs_CZ, nl_NL, uk_UA, ru_RU, tr_TR, pt_BR, ko_KR, pl_PL +``` + +Format: + +```json +{ + "Confirm": "确认", + "Save_file": "保存文件", + "Loaded {{count}} items": "已加载 {{count}} 个项目" +} +``` + +English file (`en.json`) also maintains full key-value mapping for cases where key text differs from display text. + +### Extract new keys from code + +```bash +pnpm run i18n +``` + +Scans all `src/**/*.{ts,tsx}` for `t()` calls, adds new keys to all 17 language files. Existing translations are preserved. + +### Language detection + +Priority: URL `?lang=zh_CN` > `localStorage["BambuWebLang"]` > fallback `en` + +The C++ side appends `?lang=` to the URL when loading the page, consistent with other webview pages in the project. + +### Alias configuration + +Translation files use the `@locales` path alias. If the `locales/` directory moves, update these 3 files: + +| File | Setting | +|------|---------| +| `vite.config.ts` | `resolve.alias['@locales']` | +| `tsconfig.app.json` | `compilerOptions.paths['@locales/*']` | +| `i18next-parser.config.js` | `LOCALES_DIR` constant | + +## Vite Build Notes + +The `fileProtocolCompat()` plugin in `vite.config.ts` ensures the build output works under `file://` protocol: + +1. Strips `crossorigin` attributes (blocked by browser under file://) +2. Moves ` + + diff --git a/resources/web/fila_manager/index.js b/resources/web/fila_manager/index.js new file mode 100644 index 0000000000..a45ab45575 --- /dev/null +++ b/resources/web/fila_manager/index.js @@ -0,0 +1,1461 @@ +/* Filament Manager — index.js */ + +var g_spools = []; +var g_view = "my"; +var g_tab = "all"; +var g_sort_key = ""; +var g_sort_asc = true; +var g_selected_ids = {}; +var g_filters = {}; +var g_editing_spool_id = null; +var g_dialog_mode = "manual"; +var g_quantity = 1; +var g_ams_data = null; +var g_ams_selected_unit = null; +var g_ams_selected_slot = null; +var g_grouped = false; +var g_collapsed_groups = {}; +var g_page = 1; +var g_page_size = 50; + +var BAMBU_COLORS = [ + "#000000","#333333","#555555","#808080","#BBBBBB","#FFFFFF", + "#FF0000","#CC3333","#FF6666","#FF3300","#FF6600","#FF9900", + "#FFCC00","#FFFF00","#CCFF00","#66FF00","#00CC00","#009933", + "#006633","#00CCCC","#0099CC","#0066CC","#0033CC","#0000FF", + "#3300CC","#6600CC","#9900CC","#CC00CC","#FF00FF","#FF66CC", + "#FF99CC","#CC6666","#996633","#663300","#CCCC99","#99CC66", + "#66CCCC","#6699FF","#CC99FF","#FFCC99" +]; + +var CURRENCY_SYMBOLS = {"USD":"US$","CNY":"¥","EUR":"€","JPY":"¥"}; +var g_preset_vendors = []; + +/* ===== C++ ↔ JS Bridge ===== */ +/* + * JS → C++: chrome.webview.postMessage / window.wx.postMessage + * C++ → JS: window.__cppPush(pkt) → CustomEvent('cpp:fila') + * + * __cppPush is defined here so it's available before any C++ response. + * C++ re-injects it on wxEVT_WEBVIEW_LOADED as a safety net (idempotent). + */ +var FM_VERSION = "1.0"; +var FM_REQUEST_TIMEOUT_MS = 15000; + +window.__cppPush = function(pkt) { + try { + document.dispatchEvent(new CustomEvent("cpp:fila", { detail: pkt })); + } catch(e) { console.error("[FM] __cppPush error:", e); } +}; + +var g_req_seq = 0; +var g_pending_reqs = {}; + +function postMessage(msg) { + var json = JSON.stringify(msg); + if (window.chrome && window.chrome.webview) + window.chrome.webview.postMessage(json); + else if (window.wx) + window.wx.postMessage(json); + else + console.log("[FM] postMessage (no bridge):", json); +} + +/** + * Send a request to C++ and register a response callback. + * @param {string} command + * @param {object} data + * @param {function} onResponse - callback(code, data) + * @param {number} [timeoutMs] - override default timeout; 0 = no timeout + */ +function sendRequest(command, data, onResponse, timeoutMs) { + var seq = ++g_req_seq; + var timer = null; + + function settle(code, respData) { + if (timer) { clearTimeout(timer); timer = null; } + delete g_pending_reqs[seq]; + if (onResponse) onResponse(code, respData); + } + + g_pending_reqs[seq] = settle; + + var ms = (timeoutMs === undefined) ? FM_REQUEST_TIMEOUT_MS : timeoutMs; + if (ms > 0) { + timer = setTimeout(function() { + if (g_pending_reqs[seq]) { + console.warn("[FM] request timeout seq=" + seq + " cmd=" + command); + settle(-2, { error: "request timeout" }); + } + }, ms); + } + + postMessage({ type: "request", v: FM_VERSION, seq: seq, command: command, data: data || {} }); +} + +/* ===== Push subscription registry ===== */ +var g_push_handlers = {}; + +/** + * Subscribe to a push command from C++. Returns an unsubscribe function. + * @param {string} command + * @param {function} handler - handler(data) + * @returns {function} unsubscribe + */ +function onPush(command, handler) { + if (!g_push_handlers[command]) g_push_handlers[command] = []; + g_push_handlers[command].push(handler); + return function() { + var arr = g_push_handlers[command]; + if (arr) g_push_handlers[command] = arr.filter(function(h) { return h !== handler; }); + }; +} + +function onSpoolsUpdated(code, data) { + if (code === 0) { g_spools = data || []; refresh(); } +} + +function onMachineListResponse(code, data) { + var deviceArea = document.getElementById("ams-device-area"); + var emptyArea = document.getElementById("ams-empty"); + var emptyText = document.querySelector(".ams-empty-text"); + + if (code !== 0) { + deviceArea.style.display = "none"; + emptyArea.style.display = "flex"; + if (emptyText) emptyText.textContent = "获取设备列表失败,请重试"; + document.getElementById("dialog-body").style.display = "none"; + console.error("[FM] get_machine_list failed, code=" + code); + return; + } + + var machines = (data && data.machines) || []; + + if (machines.length === 0) { + deviceArea.style.display = "none"; + emptyArea.style.display = "flex"; + if (emptyText) emptyText.textContent = "未发现可用打印机,请确保已登录并绑定设备"; + document.getElementById("dialog-body").style.display = "none"; + return; + } + + emptyArea.style.display = "none"; + deviceArea.style.display = "block"; + + var sel = document.getElementById("ams-device-select"); + sel.innerHTML = ""; + var firstOnlineId = ""; + machines.forEach(function(m) { + var opt = document.createElement("option"); + opt.value = m.dev_id; + opt.textContent = m.dev_name || m.dev_id; + if (m.is_online) opt.textContent += " (在线)"; + sel.appendChild(opt); + if (!firstOnlineId && m.is_online) firstOnlineId = m.dev_id; + }); + + var defaultId = firstOnlineId || machines[0].dev_id; + sel.value = defaultId; + + g_ams_selected_unit = null; + g_ams_selected_slot = null; + document.getElementById("ams-unit-icons").innerHTML = ""; + document.getElementById("ams-slots").innerHTML = + '
正在加载 AMS 数据…
'; + sendRequest("get_ams_data", { dev_id: defaultId }, onAmsDataResponse); +} + +function onAmsDataResponse(code, data) { + if (code !== 0) { + console.error("[FM] get_ams_data failed, code=" + code); + document.getElementById("ams-unit-icons").innerHTML = ""; + document.getElementById("ams-slots").innerHTML = + '
获取 AMS 数据失败
'; + document.getElementById("dialog-body").style.display = "none"; + return; + } + g_ams_data = data || null; + try { + renderAmsSection(); + } catch(e) { + console.error("[FM] renderAmsSection error:", e); + document.getElementById("ams-unit-icons").innerHTML = ""; + document.getElementById("ams-slots").innerHTML = + '
渲染错误: ' + e.message + '
'; + document.getElementById("dialog-body").style.display = "none"; + } +} + +/* ===== C++ → JS message dispatcher ===== */ +/* + * C++ calls: window.__cppPush({ v, ts, type, seq, code, command, data }) + * __cppPush dispatches: CustomEvent('cpp:fila', { detail: pkt }) + * Router: responses → pending callbacks; pushes → registered handlers. + */ +document.addEventListener("cpp:fila", function(e) { + var msg = e.detail; + if (!msg) return; + + var type = msg.type || ""; + + /* Response — resolve pending request callback */ + if (type === "response") { + var cb = g_pending_reqs[msg.seq]; + if (cb) cb(msg.code || 0, msg.data); + return; + } + + /* Push — dispatch to registered handlers */ + if (type === "push") { + var cmd = msg.command; + var handlers = g_push_handlers[cmd]; + if (handlers && handlers.length) { + var data = msg.data; + for (var i = 0; i < handlers.length; i++) { + try { handlers[i](data); } catch(err) { console.error("[FM] push handler error cmd=" + cmd, err); } + } + } + } +}); + +/* ===== Register push handlers ===== */ +onPush("spool_list", function(data) { g_spools = data || []; refresh(); }); +onPush("preset_options", function(data) { g_preset_vendors = (data && data.vendors) || []; }); +onPush("ams_data", function(data) { onAmsDataResponse(0, data); }); +onPush("theme_changed", function(data) { + var theme = (data && data.theme) || "dark"; + document.documentElement.dataset.theme = theme; + if (g_view === "stats") renderStats(); +}); + +/* ===== Filtering & Sorting ===== */ +function getFilteredSpools() { + var keyword = (document.getElementById("search-input").value || "").toLowerCase(); + var list = g_spools.filter(function(s) { + if (g_view === "archived") { if (s.status !== "archived") return false; } + else { if (s.status === "archived") return false; } + if (g_tab === "favorite" && !s.favorite) return false; + if (g_tab === "ams" && s.entry_method !== "ams_sync") return false; + if (keyword) { + var hay = ((s.brand||"")+" "+(s.material_type||"")+" "+(s.series||"")+" "+(s.color_name||"")).toLowerCase(); + if (hay.indexOf(keyword) === -1) return false; + } + for (var k in g_filters) { + if (g_filters[k] && s[k] !== g_filters[k]) return false; + } + return true; + }); + if (g_sort_key) { + list.sort(function(a, b) { + var va = a[g_sort_key], vb = b[g_sort_key]; + if (typeof va === "number" && typeof vb === "number") return g_sort_asc ? va - vb : vb - va; + va = String(va || ""); vb = String(vb || ""); + return g_sort_asc ? va.localeCompare(vb) : vb.localeCompare(va); + }); + } + return list; +} + +function refresh() { + var spools = getFilteredSpools(); + renderTable(spools); + updateBatchUI(); + if (g_view === "stats") renderStats(); +} + +/* ===== Status tags ===== */ +function getStatusTags(s) { + var tags = []; + var remain = s.remain_percent || 0; + if (remain === 0) tags.push({text: "已用尽", cls: "status-empty"}); + else if (remain < 20) tags.push({text: "低余量", cls: "status-low"}); + if (s.dry_reminder_days > 0 && s.dry_date) { + var diff = (Date.now() - new Date(s.dry_date).getTime()) / 86400000; + if (diff >= s.dry_reminder_days) tags.push({text: "需烘干", cls: "status-dry"}); + } + return tags; +} + +/* ===== Price formatting ===== */ +var CURRENCY_SYMBOLS = {CNY:"¥", USD:"$", EUR:"€", JPY:"¥"}; +function formatPrice(price, currency) { + var sym = CURRENCY_SYMBOLS[currency] || "$"; + return sym + " " + (price || 0).toFixed(2); +} + +/* ===== Grouping ===== */ +function groupSpools(list) { + var map = {}; + list.forEach(function(s) { + var key = (s.brand||"?") + "/" + (s.material_type||"") + (s.series ? " "+s.series : "") + "/" + (s.color_name || s.color_code || "?"); + if (!map[key]) map[key] = {key: key, count: 0, totalWeight: 0, spools: [], collapsed: !!g_collapsed_groups[key]}; + map[key].count++; + map[key].totalWeight += Math.round((s.initial_weight||0) * (s.remain_percent||0) / 100); + map[key].spools.push(s); + }); + return Object.values(map); +} + +/* ===== Table rendering ===== */ +function renderTable(allSpools) { + var tbody = document.getElementById("spool-tbody"); + var empty = document.getElementById("empty-state"); + tbody.innerHTML = ""; + + var totalCount = allSpools.length; + if (!totalCount) { + empty.style.display = "flex"; + renderPagination(0); + return; + } + empty.style.display = "none"; + + if (g_grouped) { + var groups = groupSpools(allSpools); + var flatRows = []; + groups.forEach(function(g) { + flatRows.push({_groupHeader: true, group: g}); + if (!g.collapsed) g.spools.forEach(function(s) { flatRows.push(s); }); + }); + var start = (g_page - 1) * g_page_size; + var page = flatRows.slice(start, start + g_page_size); + page.forEach(function(item) { + if (item._groupHeader) tbody.appendChild(createGroupHeader(item.group)); + else tbody.appendChild(createRow(item)); + }); + renderPagination(flatRows.length); + } else { + var start = (g_page - 1) * g_page_size; + var page = allSpools.slice(start, start + g_page_size); + page.forEach(function(s) { tbody.appendChild(createRow(s)); }); + renderPagination(totalCount); + } +} + +function createGroupHeader(g) { + var tr = document.createElement("tr"); + tr.className = "group-header"; + tr.innerHTML = '
' + + '' + + ''+esc(g.key)+'' + + ''+g.count+'' + + ''+g.totalWeight+' g' + + '
'; + tr.addEventListener("click", function() { + g.collapsed = !g.collapsed; + g_collapsed_groups[g.key] = g.collapsed; + refresh(); + }); + return tr; +} + +function buildSpoolSvg(color) { + var c = color || "#888"; + return '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''; +} + +function createRow(s) { + var tr = document.createElement("tr"); + if (g_selected_ids[s.spool_id]) tr.className = "selected"; + var remain = s.remain_percent || 0; + var pClass = remain === 0 ? "empty" : (remain < 20 ? "low" : ""); + var remainWeight = Math.round((s.initial_weight||0) * remain / 100); + var totalWeight = Math.round(s.initial_weight||0); + var tags = getStatusTags(s); + var tagsHtml = tags.length ? tags.map(function(t) { return ''+t.text+''; }).join("") : ""; + var diam = s.diameter || 1.75; + var nameParts = (s.material_type||"") + (s.series ? " "+s.series : ""); + + tr.innerHTML = + '' + + '
' + + '
' + buildSpoolSvg(s.color_code) + '
' + + '
' + + '
' + + '' + + ''+esc(nameParts||"—")+'' + + '' + + '
' + + '
'+diam+' mm | '+esc(s.color_name||"—")+'
' + + '
' + + '
' + + '
' + + '
'+remainWeight+' g / '+totalWeight+' g
' + + '
' + + '
' + + '
'+tagsHtml+'
' + + ''+formatPrice(s.unit_price, s.price_currency)+'' + + '
' + + '' + + '' + + '' + + '
'; + return tr; +} + +/* ===== Pagination ===== */ +function renderPagination(total) { + var el = document.getElementById("pagination"); + if (total <= g_page_size) { el.innerHTML = ""; return; } + var pages = Math.ceil(total / g_page_size); + if (g_page > pages) g_page = pages; + var html = ''; + var range = buildPageRange(g_page, pages); + range.forEach(function(p) { + if (p === "...") html += ''; + else html += ''; + }); + html += ''; + html += ''; + el.innerHTML = html; +} + +function buildPageRange(cur, total) { + if (total <= 7) { var a=[]; for(var i=1;i<=total;i++) a.push(i); return a; } + var r = [1]; + if (cur > 3) r.push("..."); + for (var i=Math.max(2,cur-1); i<=Math.min(total-1,cur+1); i++) r.push(i); + if (cur < total-2) r.push("..."); + if (total > 1) r.push(total); + return r; +} + +/* ===== Batch selection ===== */ +function updateBatchUI() { + var cnt = Object.keys(g_selected_ids).length; + document.getElementById("btn-delete").disabled = cnt === 0; + document.getElementById("check-all").checked = false; +} + +/* ===== Row actions ===== */ +function editSpool(id) { + openDetail(id); +} + +function addSimilar(id) { + var s = g_spools.find(function(x) { return x.spool_id === id; }); + if (!s) return; + g_editing_spool_id = null; + openDialog({ + brand: s.brand, material_type: s.material_type, series: s.series, + color_code: s.color_code, color_name: s.color_name, + initial_weight: s.initial_weight, spool_weight: s.spool_weight, + price_currency: s.price_currency, unit_price: s.unit_price + }); +} + +function toggleFav(id) { sendRequest("toggle_favorite", { spool_id: id }, onSpoolsUpdated); } + +function archiveOrDelete(id) { + if (g_view === "archived") { + if (confirm("确定删除这条耗材记录?")) sendRequest("remove_spool", { spool_id: id }, onSpoolsUpdated); + } else { + sendRequest("archive_spool", { spool_id: id }, onSpoolsUpdated); + } +} + +/* ===== Filter dropdown ===== */ +function openFilterDropdown(btn, filterKey) { + var dd = document.getElementById("filter-dropdown"); + var list = document.getElementById("filter-dropdown-list"); + var vals = {}; + g_spools.forEach(function(s) { if (s[filterKey]) vals[s[filterKey]] = true; }); + var items = Object.keys(vals).sort(); + + list.innerHTML = '
全部
'; + items.forEach(function(v) { + list.innerHTML += '
'+esc(v)+'
'; + }); + + var rect = btn.getBoundingClientRect(); + dd.style.left = rect.left + "px"; + dd.style.top = (rect.bottom + 4) + "px"; + dd.style.display = "block"; + dd._filterKey = filterKey; + dd._btn = btn; +} + +/* ===== Dialog ===== */ +function openDialog(spool) { + var isEdit = !!spool; + document.getElementById("dialog-title").textContent = isEdit ? "编辑耗材" : "添加耗材"; + document.getElementById("dialog-confirm").textContent = isEdit ? "保存" : "添加"; + document.getElementById("quantity-control").style.display = isEdit ? "none" : "flex"; + g_quantity = 1; + document.getElementById("qty-value").textContent = "1"; + + populateDropdowns(); + renderColorPalette(spool ? spool.color_code : ""); + + if (isEdit) { + setVal("form-brand", spool.brand); + populateTypeDropdown(); + setVal("form-type", spool.material_type); + populateSeriesDropdown(); + setVal("form-series", spool.series); + document.getElementById("form-color-code").value = spool.color_code || ""; + setVal("form-color-name", spool.color_name); + setVal("form-total-weight", spool.initial_weight || 1000); + setVal("form-spool-weight", spool.spool_weight || 250); + calcNetWeight(); + setVal("form-remain-alert", spool.remain_alert_pct || 0); + setVal("form-dry-date", spool.dry_date); + setVal("form-dry-reminder", spool.dry_reminder_days || 0); + setVal("form-currency", spool.price_currency); + setVal("form-price", spool.unit_price || ""); + setVal("form-note", spool.note); + updateCharCount(); + } else { + ["form-brand","form-type","form-series","form-color-name","form-dry-date","form-currency","form-price","form-note"].forEach(function(id) { setVal(id, ""); }); + document.getElementById("form-color-code").value = ""; + setVal("form-total-weight", 1000); + setVal("form-spool-weight", 250); + calcNetWeight(); + setVal("form-remain-alert", 0); + setVal("form-dry-reminder", 0); + updateCharCount(); + } + + document.getElementById("advanced-section").style.display = "none"; + document.getElementById("advanced-toggle").classList.remove("open"); + g_ams_selected_slot = null; + g_ams_selected_unit = null; + setAmsFormReadonly(false); + switchDialogMode("manual"); + document.getElementById("dialog-overlay").style.display = "flex"; + validateForm(); +} + +function closeDialog() { + document.getElementById("dialog-overlay").style.display = "none"; + g_editing_spool_id = null; + g_ams_selected_slot = null; + setAmsFormReadonly(false); +} + +function switchDialogMode(mode) { + g_dialog_mode = mode; + document.querySelectorAll(".dialog-tab").forEach(function(t) { + t.classList.toggle("active", t.getAttribute("data-mode") === mode); + }); + document.getElementById("ams-section").style.display = mode === "ams" ? "block" : "none"; + document.getElementById("dialog-body").style.display = mode === "manual" ? "block" : (g_ams_selected_slot ? "block" : "none"); + + if (mode === "ams") { + g_ams_selected_slot = null; + document.getElementById("ams-device-area").style.display = "none"; + document.getElementById("ams-empty").style.display = "flex"; + var emptyText = document.querySelector(".ams-empty-text"); + if (emptyText) emptyText.textContent = "正在获取设备信息…"; + sendRequest("get_machine_list", {}, onMachineListResponse); + } +} + +function submitDialog() { + var data = { + brand: getVal("form-brand"), + material_type: getVal("form-type"), + series: getVal("form-series"), + color_code: document.getElementById("form-color-code").value, + color_name: getVal("form-color-name"), + initial_weight: parseFloat(getVal("form-total-weight")) || 1000, + spool_weight: parseFloat(getVal("form-spool-weight")) || 0, + net_weight: parseFloat(getVal("form-net-weight")) || 0, + remain_alert_pct: parseInt(getVal("form-remain-alert")) || 0, + dry_date: getVal("form-dry-date"), + dry_reminder_days: parseInt(getVal("form-dry-reminder")) || 0, + price_currency: getVal("form-currency"), + unit_price: parseFloat(getVal("form-price")) || 0, + note: getVal("form-note") + }; + if (g_editing_spool_id) { + data.spool_id = g_editing_spool_id; + sendRequest("update_spool", data, onSpoolsUpdated); + } else if (g_dialog_mode === "ams" && g_ams_selected_slot) { + var tray = g_ams_selected_slot.tray; + data.entry_method = "ams_sync"; + data.tag_uid = tray.tag_uid || ""; + data.setting_id = tray.setting_id || ""; + data.bound_ams_id = g_ams_selected_slot.ams_id || ""; + data.bound_dev_id = (g_ams_data && g_ams_data.dev_id) || ""; + data.remain_percent = tray.remain || 0; + sendRequest("add_spool", data, onSpoolsUpdated); + } else if (g_quantity > 1) { + data.entry_method = "manual"; + sendRequest("batch_add", { spool: data, quantity: g_quantity }, onSpoolsUpdated); + } else { + data.entry_method = "manual"; + sendRequest("add_spool", data, onSpoolsUpdated); + } + closeDialog(); +} + +/* ===== Color palette ===== */ +function renderColorPalette(selectedColor) { + var el = document.getElementById("color-palette"); + el.innerHTML = ""; + var addBtn = document.createElement("div"); + addBtn.className = "color-swatch-add"; + addBtn.innerHTML = '+'; + el.appendChild(addBtn); + + BAMBU_COLORS.forEach(function(c) { + var sw = document.createElement("div"); + sw.className = "color-swatch" + (c.toUpperCase() === (selectedColor||"").toUpperCase() ? " selected" : ""); + sw.style.background = c; + sw.setAttribute("data-color", c); + sw.addEventListener("click", function() { selectColor(c); }); + el.appendChild(sw); + }); + + addBtn.querySelector("input").addEventListener("change", function(e) { + selectColor(e.target.value); + }); +} + +function selectColor(c) { + document.getElementById("form-color-code").value = c; + document.querySelectorAll(".color-swatch").forEach(function(sw) { + sw.classList.toggle("selected", sw.getAttribute("data-color") && sw.getAttribute("data-color").toUpperCase() === c.toUpperCase()); + }); + validateForm(); +} + +/* ===== Helpers ===== */ +function populateDropdowns() { + var brands = g_preset_vendors.map(function(v) { return v.name; }).sort(); + fillSelect("form-brand", brands, "选择品牌"); + populateTypeDropdown(); +} + +function getTypesForBrand(brand) { + if (brand) { + var vendor = g_preset_vendors.find(function(v) { return v.name === brand; }); + return vendor ? vendor.types || [] : []; + } + var seen = {}, result = []; + g_preset_vendors.forEach(function(v) { + (v.types || []).forEach(function(t) { + if (!seen[t.name]) { seen[t.name] = true; result.push(t); } + }); + }); + return result; +} + +function populateTypeDropdown() { + var brand = getVal("form-brand"); + var typeObjs = getTypesForBrand(brand); + var names = typeObjs.map(function(t) { return t.name; }).sort(); + var prev = getVal("form-type"); + fillSelect("form-type", names, "选择类型"); + if (names.indexOf(prev) !== -1) setVal("form-type", prev); + populateSeriesDropdown(); +} + +function populateSeriesDropdown() { + var brand = getVal("form-brand"); + var type = getVal("form-type"); + var seriesList = []; + var seen = {}; + + var typeObjs = getTypesForBrand(brand); + typeObjs.forEach(function(t) { + if (type && t.name !== type) return; + (t.series || []).forEach(function(s) { + if (s && !seen[s]) { seen[s] = true; seriesList.push(s); } + }); + }); + seriesList.sort(); + + var prev = getVal("form-series"); + fillSelect("form-series", seriesList, "选择系列"); + if (seriesList.indexOf(prev) !== -1) setVal("form-series", prev); +} + +function fillSelect(id, items, placeholder) { + var sel = document.getElementById(id); + sel.innerHTML = ''; + items.forEach(function(v) { sel.innerHTML += ''; }); +} + +function calcNetWeight() { + var tw = parseFloat(getVal("form-total-weight")) || 0; + var sw = parseFloat(getVal("form-spool-weight")) || 0; + setVal("form-net-weight", Math.max(0, tw - sw)); + validateForm(); +} + +function validateForm() { + var brand = getVal("form-brand"); + var type = getVal("form-type"); + var series = getVal("form-series"); + var color = document.getElementById("form-color-code").value; + var weight = parseFloat(getVal("form-total-weight")) || 0; + var valid = brand && type && series && color && weight > 0; + var btn = document.getElementById("dialog-confirm"); + btn.disabled = !valid; +} + +function updateCharCount() { + var note = getVal("form-note") || ""; + document.getElementById("char-count").textContent = note.length + "/50"; +} + +function setVal(id, v) { document.getElementById(id).value = v == null ? "" : v; } +function getVal(id) { return document.getElementById(id).value; } +function esc(s) { return s == null ? "" : String(s).replace(/&/g,"&").replace(//g,">").replace(/"/g,"""); } + +/* ===== Detail Dialog ===== */ +var g_detail_spool_id = null; + +function openDetail(id) { + var s = g_spools.find(function(x) { return x.spool_id === id; }); + if (!s) return; + g_detail_spool_id = id; + + var nameParts = (s.material_type||"") + (s.series ? " "+s.series : ""); + document.getElementById("det-spool-name").textContent = nameParts || "—"; + var icon = document.getElementById("det-spool-icon"); + icon.style.setProperty("--spool-color", s.color_code || "#888"); + icon.innerHTML = buildSpoolSvg(s.color_code) + '
'; + var entryTag = document.getElementById("det-entry-tag"); + var entryMap = {manual:"手动", ams_sync:"自动", rfid:"RFID"}; + entryTag.textContent = entryMap[s.entry_method] || ""; + document.getElementById("det-spool-sub").textContent = (s.diameter || 1.75) + " mm|" + (s.color_name || "—"); + + document.getElementById("det-v-brand").textContent = s.brand || "—"; + document.getElementById("det-v-type").textContent = s.material_type || "—"; + document.getElementById("det-v-series").textContent = s.series || "—"; + var colorEl = document.getElementById("det-v-color"); + colorEl.style.background = s.color_code || "#888"; + var tw = s.initial_weight || 0, sw = s.spool_weight || 0; + document.getElementById("det-v-tw").textContent = tw + " g"; + document.getElementById("det-v-sw").textContent = sw + " g"; + document.getElementById("det-v-nw").textContent = Math.max(0, tw - sw) + " g"; + document.getElementById("det-v-param1").textContent = s.brand ? (s.brand + " " + (s.material_type||"") + " " + (s.series||"")) : "—"; + var alertMap = {0:"—", 10:"≦ 10g", 20:"≦ 20g", 30:"≦ 30g", 50:"≦ 50g"}; + document.getElementById("det-v-remain-alert").textContent = alertMap[s.remain_alert_pct] || "—"; + document.getElementById("det-v-dry-date").textContent = s.dry_date || "—"; + var dryMap = {0:"—", 7:"每周", 14:"每两周", 30:"每月", 60:"每两月"}; + document.getElementById("det-v-dry-reminder").textContent = dryMap[s.dry_reminder_days] || "—"; + var priceStr = "—"; + if (s.unit_price) { + var csym = CURRENCY_SYMBOLS[s.price_currency] || ""; + var cname = s.price_currency ? s.price_currency + " (" + csym + ")" : ""; + priceStr = cname + " " + s.unit_price.toFixed(2) + "/kg"; + } + document.getElementById("det-v-price").textContent = priceStr; + document.getElementById("det-v-note").textContent = s.note || "—"; + + updateDetailNav(); + switchDetailTab("info"); + document.getElementById("detail-overlay").style.display = "flex"; +} + +function closeDetail() { + document.getElementById("detail-overlay").style.display = "none"; + g_detail_spool_id = null; +} + +function updateDetailNav() { + var list = getFilteredSpools(); + var idx = -1; + for (var i = 0; i < list.length; i++) { + if (list[i].spool_id === g_detail_spool_id) { idx = i; break; } + } + document.getElementById("det-prev").disabled = idx <= 0; + document.getElementById("det-next").disabled = idx < 0 || idx >= list.length - 1; +} + +function navigateDetail(dir) { + var list = getFilteredSpools(); + var idx = -1; + for (var i = 0; i < list.length; i++) { + if (list[i].spool_id === g_detail_spool_id) { idx = i; break; } + } + var next = idx + dir; + if (next >= 0 && next < list.length) { + openDetail(list[next].spool_id); + } +} + +function switchDetailTab(tab) { + document.querySelectorAll(".detail-tab").forEach(function(t) { + t.classList.toggle("active", t.getAttribute("data-dtab") === tab); + }); + document.getElementById("dtab-info").style.display = tab === "info" ? "block" : "none"; + document.getElementById("dtab-usage").style.display = tab === "usage" ? "block" : "none"; +} + + +/* ===== AMS Section ===== */ +function buildSmallSpoolSvg(color) { + var c = color || "#888"; + return '' + + '' + + '' + + '' + + '' + + '' + + ''; +} + +function buildAmsUnitIcon(amsUnit, isActive) { + var trays = amsUnit.trays || []; + var colors = trays.map(function(t) { return (t.is_exists && t.color) ? t.color : "rgba(255,255,255,0.1)"; }); + while (colors.length < 4) colors.push("rgba(255,255,255,0.1)"); + return '' + + '' + + '' + + '' + + '' + + '' + + ''; +} + +function renderAmsSection() { + var units = (g_ams_data && g_ams_data.ams_units) || []; + if (units.length === 0) { + document.getElementById("ams-unit-icons").innerHTML = ""; + document.getElementById("ams-slots").innerHTML = + '
该设备未识别到 AMS
'; + document.getElementById("dialog-body").style.display = "none"; + return; + } + + if (!g_ams_selected_unit || !units.find(function(u) { return u.ams_id === g_ams_selected_unit; })) { + g_ams_selected_unit = units[0].ams_id; + } + + var iconContainer = document.getElementById("ams-unit-icons"); + iconContainer.innerHTML = ""; + units.forEach(function(u) { + var btn = document.createElement("button"); + btn.className = "ams-unit-btn" + (u.ams_id === g_ams_selected_unit ? " active" : ""); + btn.title = "AMS " + (parseInt(u.ams_id) + 1); + btn.innerHTML = buildAmsUnitIcon(u, u.ams_id === g_ams_selected_unit); + btn.addEventListener("click", function() { + g_ams_selected_unit = u.ams_id; + g_ams_selected_slot = null; + renderAmsSection(); + document.getElementById("dialog-body").style.display = "none"; + }); + iconContainer.appendChild(btn); + }); + + var currentUnit = units.find(function(u) { return u.ams_id === g_ams_selected_unit; }); + renderAmsSlots(currentUnit); +} + +function renderAmsSlots(amsUnit) { + var container = document.getElementById("ams-slots"); + container.innerHTML = ""; + if (!amsUnit) return; + + var trays = amsUnit.trays || []; + var slotLabels = ["A1","A2","A3","A4"]; + + trays.forEach(function(tray, i) { + var div = document.createElement("div"); + var label = slotLabels[i] || ("A" + (i+1)); + var isSelected = g_ams_selected_slot && g_ams_selected_slot.slot_id === tray.slot_id && g_ams_selected_slot.ams_id === amsUnit.ams_id; + + if (tray.is_exists) { + div.className = "ams-slot" + (isSelected ? " active" : ""); + var colorDot = ''; + div.innerHTML = + '
' + label + '
' + + '
' + + '
' + buildSmallSpoolSvg(tray.color) + '
' + + '
' + + '
' + colorDot + esc(tray.fila_type || "—") + '
' + + '
' + esc(tray.weight ? tray.weight + "g" : "—") + '
' + + '
' + + '
'; + + div.addEventListener("click", function() { + g_ams_selected_slot = { + ams_id: amsUnit.ams_id, + slot_id: tray.slot_id, + tray: tray + }; + renderAmsSlots(amsUnit); + fillFormFromAms(tray); + }); + } else { + div.className = "ams-slot empty-slot"; + div.innerHTML = + '
' + label + '
' + + '
' + + '
' + buildSmallSpoolSvg("#555") + '
' + + '
' + + '
'; + } + container.appendChild(div); + }); +} + +function fillFormFromAms(tray) { + document.getElementById("dialog-body").style.display = "block"; + var hasUuid = !!(tray.tag_uid && tray.tag_uid.length > 0); + + var brandName = tray.sub_brands || ""; + var fullType = tray.fila_type || ""; + + populateDropdowns(); + setVal("form-brand", brandName); + populateTypeDropdown(); + + var typeEl = document.getElementById("form-type"); + var matchedType = ""; + var seriesRemainder = ""; + for (var i = 0; i < typeEl.options.length; i++) { + var opt = typeEl.options[i].value; + if (!opt) continue; + if (fullType === opt) { matchedType = opt; break; } + if (fullType.indexOf(opt) === 0) { + if (!matchedType || opt.length > matchedType.length) { + matchedType = opt; + seriesRemainder = fullType.substring(opt.length).trim(); + } + } + } + setVal("form-type", matchedType); + populateSeriesDropdown(); + if (seriesRemainder) setVal("form-series", seriesRemainder); + + if (tray.color) { + document.getElementById("form-color-code").value = tray.color; + renderColorPalette(tray.color); + } + + var w = parseInt(tray.weight) || 1000; + setVal("form-total-weight", w); + setVal("form-spool-weight", 250); + calcNetWeight(); + + setAmsFormReadonly(hasUuid); + validateForm(); +} + +function setAmsFormReadonly(readonly) { + var fields = ["form-brand","form-type","form-series","form-color-name", + "form-total-weight","form-spool-weight"]; + fields.forEach(function(id) { + var el = document.getElementById(id); + if (!el) return; + if (readonly) { + el.setAttribute("disabled", "disabled"); + el.classList.add("ams-readonly"); + } else { + el.removeAttribute("disabled"); + el.classList.remove("ams-readonly"); + } + }); + var palette = document.getElementById("color-palette"); + if (palette) { + palette.style.pointerEvents = readonly ? "none" : ""; + palette.style.opacity = readonly ? "0.5" : ""; + } +} + +/* ===== Event bindings ===== */ +document.addEventListener("DOMContentLoaded", function() { + // Sidebar + document.querySelectorAll(".nav-item").forEach(function(el) { + el.addEventListener("click", function() { + g_view = this.getAttribute("data-view"); + document.querySelectorAll(".nav-item").forEach(function(n) { n.classList.remove("active"); }); + this.classList.add("active"); + g_selected_ids = {}; + document.getElementById("stats-view").style.display = (g_view === "stats") ? "" : "none"; + document.getElementById("list-view").style.display = (g_view === "stats") ? "none" : ""; + refresh(); + }); + }); + + // Tabs + document.querySelectorAll(".tab-pill").forEach(function(el) { + el.addEventListener("click", function() { + g_tab = this.getAttribute("data-tab"); + document.querySelectorAll(".tab-pill").forEach(function(t) { t.classList.remove("active"); }); + this.classList.add("active"); + refresh(); + }); + }); + + // Sort + document.querySelectorAll("th.sortable").forEach(function(th) { + th.addEventListener("click", function() { + var key = this.getAttribute("data-sort"); + if (g_sort_key === key) { g_sort_asc = !g_sort_asc; } + else { g_sort_key = key; g_sort_asc = true; } + document.querySelectorAll("th.sortable").forEach(function(h) { h.classList.remove("sort-asc","sort-desc"); }); + this.classList.add(g_sort_asc ? "sort-asc" : "sort-desc"); + refresh(); + }); + }); + + // Check all + document.getElementById("check-all").addEventListener("change", function() { + var checked = this.checked; + var rows = getFilteredSpools(); + g_selected_ids = {}; + if (checked) rows.forEach(function(s) { g_selected_ids[s.spool_id] = true; }); + refresh(); + }); + + // Row checkbox delegation + document.getElementById("spool-tbody").addEventListener("change", function(e) { + if (e.target.type === "checkbox") { + var id = e.target.getAttribute("data-id"); + if (e.target.checked) g_selected_ids[id] = true; + else delete g_selected_ids[id]; + e.target.closest("tr").classList.toggle("selected", e.target.checked); + updateBatchUI(); + } + }); + + // Batch delete + document.getElementById("btn-delete").addEventListener("click", function() { + var ids = Object.keys(g_selected_ids); + if (!ids.length) return; + if (confirm("确定删除选中的 " + ids.length + " 条记录?")) { + sendRequest("batch_remove", { spool_ids: ids }, onSpoolsUpdated); + g_selected_ids = {}; + } + }); + + // Search + document.getElementById("search-input").addEventListener("input", function() { refresh(); }); + + // Filter buttons + document.querySelectorAll(".filter-btn").forEach(function(btn) { + btn.addEventListener("click", function(e) { + e.stopPropagation(); + var key = this.getAttribute("data-filter"); + var dd = document.getElementById("filter-dropdown"); + if (dd.style.display === "block" && dd._filterKey === key) { + dd.style.display = "none"; return; + } + openFilterDropdown(this, key); + }); + }); + + // Filter dropdown item click + document.getElementById("filter-dropdown").addEventListener("click", function(e) { + var item = e.target.closest(".filter-dropdown-item"); + if (!item) return; + var val = item.getAttribute("data-val"); + var key = this._filterKey; + if (val) g_filters[key] = val; else delete g_filters[key]; + if (this._btn) this._btn.classList.toggle("active", !!val); + this.style.display = "none"; + refresh(); + }); + + // Close dropdown on outside click + document.addEventListener("click", function() { + document.getElementById("filter-dropdown").style.display = "none"; + }); + + // Group toggle + document.getElementById("btn-group").addEventListener("click", function() { + g_grouped = !g_grouped; + g_collapsed_groups = {}; + g_page = 1; + this.classList.toggle("btn-group-active", g_grouped); + refresh(); + }); + + // Pagination delegation + document.getElementById("pagination").addEventListener("click", function(e) { + var btn = e.target.closest(".page-btn"); + if (!btn || btn.disabled) return; + g_page = parseInt(btn.getAttribute("data-p")) || 1; + refresh(); + }); + document.getElementById("pagination").addEventListener("change", function(e) { + if (e.target.id === "page-size-sel") { + g_page_size = parseInt(e.target.value) || 50; + g_page = 1; + refresh(); + } + }); + + // Add button + document.getElementById("btn-add").addEventListener("click", function() { + g_editing_spool_id = null; + openDialog(null); + }); + + // Dialog + document.getElementById("dialog-close").addEventListener("click", closeDialog); + document.getElementById("dialog-cancel").addEventListener("click", closeDialog); + document.getElementById("dialog-confirm").addEventListener("click", submitDialog); + + // AMS device selector + document.getElementById("ams-device-select").addEventListener("change", function() { + var devId = this.value; + g_ams_selected_unit = null; + g_ams_selected_slot = null; + document.getElementById("ams-unit-icons").innerHTML = ""; + document.getElementById("ams-slots").innerHTML = + '
正在加载 AMS 数据…
'; + document.getElementById("dialog-body").style.display = "none"; + sendRequest("get_ams_data", { dev_id: devId }, onAmsDataResponse); + }); + + document.querySelectorAll(".dialog-tab").forEach(function(t) { + t.addEventListener("click", function() { switchDialogMode(this.getAttribute("data-mode")); }); + }); + + // Brand → Type → Series linkage + document.getElementById("form-brand").addEventListener("change", function() { + setVal("form-type", ""); + setVal("form-series", ""); + populateTypeDropdown(); + validateForm(); + }); + document.getElementById("form-type").addEventListener("change", function() { + setVal("form-series", ""); + populateSeriesDropdown(); + validateForm(); + }); + document.getElementById("form-series").addEventListener("change", function() { + validateForm(); + }); + + // Weight calc + document.getElementById("form-total-weight").addEventListener("input", calcNetWeight); + document.getElementById("form-spool-weight").addEventListener("input", calcNetWeight); + + // Note char count + document.getElementById("form-note").addEventListener("input", updateCharCount); + + // Quantity + document.getElementById("qty-minus").addEventListener("click", function() { + g_quantity = Math.max(1, g_quantity - 1); + document.getElementById("qty-value").textContent = g_quantity; + }); + document.getElementById("qty-plus").addEventListener("click", function() { + g_quantity = Math.min(99, g_quantity + 1); + document.getElementById("qty-value").textContent = g_quantity; + }); + + // Advanced toggle + document.getElementById("advanced-toggle").addEventListener("click", function() { + var sec = document.getElementById("advanced-section"); + var open = sec.style.display !== "none"; + sec.style.display = open ? "none" : "block"; + this.classList.toggle("open", !open); + }); + + // Detail dialog + document.getElementById("det-close").addEventListener("click", closeDetail); + document.getElementById("det-prev").addEventListener("click", function() { navigateDetail(-1); }); + document.getElementById("det-next").addEventListener("click", function() { navigateDetail(1); }); + document.querySelectorAll(".detail-tab").forEach(function(t) { + t.addEventListener("click", function() { switchDetailTab(this.getAttribute("data-dtab")); }); + }); + document.getElementById("det-edit-btn").addEventListener("click", function() { + if (!g_detail_spool_id) return; + var s = g_spools.find(function(x) { return x.spool_id === g_detail_spool_id; }); + closeDetail(); + if (s) { + g_editing_spool_id = s.spool_id; + openDialog(s); + } + }); + + // Reminder tabs + document.querySelectorAll(".reminder-tab").forEach(function(t) { + t.addEventListener("click", function() { + document.querySelectorAll(".reminder-tab").forEach(function(r) { r.classList.remove("active"); }); + this.classList.add("active"); + renderReminderList(this.getAttribute("data-rtab")); + }); + }); + + // Heatmap month selector + var hmSel = document.getElementById("heatmap-month"); + if (hmSel) { + var now = new Date(); + for (var m = 0; m < 6; m++) { + var d = new Date(now.getFullYear(), now.getMonth() - m, 1); + var opt = document.createElement("option"); + opt.value = d.getFullYear() + "-" + String(d.getMonth()+1).padStart(2,"0"); + opt.textContent = d.getFullYear() + "/" + (d.getMonth()+1); + hmSel.appendChild(opt); + } + hmSel.addEventListener("change", function() { renderHeatmap(); }); + } + + // Init: single request, C++ responds with theme + spools + presets + sendRequest("init", {}, function(code, data) { + if (code !== 0) return; + var theme = (data && data.theme) || "dark"; + document.documentElement.dataset.theme = theme; + g_spools = (data && data.spools) || []; + g_preset_vendors = (data && data.presets && data.presets.vendors) || []; + refresh(); + }); +}); + +/* ===== Statistics ===== */ +function cssVar(name) { + return getComputedStyle(document.documentElement).getPropertyValue(name).trim(); +} +var PIE_COLORS = ["#8BC34A","#4CAF50","#009688","#3F51B5","#FF9800","#F44336","#9C27B0","#00BCD4","#FFC107","#795548"]; + +function renderStats() { + var spools = g_spools.filter(function(s) { return s.status !== "archived"; }); + var totalValue = 0, colorSet = {}; + spools.forEach(function(s) { + var nw = (s.initial_weight || 0) - (s.spool_weight || 0); + totalValue += (s.unit_price || 0) * Math.max(0, nw) / 1000; + if (s.color_name) colorSet[s.color_name] = true; + }); + document.getElementById("stat-total-value").textContent = "$ " + totalValue.toFixed(2); + document.getElementById("stat-total-count").textContent = spools.length; + document.getElementById("stat-color-count").textContent = Object.keys(colorSet).length; + + renderPieChart("pie-type", "legend-type", countBy(spools, "material_type"), null); + var colorData = countByColor(spools); + renderPieChart("pie-color", "legend-color", colorData, null); + renderReminderList("low"); + renderHeatmap(); + renderLineChart(); + renderBarChart(); +} + +function countByColor(arr) { + var map = {}; + arr.forEach(function(s) { + var name = s.color_name || "其他"; + if (!map[name]) map[name] = {count: 0, color: s.color_code || "#888"}; + map[name].count++; + }); + var result = []; + for (var k in map) result.push({name: k, value: map[k].count, color: map[k].color}); + result.sort(function(a, b) { return b.value - a.value; }); + return result; +} + +function countBy(arr, key) { + var map = {}; + arr.forEach(function(s) { + var v = s[key] || "其他"; + map[v] = (map[v] || 0) + 1; + }); + var result = []; + for (var k in map) result.push({name: k, value: map[k]}); + result.sort(function(a, b) { return b.value - a.value; }); + return result; +} + +function renderPieChart(canvasId, legendId, data) { + var canvas = document.getElementById(canvasId); + if (!canvas) return; + var ctx = canvas.getContext("2d"); + var w = canvas.width, h = canvas.height; + var cx = w/2, cy = h/2, r = Math.min(w,h)/2 - 8, ri = r * 0.55; + ctx.clearRect(0, 0, w, h); + var total = 0; + data.forEach(function(d) { total += d.value; }); + if (total === 0) return; + var angle = -Math.PI / 2; + data.forEach(function(d, i) { + var slice = (d.value / total) * Math.PI * 2; + ctx.beginPath(); + ctx.moveTo(cx + ri * Math.cos(angle), cy + ri * Math.sin(angle)); + ctx.arc(cx, cy, r, angle, angle + slice); + ctx.arc(cx, cy, ri, angle + slice, angle, true); + ctx.closePath(); + ctx.fillStyle = d.color || PIE_COLORS[i % PIE_COLORS.length]; + ctx.fill(); + d._color = ctx.fillStyle; + angle += slice; + }); + var legend = document.getElementById(legendId); + if (!legend) return; + legend.innerHTML = ""; + data.slice(0, 6).forEach(function(d) { + var pct = ((d.value / total) * 100).toFixed(1); + legend.innerHTML += '
'+esc(d.name)+''+pct+'%
'; + }); +} + +function renderReminderList(tab) { + var list = document.getElementById("reminder-list"); + if (!list) return; + var spools = g_spools.filter(function(s) { return s.status !== "archived"; }); + var filtered; + if (tab === "low") { + filtered = spools.filter(function(s) { return (s.remain_percent||0) > 0 && (s.remain_percent||0) <= 20; }); + } else if (tab === "dry") { + filtered = spools.filter(function(s) { + if (!s.dry_date || !s.dry_reminder_days) return false; + var d = new Date(s.dry_date); + d.setDate(d.getDate() + s.dry_reminder_days); + return d <= new Date(); + }); + } else { + filtered = spools.filter(function(s) { return (s.remain_percent||0) === 0; }); + } + if (filtered.length === 0) { + list.innerHTML = '
暂无提醒
'; + return; + } + list.innerHTML = ""; + filtered.forEach(function(s) { + var nameParts = (s.material_type||"") + (s.series ? " "+s.series : ""); + var item = document.createElement("div"); + item.className = "reminder-item"; + item.innerHTML = '
'+buildSpoolSvg(s.color_code)+'
' + + '
'+esc(nameParts||"—")+'
'+esc(s.color_name||"—")+' | '+(s.diameter||1.75)+' mm
'; + item.addEventListener("click", function() { openDetail(s.spool_id); }); + list.appendChild(item); + }); +} + +function renderHeatmap() { + var wrap = document.getElementById("heatmap-wrap"); + if (!wrap) return; + var sel = document.getElementById("heatmap-month"); + var parts = (sel ? sel.value : "").split("-"); + var year = parseInt(parts[0]) || new Date().getFullYear(); + var month = parseInt(parts[1]) || (new Date().getMonth() + 1); + var firstDay = new Date(year, month - 1, 1); + var daysInMonth = new Date(year, month, 0).getDate(); + var startDow = (firstDay.getDay() + 6) % 7; + var dayLabels = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]; + + var html = '
'; + dayLabels.forEach(function(d) { html += ''+d+''; }); + html += '
'; + for (var i = 0; i < startDow; i++) html += ''; + for (var d = 1; d <= daysInMonth; d++) { + var level = Math.floor(Math.random() * 5); + var cls = level > 0 ? " l"+level : ""; + html += '
'; + } + html += '
'; + wrap.innerHTML = html; +} + +function renderLineChart() { + var canvas = document.getElementById("chart-line"); + if (!canvas) return; + var ctx = canvas.getContext("2d"); + var w = canvas.width, h = canvas.height; + var pad = {top:20, right:20, bottom:30, left:40}; + ctx.clearRect(0, 0, w, h); + + var days = 7; + var data = []; + for (var i = 0; i < days; i++) { + data.push(Math.round(Math.random() * 150 + 20)); + } + var max = Math.max.apply(null, data) * 1.2; + var chartW = w - pad.left - pad.right, chartH = h - pad.top - pad.bottom; + + var gridColor = cssVar("--chart-grid"); + var labelColor = cssVar("--chart-text"); + ctx.strokeStyle = gridColor; + ctx.lineWidth = 1; + for (var i = 0; i <= 4; i++) { + var y = pad.top + (chartH / 4) * i; + ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(w - pad.right, y); ctx.stroke(); + ctx.fillStyle = labelColor; + ctx.font = "11px sans-serif"; + ctx.textAlign = "right"; + ctx.fillText(Math.round(max - (max/4)*i), pad.left - 6, y + 4); + } + + var now = new Date(); + ctx.textAlign = "center"; + ctx.fillStyle = labelColor; + data.forEach(function(v, i) { + var d = new Date(now.getTime() - (days-1-i)*86400000); + var x = pad.left + (chartW / (days-1)) * i; + ctx.fillText((d.getMonth()+1)+"/"+d.getDate(), x, h - 6); + }); + + ctx.beginPath(); + ctx.strokeStyle = "#50e81d"; + ctx.lineWidth = 2; + ctx.lineJoin = "round"; + data.forEach(function(v, i) { + var x = pad.left + (chartW / (days-1)) * i; + var y = pad.top + chartH - (v / max) * chartH; + if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); + }); + ctx.stroke(); +} + +function renderBarChart() { + var canvas = document.getElementById("chart-bar"); + if (!canvas) return; + var ctx = canvas.getContext("2d"); + var w = canvas.width, h = canvas.height; + var pad = {top:10, right:20, bottom:30, left:40}; + ctx.clearRect(0, 0, w, h); + + var days = 7; + var types = ["PLA","ABS","PETG"]; + var colors = ["#4CAF50","#FF9800","#2196F3"]; + var barData = []; + for (var i = 0; i < days; i++) { + var group = []; + types.forEach(function() { group.push(Math.round(Math.random() * 120 + 30)); }); + barData.push(group); + } + var max = 0; + barData.forEach(function(g) { g.forEach(function(v) { if (v > max) max = v; }); }); + max *= 1.2; + var chartW = w - pad.left - pad.right, chartH = h - pad.top - pad.bottom; + + var gridColor2 = cssVar("--chart-grid"); + var labelColor2 = cssVar("--chart-text"); + ctx.strokeStyle = gridColor2; + ctx.lineWidth = 1; + for (var i = 0; i <= 4; i++) { + var y = pad.top + (chartH / 4) * i; + ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(w - pad.right, y); ctx.stroke(); + ctx.fillStyle = labelColor2; + ctx.font = "11px sans-serif"; + ctx.textAlign = "right"; + ctx.fillText(Math.round(max - (max/4)*i), pad.left - 6, y + 4); + } + + var groupW = chartW / days; + var barW = Math.min(16, (groupW - 8) / types.length); + var now = new Date(); + ctx.textAlign = "center"; + barData.forEach(function(group, gi) { + var gx = pad.left + groupW * gi + groupW / 2; + var d = new Date(now.getTime() - (days-1-gi)*86400000); + ctx.fillStyle = labelColor2; + ctx.fillText((d.getMonth()+1)+"/"+d.getDate(), gx, h - 6); + var totalBarsW = barW * types.length + 2 * (types.length - 1); + var startX = gx - totalBarsW / 2; + group.forEach(function(v, bi) { + var barH = (v / max) * chartH; + var x = startX + bi * (barW + 2); + var y = pad.top + chartH - barH; + ctx.fillStyle = colors[bi % colors.length]; + ctx.beginPath(); + ctx.roundRect(x, y, barW, barH, [2, 2, 0, 0]); + ctx.fill(); + }); + }); +} diff --git a/resources/web/flush/NozzleListTable.html b/resources/web/flush/NozzleListTable.html index cfe467f4e3..6c7cd29c7d 100644 --- a/resources/web/flush/NozzleListTable.html +++ b/resources/web/flush/NozzleListTable.html @@ -9,11 +9,21 @@ margin: 0; padding: 0; height: 100%; - overflow: hidden; background-color: #ffffff; transition: background-color 0.3s ease; } + html { + overflow: hidden; + } + + body { + /* Let the user scroll when the webview is too short for the content + (e.g. extreme Windows Accessibility text-size settings). */ + overflow-y: auto; + overflow-x: auto; + } + table { border-collapse: collapse; width: 100%; @@ -175,8 +185,11 @@ function sendLayoutMessage() { const table = document.querySelector('table'); - const tableWidth = table.offsetWidth; // 表格可见宽度 - const tableHeight = table.offsetHeight; // 表格可见高度 + // getBoundingClientRect() reflects CSS `zoom`, so the reported size + // matches the visible pixels the webview needs on the C++ side. + const rect = table.getBoundingClientRect(); + const tableWidth = Math.ceil(rect.width); + const tableHeight = Math.ceil(rect.height); const layoutMsg = JSON.stringify({ msg: 'layout', diff --git a/resources/web/model/model.js b/resources/web/model/model.js index 89a293ca93..39358c586e 100644 --- a/resources/web/model/model.js +++ b/resources/web/model/model.js @@ -427,7 +427,8 @@ function ConstructFileHtml( ID, pItem ) { let fTotal=pItem.length; - let strHtml=''; + let $board = $('#'+ID+' .FileListBoard'); + $board.empty(); for( let f=0;f'+ - '
'+ - '
'+tName+'
'+ - '
'+ - '
'+ - ''; + let $fileItem = $('
').addClass('FileItem'); + let $iconWrap = $('
').addClass(strClass); + $iconWrap.append($('').attr('src', ImgPath)); + let $fileText = $('
').addClass('FileText'); + $fileText.append($('
').addClass('FileName').text(tName)); + let $fileMenu = $('
').addClass('FileMenu'); + $fileMenu.append($('').attr('src', 'img/s.svg')); + $fileMenu.on('click', function() { + OnClickOpenFile(tPath); + }); + $fileItem.append($iconWrap); + $fileItem.append($fileText); + $fileItem.append($fileMenu); + $board.append($fileItem); } else { ImgID++; let TmpImgID="AF"+ImgID; - strHtml+='
'+ - '
'+ - '
'+ - '
'+tName+'
'+ - '
'+ - '
'+ - '
'; + let $fileItem = $('
').addClass('FileItem'); + let $iconWrap = $('
').addClass(strClass); + $iconWrap.append($('').attr('id', TmpImgID).attr('src', ImgPath)); + let $fileText = $('
').addClass('FileText'); + $fileText.append($('
').addClass('FileName').text(tName)); + let $fileMenu = $('
').addClass('FileMenu'); + $fileMenu.append($('').attr('src', 'img/s.svg')); + $fileMenu.on('click', function() { + OnClickOpenImage(TmpImgID); + }); + $fileItem.append($iconWrap); + $fileItem.append($fileText); + $fileItem.append($fileMenu); + $board.append($fileItem); } } - $('#'+ID+' .FileListBoard').html(strHtml); - if( fTotal>0 ) $('#'+ID).show(); } diff --git a/resources/web/model_new/index.js b/resources/web/model_new/index.js index 7ada78f386..5f6f3661c0 100644 --- a/resources/web/model_new/index.js +++ b/resources/web/model_new/index.js @@ -279,8 +279,8 @@ function isImageFileTail(fileTail) { function ConstructFileHtml( ID, pItem ){ let fTotal=pItem.length; - - let strHtml=''; + let $container = $("#"+ID); + $container.empty(); for( let f=0;f').addClass('attachment'); + if (isImageFile && tPath) { + $attachment.addClass('attachment-image'); + } if (tPath) { - onclick = ' onClick="OnClickOpenFile(\''+tPath+'\')"'; + $attachment.on('click', function() { + OnClickOpenFile(tPath); + }); } + + let $img = $('').attr('alt', tName); if (isImageFile && tPath) { - strHtml += '
' + tName + '' + tName + '
'; + $img.addClass('attachment-thumb').attr('src', tPath); } else { - strHtml += '
' + tName + '' + tName + '
'; + $img.attr('src', ImgPath); } + + $attachment.append($img); + $attachment.append(document.createTextNode(tName)); + $container.append($attachment); } - $("#"+ID).html( strHtml ); - if( fTotal>0 ) {$("#"+ID).show();} + if( fTotal>0 ) {$container.show();} } function OnClickOpenFile( strFullPath ) diff --git a/resources/web/model_new/js/editor.js b/resources/web/model_new/js/editor.js index 37a7d92cf8..8daaa640ec 100644 --- a/resources/web/model_new/js/editor.js +++ b/resources/web/model_new/js/editor.js @@ -413,11 +413,12 @@ function addAccessoryBtnListener() { });1 } function setAccessories(id, accessoriesList) { - let updateHtml = ""; + const $container = $(`#${id}`); + $container.empty(); if (accessoriesList.length > 0) { - $(`#${id}`).prev().show(); + $container.prev().show(); }else { - $(`#${id}`).prev().hide(); + $container.prev().hide(); } for (let i = 0; i < accessoriesList.length; i++) { let acc_filepath = accessoriesList[i].filepath; @@ -428,23 +429,23 @@ function setAccessories(id, accessoriesList) { type = getFileType(acc_filepath); } let iconPath = `img/icon_${type}.svg`; - let html = `
${decodeURIComponent(accessoriesList[i].filename)}
`; - updateHtml += html; + let $attachment = $('
').addClass('attachment').attr('data-index', i); + $attachment.data('path', acc_filepath || ''); + $attachment.append($('').addClass('attachment-icon').attr('src', iconPath)); + $attachment.append(document.createTextNode(decodeURIComponent(accessoriesList[i].filename))); + $attachment.append($('').addClass('attachment-delete').attr('src', 'img/del.svg')); + $container.append($attachment); } - $(`#${id}`).html(updateHtml); - $(`#${id}`).children('.attachment').each(function(idx) { - $(this).data('path', accessoriesList[idx]?.filepath || ''); - }); - $(`#${id}`).prev().children('label').text(accessoriesList.length); - $(`#${id}`).off('click', '.attachment-delete'); - $(`#${id}`).on('click', '.attachment-delete', function (event) { + $container.prev().children('label').text(accessoriesList.length); + $container.off('click', '.attachment-delete'); + $container.on('click', '.attachment-delete', function (event) { event.stopPropagation(); let index = parseInt($(this).parent().data('index')); removeAccessoryAt(index, accessoriesList); setAccessories(id, accessoriesList); }); - $(`#${id}`).off('click', '.attachment'); - $(`#${id}`).on('click', '.attachment', function (event) { + $container.off('click', '.attachment'); + $container.on('click', '.attachment', function (event) { if ($(event.target).closest('.attachment-delete').length) return; const path = $(this).data('path'); OnClickOpenFile(event, path); diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 48a7703c03..6c66134a9d 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -1329,6 +1329,83 @@ static int construct_assemble_list(std::vector &assemble_ return ret; } +// For estimate_mode: given a source filament preset name (e.g. "Bambu PLA Basic @BBL P1S 0.4 nozzle") +// and the new machine's BBL tag (e.g. "X2D 0.4 nozzle"), construct the target filament preset name +// (e.g. "Bambu PLA Basic @BBL X2D 0.4 nozzle") and verify it exists in filament_full_dir. +// Returns the resolved filament preset name, or empty string if not found. +// Resolution order: +// 1. Exact name match: " @BBL " +// 2. Scan filament_full_dir for any file starting with " @" whose compatible_printers contains new_printer_system_name +// 3. Fall back to the machine's default_filament_preset +static std::string estimate_filament_preset_name( + const std::string& src_filament_name, + const std::string& new_machine_bbl_tag, + const std::string& filament_full_dir, + const std::string& new_printer_system_name, + const std::string& default_filament_preset) +{ + // Extract base filament name by stripping "@BBL ..." or "@base" suffix + std::string base_name = src_filament_name; + auto at_pos = base_name.find(" @"); + if (at_pos != std::string::npos) + base_name = base_name.substr(0, at_pos); + + BOOST_LOG_TRIVIAL(info) << boost::format( + "estimate_filament_preset_name: src_filament_name %1%, base %2%, new_machine_bbl_tag %3%, new_printer_system_name %4%, default_filament_preset %5%") % src_filament_name %base_name %new_machine_bbl_tag %new_printer_system_name %default_filament_preset; + + // Lambda: check whether a filament json file's compatible_printers contains new_printer_system_name + auto is_compatible_with_printer = [&](const std::string& file_path) -> bool { + boost::nowide::ifstream ifs(file_path); + if (!ifs.is_open()) return false; + try { + nlohmann::json j; + ifs >> j; + if (j.contains("compatible_printers") && j["compatible_printers"].is_array()) { + for (const auto& cp : j["compatible_printers"]) { + if (cp.is_string() && cp.get() == new_printer_system_name) + return true; + } + } + } catch (...) {} + return false; + }; + + // 1. Try exact name match: " @BBL ", and verify compatible_printers + std::string target_name = base_name + " @BBL " + new_machine_bbl_tag; + std::string target_path = filament_full_dir + target_name + ".json"; + if (boost::filesystem::exists(target_path) && is_compatible_with_printer(target_path)) + return target_name; + + // 2. Scan filament_full_dir for files starting with " @" and check compatible_printers + std::string prefix = base_name + " @"; + try { + for (const auto& entry : boost::filesystem::directory_iterator(filament_full_dir)) { + if (!boost::filesystem::is_regular_file(entry)) continue; + std::string fname = entry.path().stem().string(); // filename without .json + if (fname.size() < prefix.size() || fname.compare(0, prefix.size(), prefix) != 0) continue; + if (is_compatible_with_printer(entry.path().string())) { + BOOST_LOG_TRIVIAL(info) << boost::format( + "estimate_filament_preset_name: '%1%' compatible with '%2%', using it") + % fname % new_printer_system_name; + return fname; + } + } + } catch (const boost::filesystem::filesystem_error& e) { + BOOST_LOG_TRIVIAL(warning) << boost::format( + "estimate_filament_preset_name: error scanning filament_full_dir: %1%") % e.what(); + } + + // 3. Fallback: use the machine's default filament preset directly + if (!default_filament_preset.empty() && + boost::filesystem::exists(filament_full_dir + default_filament_preset + ".json")) + return default_filament_preset; + + BOOST_LOG_TRIVIAL(warning) << boost::format( + "estimate_filament_preset_name: no match for '%1%' with machine '%2%', skipping") + % base_name % new_printer_system_name; + return ""; +} + static void load_downward_settings_list_from_config(std::string config_file, std::string printer_name, std::string printer_model, std::vector& downward_settings) { std::map printer_params; @@ -1567,7 +1644,7 @@ int CLI::run(int argc, char **argv) std::vector plate_obj_size_infos; //int arrange_option; int plate_to_slice = 0, filament_count = 0, duplicate_count = 0, real_duplicate_count = 0, current_extruder_count = 1, new_extruder_count = 1, current_printer_variant_count = 1, current_print_variant_count = 1, new_printer_variant_count = 1; - bool first_file = true, is_bbl_3mf = false, need_arrange = true, has_thumbnails = false, up_config_to_date = false, normative_check = true, duplicate_single_object = false, use_first_fila_as_default = false, minimum_save = false, enable_timelapse = false, has_support = false; + bool first_file = true, is_bbl_3mf = false, need_arrange = true, has_thumbnails = false, up_config_to_date = false, normative_check = true, duplicate_single_object = false, use_first_fila_as_default = false, minimum_save = false, enable_timelapse = false, has_support = false, estimate_mode = false; bool allow_rotations = true, skip_modified_gcodes = false, avoid_extrusion_cali_region = false, skip_useless_pick = false, allow_newer_file = false, current_is_multi_extruder = false, new_is_multi_extruder = false, allow_mix_temp = false, enable_wrapping_detect = false; Semver file_version; Slic3r::GUI::Camera::ViewAngleType camera_view = Slic3r::GUI::Camera::ViewAngleType::Iso; @@ -1636,6 +1713,10 @@ int CLI::run(int argc, char **argv) if (allow_mix_temp_option) allow_mix_temp = allow_mix_temp_option->value; + ConfigOptionBool* estimate_mode_option = m_config.option("estimate_mode"); + if (estimate_mode_option) + estimate_mode = estimate_mode_option->value; + ConfigOptionInt* camera_view_option = m_config.option("camera_view"); if (camera_view_option) camera_view = (Slic3r::GUI::Camera::ViewAngleType)(camera_view_option->value); @@ -2288,6 +2369,44 @@ int CLI::run(int argc, char **argv) } } + // estimate_mode: auto-fill load_filaments with resolved paths from filament_full/ for the new machine + if (estimate_mode && load_filaments.empty()) { + // Derive the new machine's BBL tag and default preset from its default_filament_profile + // e.g. "Bambu PLA Basic @BBL X2D 0.4 nozzle" -> tag is "X2D 0.4 nozzle" + std::string new_machine_bbl_tag; + std::string default_filament_preset; + auto default_fp_opt = load_machine_config.option("default_filament_profile"); + if (default_fp_opt && !default_fp_opt->values.empty()) { + default_filament_preset = default_fp_opt->values[0]; + auto tag_pos = default_filament_preset.find(" @BBL "); + if (tag_pos != std::string::npos) + new_machine_bbl_tag = default_filament_preset.substr(tag_pos + 6); // skip " @BBL " + } + if (new_machine_bbl_tag.empty()) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" %1%: estimate_mode: cannot determine BBL machine tag from default_filament_profile") % __LINE__; + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); + flush_and_exit(CLI_INVALID_PARAMS); + } + + std::string filament_full_dir = resources_dir() + "/profiles/BBL/filament_full/"; + auto& filaments_opt = m_config.option("load_filaments", true)->values; + for (int index = 0; index < (int)converted_filaments_system_name.size(); index++) { + std::string preset_name = estimate_filament_preset_name( + converted_filaments_system_name[index], new_machine_bbl_tag, filament_full_dir, new_printer_system_name, default_filament_preset); + if (preset_name.empty()) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":%1%, estimate_mode: no filament preset found for slot %2% (%3%), skipping") + % __LINE__ % index % converted_filaments_system_name[index]; + filaments_opt.push_back(""); // keep slot count aligned + } else { + filaments_opt.push_back(filament_full_dir + preset_name + ".json"); + BOOST_LOG_TRIVIAL(info) << boost::format("estimate_mode: slot %1% -> %2%") % index % preset_name; + } + } + // ensure empty slots are filled with the first valid filament preset, + // so load_filaments_config/index stay aligned with slot indices + use_first_fila_as_default = true; + } + //load filaments files int load_filament_count = load_filaments.size(); std::vector load_filaments_index; @@ -2853,6 +2972,13 @@ int CLI::run(int argc, char **argv) record_exit_reson(outfile_dir, CLI_PROCESS_NOT_COMPATIBLE, 0, cli_errors[CLI_PROCESS_NOT_COMPATIBLE], sliced_info); flush_and_exit(CLI_PROCESS_NOT_COMPATIBLE); } + + if (estimate_mode && (new_printer_name.empty() || current_printer_name.empty() || (new_printer_name == current_printer_name))) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" %1%: estimate_mode requires a machine switch via --load_settings") % __LINE__; + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); + flush_and_exit(CLI_INVALID_PARAMS); + } + sliced_info.upward_machines = upward_compatible_printers; //create project embedded preset if needed @@ -3847,7 +3973,45 @@ int CLI::run(int argc, char **argv) m_extra_config.set_key_value("enable_filament_dynamic_map", new ConfigOptionBool(false)); if (!m_extra_config.has("has_filament_switcher")) m_extra_config.set_key_value("has_filament_switcher", new ConfigOptionBool(false)); + + // estimate_mode: auto-fill extruder state and material mapping params after machine switch + if (estimate_mode) { + // Validate or set filament_map_mode + if (m_extra_config.has("filament_map_mode")) { + auto opt_fmm = dynamic_cast*>(m_extra_config.option("filament_map_mode")); + if (!opt_fmm || opt_fmm->value != fmmAutoForFlush) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" %1%: estimate_mode requires filament_map_mode to be AutoForFlush if explicitly set") % __LINE__; + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); + flush_and_exit(CLI_INVALID_PARAMS); + } + } else if (new_is_multi_extruder || support_multi_nozzle) { + m_extra_config.option>("filament_map_mode", true)->value = fmmAutoForFlush; + } + + // Multi-extruder machine (X2D / H2D class): fill nozzle_volume_type + // extruder_ams_count and extruder_filament_info are filled per-plate in the slicing loop + if (new_is_multi_extruder || support_multi_nozzle) { + // nozzle_volume_type: all extruders set to standard + ConfigOptionEnumsGeneric* opt_nvt = m_extra_config.option("nozzle_volume_type", true); + opt_nvt->values.assign(new_extruder_count, nvtStandard); + } + + // Multi-sub-nozzle machine (H2C class): fill extruder_nozzle_count, extruder_nozzle_volume_type + // extruder_ams_count and extruder_filament_info are filled per-plate in the slicing loop + if (support_multi_nozzle) { + // extruder_nozzle_count: set from extruder_max_nozzle_count + m_extra_config.option("extruder_nozzle_count", true)->values = std::vector(extruder_max_nozzle_count.begin(), extruder_max_nozzle_count.end()); + + // extruder_nozzle_volume_type: all sub-nozzles set to standard + int total_sub_nozzles = 0; + for (int v : extruder_max_nozzle_count) + total_sub_nozzles += (v > 0 ? v : 1); + m_extra_config.option("extruder_nozzle_volume_type", true)->values.assign(total_sub_nozzles, nvtStandard); + } + } + m_print_config.apply(m_extra_config, true); + // Normalizing after importing the 3MFs / AMFs m_print_config.normalize_fdm(); @@ -6403,7 +6567,8 @@ int CLI::run(int argc, char **argv) flush_and_exit(CLI_ONLY_ONE_TPU_SUPPORTED); } - if (new_extruder_count > 1) { + if (new_is_multi_extruder || support_multi_nozzle) { + //if (new_extruder_count > 1) { std::vector> unprintable_filament_vec; for (const std::set& filamnt_ids : unprintable_filament_ids) { unprintable_filament_vec.emplace_back(std::vector(filamnt_ids.begin(), filamnt_ids.end())); @@ -6455,6 +6620,52 @@ int CLI::run(int argc, char **argv) } } + // Common: sanitize filament_map -1 values for all modes + std::vector filament_maps; + if (m_extra_config.option("filament_map")) { + filament_maps = m_extra_config.option("filament_map")->values; + int default_value = -1; + bool has_invalid_value = false; + for (int f_index = 0; f_index < filament_maps.size(); f_index++) + { + if (filament_maps[f_index] != -1) + { + if (default_value == -1) + default_value = filament_maps[f_index]; + else + continue; + } + else + has_invalid_value = true; + + if (has_invalid_value && (default_value != -1)) + break; + } + BOOST_LOG_TRIVIAL(info) << boost::format("%1% :filament map default_value %2%, has_invalid_value %3% ") % __LINE__ %default_value %has_invalid_value; + + if (has_invalid_value) + { + for (int f_index = 0; f_index < filament_maps.size(); f_index++) + { + if (filament_maps[f_index] == -1) + { + if (default_value != -1) { + filament_maps[f_index] = default_value; + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% : set filament_map of filament %2% to first value %3%.")% (index + 1) %(f_index+1) %default_value; + } + else { + filament_maps[f_index] = 1; + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% : set filament_map of filament %2% to default value 1.")% (index + 1) %(f_index+1); + } + } + } + m_extra_config.option("filament_map")->values = filament_maps; + } + part_plate->set_filament_maps(filament_maps); + } + else + filament_maps = part_plate->get_real_filament_maps(m_print_config); + if (is_auto_filament_map_mode(mode)) { std::vector conflict_filament_vector; for (int index = 0; index < new_extruder_count; index++) @@ -6488,52 +6699,8 @@ int CLI::run(int argc, char **argv) } } else { - std::vector filament_maps; std::vector filament_nozzle_maps; std::vector filament_volume_maps; // TODO: print with multi volume types - if (m_extra_config.option("filament_map")) { - filament_maps = m_extra_config.option("filament_map")->values; - int default_value = -1; - bool has_invalid_value = false; - for (int f_index = 0; f_index < filament_maps.size(); f_index++) - { - if (filament_maps[f_index] != -1) - { - if (default_value == -1) - default_value = filament_maps[f_index]; - else - continue; - } - else - has_invalid_value = true; - - if (has_invalid_value && (default_value != -1)) - break; - } - BOOST_LOG_TRIVIAL(info) << boost::format("%1% :filament map default_value %2%, has_invalid_value %3% ") % __LINE__ %default_value %has_invalid_value; - - if (has_invalid_value) - { - for (int f_index = 0; f_index < filament_maps.size(); f_index++) - { - if (filament_maps[f_index] == -1) - { - if (default_value != -1) { - filament_maps[f_index] = default_value; - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% : set filament_map of filament %2% to first value %3%.")% (index + 1) %(f_index+1) %default_value; - } - else { - filament_maps[f_index] = 1; - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% : set filament_map of filament %2% to default value 1.")% (index + 1) %(f_index+1); - } - } - } - m_extra_config.option("filament_map")->values = filament_maps; - } - part_plate->set_filament_maps(filament_maps); - } - else - filament_maps = part_plate->get_real_filament_maps(m_print_config); if (support_multi_nozzle && (mode == fmmManual || mode == fmmNozzleManual) && (plate_to_slice != 0)) { /* @@ -6671,10 +6838,12 @@ int CLI::run(int argc, char **argv) const ConfigOptionStrings* filament_type = dynamic_cast(m_print_config.option("filament_type")); std::vector types = filament_type ? filament_type->vserialize() : std::vector{"PLA"}; + int estimate_slots = estimate_mode ? 8 : 4; + std::string estimate_ams_str = estimate_mode ? "1#0|4#2" : "1#0|4#1"; for (int e_index = 0; e_index < new_extruder_count; e_index++) { - extruder_ams_count[e_index] = "1#0|4#1"; - for (int color_index = 0; color_index < 4; color_index++) + extruder_ams_count[e_index] = estimate_ams_str; + for (int color_index = 0; color_index < estimate_slots; color_index++) { DynamicPrintConfig temp_config; std::vector temp_colors(1, "#FFFFFFFF"); diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index ee57116399..963d0286a1 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -258,6 +258,11 @@ template class EdgeCache { inline Vertex coords(const ContourCache& cache, double distance) const { assert(distance >= .0 && distance <= 1.0); if (cache.distances.empty() || cache.emap.empty()) return Vertex{}; + // Zero-perimeter contour (all edges collapsed to one point): + // angleToXaxis() below would be atan2(0,0) = NaN and propagate + // into INT32_MIN UB. The only well-defined point on such a + // "circumference" is that single point itself. + if (cache.full_distance <= 0.0) return cache.emap.front().first(); if (distance > 1.0) distance = std::fmod(distance, 1.0); // distance is from 0.0 to 1.0, we scale it up to the full length of @@ -643,12 +648,40 @@ class _NofitPolyPlacer: public PlacerBoilerplate<_NofitPolyPlacer NaN + // -> INT32_MIN UB and the ~21km fly-away placement). if (innerNfp.area() == 0) { - return {innerNfp}; + auto innerBB = sl::boundingBox(innerNfp); + auto minCorner = innerBB.minCorner(); + auto maxCorner = innerBB.maxCorner(); + + // NFP collapsed to a single point. + if (getX(minCorner) == getX(maxCorner) && getY(minCorner) == getY(maxCorner)) { + for (const RawShape& nfp : nfps) { + if (sl::isInside(minCorner, nfp)) return {}; + } + return { innerNfp }; + } + + // NFP collapsed to an axis-aligned segment. + Slic3r::Polylines lines = Slic3r::diff_pl( + Slic3r::Polylines{ Slic3r::Polyline(minCorner, maxCorner) }, nfps); + Shapes NFP; + NFP.reserve(lines.size()); + for (Slic3r::Polyline& line : lines) { + if (line.points.size() < 2) continue; + if (line.points.front() == line.points.back()) continue; + Slic3r::ExPolygon expoly; + expoly.contour.points = std::move(line.points); + NFP.push_back(std::move(expoly)); + } + return NFP; } - Shapes finalNFP = nfp::subtract({ innerNfp }, nfps); - return finalNFP; + return nfp::subtract({ innerNfp }, nfps); } Shapes calcnfp(const RawShape &sliding, const Shapes &stationarys, const Box &bed, Lvl) @@ -669,8 +702,31 @@ class _NofitPolyPlacer: public PlacerBoilerplate<_NofitPolyPlacer 0) + ap.inflation = std::max(ap.inflation, params.min_inflation_floor); }); params.brim_skirt_distance = std::max(params.brim_skirt_distance, float(params.brim_max)); } diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index 52a325b421..235c3078a2 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -110,6 +110,14 @@ struct ArrangeParams { /// pair of items on the print bed in any direction. coord_t min_obj_distance = 0; + /// Optional lower bound for per-item inflation when min_obj_distance == 0. + /// 0 means disabled (legacy behavior). When > 0, update_selected_items_inflation + /// will clamp ap.inflation up to this value, guaranteeing a minimum visible gap + /// between copies even when brim/tree-support are also zero. + /// Set by callers that need a guaranteed gap (e.g. FillBedJob for "auto" distance); + /// other arrange paths leave it at 0 so legacy spacing is preserved. + coord_t min_inflation_floor = 0; + /// The accuracy of optimization. /// Goes from 0.0 to 1.0 and scales performance as well float accuracy = 1.f; diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 4bd7836b6a..9cea07b63a 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -1052,13 +1052,6 @@ static ExPolygons outer_inner_brim_area(const Print& print, } int extruder_nums = print.config().nozzle_diameter.values.size(); - std::vector extruder_unprintable_area; - if (extruder_nums == 1) - extruder_unprintable_area.emplace_back(Polygons{Model::getBedPolygon()}); - else { - extruder_unprintable_area = print.get_extruder_printable_polygons(); - } - std::vector filament_map = print.get_filament_maps(); if (print.has_wipe_tower() && !print.get_fake_wipe_tower().outer_wall.empty()) { ExPolygons expolyFromLines{}; @@ -1070,33 +1063,42 @@ static ExPolygons outer_inner_brim_area(const Print& print, expolygons_append(no_brim_area, expolyFromLines); } - std::vector extruder_no_brim_area_cache(extruder_nums, no_brim_area); - for (int extruder_id = 0; extruder_id < extruder_nums; ++extruder_id) { - auto bedPoly = extruder_unprintable_area[extruder_id]; - auto bedExPoly = diff_ex((offset(bedPoly, scale_(30.), jtRound, SCALED_RESOLUTION)), {bedPoly}); - if (!bedExPoly.empty()) { - extruder_no_brim_area_cache[extruder_id].push_back(bedExPoly.front()); + // Determine which extruders are actually used via group_result. + // If multiple extruders are used, clip brim to the shared printable area; + // if only one extruder is used, clip brim to that extruder's printable area. + // This avoids depending on filament_map which varies per-layer under dynamic map mode. + if (extruder_nums > 1) { + std::vector used_extruders; + auto group_result = print.get_nozzle_group_result(); + if (group_result) + used_extruders = group_result->get_used_extruders(); + + Polygons clip_printable; + if (used_extruders.size() > 1) { + clip_printable = print.get_extruder_shared_printable_polygon(); + } else if (used_extruders.size() == 1) { + auto extruder_printable_polys = print.get_extruder_printable_polygons(); + int eid = used_extruders.front(); + if (eid >= 0 && eid < (int)extruder_printable_polys.size()) + clip_printable = extruder_printable_polys[eid]; } - extruder_no_brim_area_cache[extruder_id] = offset2_ex(extruder_no_brim_area_cache[extruder_id], scaled_flow_width, -scaled_flow_width); // connect scattered small areas to prevent generating very small brims - } - for (const PrintObject* object : print.objects()) { - ExPolygons extruder_no_brim_area = no_brim_area; - auto iter = std::find_if(objPrintVec.begin(), objPrintVec.end(), [object](const std::pair& item) { - return item.first == object->id(); - }); - - if (iter != objPrintVec.end()) { - int extruder_id = filament_map[iter->second - 1] - 1; - extruder_no_brim_area = extruder_no_brim_area_cache[extruder_id]; + if (!clip_printable.empty()) { + auto bedExPoly = diff_ex(offset(clip_printable, scale_(30.), jtRound, SCALED_RESOLUTION), {clip_printable}); + if (!bedExPoly.empty()) { + no_brim_area.push_back(bedExPoly.front()); + } } + } + no_brim_area = offset2_ex(no_brim_area, scaled_flow_width, -scaled_flow_width); + for (const PrintObject* object : print.objects()) { if (brimAreaMap.find(object->id()) != brimAreaMap.end()) { - brimAreaMap[object->id()] = diff_ex(brimAreaMap[object->id()], extruder_no_brim_area); + brimAreaMap[object->id()] = diff_ex(brimAreaMap[object->id()], no_brim_area); } if (supportBrimAreaMap.find(object->id()) != supportBrimAreaMap.end()) - supportBrimAreaMap[object->id()] = diff_ex(supportBrimAreaMap[object->id()], extruder_no_brim_area); + supportBrimAreaMap[object->id()] = diff_ex(supportBrimAreaMap[object->id()], no_brim_area); } brim_area.clear(); diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index b4b0a0df5b..a79be2e5c8 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -45,7 +45,7 @@ namespace Slic3r { //static const std::string CONFIG_INHERITS_KEY = "inherits"; //static const std::string CONFIG_INSTANT_KEY = "instantiation"; -// Escape \n, \r and backslash +// Escape \n, \r, quotes and backslash std::string escape_string_cstyle(const std::string &str) { // Allocate a buffer twice the input string length, @@ -60,6 +60,9 @@ std::string escape_string_cstyle(const std::string &str) } else if (c == '\n') { (*outptr ++) = '\\'; (*outptr ++) = 'n'; + } else if (c == '"') { + (*outptr ++) = '\\'; + (*outptr ++) = '"'; } else if (c == '\\') { (*outptr ++) = '\\'; (*outptr ++) = '\\'; @@ -119,7 +122,7 @@ std::string escape_strings_cstyle(const std::vector &strs) return std::string(out.data(), outptr - out.data()); } -// Unescape \n, \r and backslash +// Unescape \n, \r, quotes and backslash bool unescape_string_cstyle(const std::string &str, std::string &str_out) { std::vector out(str.size(), 0); diff --git a/src/libslic3r/FilamentGroup.cpp b/src/libslic3r/FilamentGroup.cpp index d224a6235f..05079ee5c1 100644 --- a/src/libslic3r/FilamentGroup.cpp +++ b/src/libslic3r/FilamentGroup.cpp @@ -39,18 +39,23 @@ namespace Slic3r return filament_merge_map; } - static uint64_t fnv_hash_two_ints(const int a, const int b) + static uint64_t fnv_hash_nozzle(int volume_type, int is_right_extruder, int loaded_filament = -1) { constexpr uint64_t FNV_OFFSET_BASIS = 14695981039346656037ULL; constexpr uint64_t FNV_PRIME = 1099511628211ULL; constexpr uint64_t SALT_A = 0xA5A5A5A5A5A5A5A5ULL; constexpr uint64_t SALT_B = 0x5A5A5A5A5A5A5A5AULL; + constexpr uint64_t SALT_C = 0x3C3C3C3C3C3C3C3CULL; uint64_t h = FNV_OFFSET_BASIS; - h ^= static_cast(a) + SALT_A; + h ^= static_cast(volume_type) + SALT_A; h *= FNV_PRIME; - h ^= static_cast(b) + SALT_B; + h ^= static_cast(is_right_extruder) + SALT_B; h *= FNV_PRIME; + if (loaded_filament >= 0) { + h ^= static_cast(loaded_filament) + SALT_C; + h *= FNV_PRIME; + } return h; } @@ -85,10 +90,14 @@ namespace Slic3r const std::vector& used_filaments, const std::vector& used_filament_info, const std::vector>& machine_filament_info_, + const bool has_filament_switcher, const double color_threshold) { using namespace FlushPredict; + if (has_filament_switcher) + return filament_to_nozzles.size() ? filament_to_nozzles.front() : std::vector(); + const int fail_cost = 9999; // these code is to make we machine filament info size is 2 @@ -574,10 +583,12 @@ namespace Slic3r std::unordered_set, decltype(vector_hash), decltype(vector_equal)> group_set(0, vector_hash, vector_equal); std::vector group_hashs; - //2.Compute hash value based on nozzle type left/right extruder + high/standard flow + //2.Compute hash value based on nozzle type, extruder side, and loaded filament std::vector nozzles_hash(m_k); - for (auto nozzle : context.nozzle_info.nozzle_list) { - nozzles_hash[nozzle.group_id] = fnv_hash_two_ints(nozzle.volume_type, nozzle.group_id > 0); + for (const auto &nozzle : context.nozzle_info.nozzle_list) { + auto it = context.nozzle_info.nozzle_status.find(nozzle.group_id); + int loaded_filament = (it != context.nozzle_info.nozzle_status.end()) ? it->second : -1; + nozzles_hash[nozzle.group_id] = fnv_hash_nozzle(nozzle.volume_type, nozzle.group_id > 0, loaded_filament); } //3.Enumerate group assignments @@ -644,6 +655,21 @@ namespace Slic3r auto group_res = MultiNozzleUtils::LayeredNozzleGroupResult::create(labels, context.nozzle_info.nozzle_list, used_filaments); auto change_count = get_estimate_extruder_filament_change_count(*group_res); auto flush_volume = calc_cost(used_labels,std::vector(m_k,0),-1); + + //6.1 Add initial flush cost for nozzles that already have a filament loaded + for (const auto &[nozzle_id, slot_indices] : nozzles_filaments) { + auto it = context.nozzle_info.nozzle_status.find(nozzle_id); + if (it == context.nozzle_info.nozzle_status.end() || it->second == -1) + continue; + + int loaded_filament = it->second; + int extruder_id = context.nozzle_info.nozzle_list[nozzle_id].extruder_id; + double total_flush = 0; + for (int slot : slot_indices) + total_flush += context.model_info.flush_matrix[extruder_id][loaded_filament][used_filaments[slot]]; + flush_volume += total_flush / slot_indices.size(); + } + double time = change_count.first *context.speed_info.extruder_change_time + change_count.second *context.speed_info.filament_change_time; double score = evaluate_score(flush_volume, time, true); @@ -977,11 +1003,7 @@ namespace Slic3r catch (const FilamentGroupException& e) { } - auto merged_map = try_merge_filaments(); - rebuild_context(merged_map); - - std::vector filament_map = calc_filament_group_for_flush(cost); - return seperate_merged_filaments(filament_map, merged_map); + return calc_filament_group_for_flush(cost); } std::vector FilamentGroup::calc_filament_group_for_match(int* cost) @@ -1197,7 +1219,7 @@ namespace Slic3r used_filament_info.emplace_back(ctx.model_info.filament_info[f]); } - ret = select_best_group_for_ams(memoryed_maps, ctx.nozzle_info.nozzle_list, used_filaments, used_filament_info, ctx.machine_info.machine_filament_info); + ret = select_best_group_for_ams(memoryed_maps, ctx.nozzle_info.nozzle_list, used_filaments, used_filament_info, ctx.machine_info.machine_filament_info, ctx.group_info.has_filament_switcher); return ret; } @@ -1547,7 +1569,7 @@ namespace Slic3r std::vector used_filament_info; for (auto f : used_filaments) { used_filament_info.emplace_back(m_context.model_info.filament_info[f]); } - auto ret = select_best_group_for_ams(filament_to_nozzles, m_context.nozzle_info.nozzle_list, used_filaments, used_filament_info, m_context.machine_info.machine_filament_info); + auto ret = select_best_group_for_ams(filament_to_nozzles, m_context.nozzle_info.nozzle_list, used_filaments, used_filament_info, m_context.machine_info.machine_filament_info, m_context.group_info.has_filament_switcher); return ret; } diff --git a/src/libslic3r/FilamentGroup.hpp b/src/libslic3r/FilamentGroup.hpp index ae25a7b0ce..b3b9d16c59 100644 --- a/src/libslic3r/FilamentGroup.hpp +++ b/src/libslic3r/FilamentGroup.hpp @@ -86,6 +86,7 @@ namespace Slic3r FGMode mode; FGStrategy strategy; bool ignore_ext_filament; + bool has_filament_switcher = false; std::vector filament_volume_map; } group_info; @@ -115,6 +116,7 @@ namespace Slic3r const std::vector& used_filaments, const std::vector& used_filament_info, const std::vector>& machine_filament_info, + const bool has_filament_switcher = false, const double color_delta_threshold = 20); diff --git a/src/libslic3r/FilamentMixer.cpp b/src/libslic3r/FilamentMixer.cpp index 177983aa7a..5aa8bea0c7 100644 --- a/src/libslic3r/FilamentMixer.cpp +++ b/src/libslic3r/FilamentMixer.cpp @@ -1,12 +1,14 @@ #include "FilamentMixer.hpp" #include +#include #include #include #include #include #include "FilamentMixerModel.hpp" +#include "LocalesUtils.hpp" namespace Slic3r { namespace { @@ -105,6 +107,48 @@ std::string blend_color(const std::string& hex_a, const std::string& hex_b, floa return std::string(buf); } +std::string blend_color_multi(const std::vector &hex_colors, + const std::vector &weights) +{ + if (hex_colors.empty()) + return "#000000"; + if (hex_colors.size() == 1) { + unsigned char cr = 128, cg = 128, cb = 128; + parse_hex(hex_colors.front(), cr, cg, cb); + char buf[8]; + std::snprintf(buf, sizeof(buf), "#%02X%02X%02X", cr, cg, cb); + return std::string(buf); + } + + assert(hex_colors.size() == weights.size()); + + unsigned char r = 128, g = 128, b = 128; + int accumulated = 0; + + for (size_t i = 0; i < hex_colors.size() && i < weights.size(); ++i) { + if (weights[i] <= 0) + continue; + unsigned char cr = 128, cg = 128, cb = 128; + parse_hex(hex_colors[i], cr, cg, cb); + if (accumulated == 0) { + r = cr; g = cg; b = cb; + accumulated = weights[i]; + } else { + const int new_total = accumulated + weights[i]; + const float t = static_cast(weights[i]) / static_cast(new_total); + filament_mixer_lerp(r, g, b, cr, cg, cb, t, &r, &g, &b); + accumulated = new_total; + } + } + + if (accumulated == 0) + return "#000000"; + + char buf[8]; + std::snprintf(buf, sizeof(buf), "#%02X%02X%02X", r, g, b); + return std::string(buf); +} + std::vector parse_mixed_components(const std::string &str) { std::vector components; @@ -124,6 +168,7 @@ std::vector parse_mixed_components(const std::string &str) std::vector parse_mixed_ratios(const std::string &str, size_t n_components) { + CNumericLocalesSetter c_locale_setter; std::vector ratios; if (!str.empty()) { std::istringstream ss(str); diff --git a/src/libslic3r/FilamentMixer.hpp b/src/libslic3r/FilamentMixer.hpp index 06367a3eb1..870ceeaef7 100644 --- a/src/libslic3r/FilamentMixer.hpp +++ b/src/libslic3r/FilamentMixer.hpp @@ -25,6 +25,11 @@ void filament_mixer_lerp_linear_float(float r1, float g1, float b1, // Returns "#RRGGBB" string. std::string blend_color(const std::string& hex_a, const std::string& hex_b, float ratio_b); +// Blend N hex colors by integer weights using polynomial pigment mixing. +// Pairwise accumulation via filament_mixer_lerp. Returns "#RRGGBB". +std::string blend_color_multi(const std::vector &hex_colors, + const std::vector &weights); + // Parse comma-separated 1-based component IDs, e.g. "1,3" → {1, 3}. std::vector parse_mixed_components(const std::string &str); diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index f98d433c8d..76b3626c13 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -69,6 +69,7 @@ struct SurfaceFillParams float sparse_infill_speed = 0; float top_surface_speed = 0; float solid_infill_speed = 0; + float initial_layer_flow_ratio = 1.f; float infill_shift_step = 0;// param for cross zag float infill_rotate_step = 0; // param for zig zag to get cross texture bool symmetric_infill_y_axis = false; @@ -100,6 +101,7 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter()); RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, bridge); RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, extrusion_role); + RETURN_COMPARE_NON_EQUAL(initial_layer_flow_ratio); RETURN_COMPARE_NON_EQUAL(sparse_infill_speed); RETURN_COMPARE_NON_EQUAL(top_surface_speed); RETURN_COMPARE_NON_EQUAL(solid_infill_speed); @@ -128,6 +130,7 @@ struct SurfaceFillParams this->anchor_length_max == rhs.anchor_length_max && this->flow == rhs.flow && this->extrusion_role == rhs.extrusion_role && + this->initial_layer_flow_ratio == rhs.initial_layer_flow_ratio && this->sparse_infill_speed == rhs.sparse_infill_speed && this->top_surface_speed == rhs.top_surface_speed && this->solid_infill_speed == rhs.solid_infill_speed && @@ -200,6 +203,8 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p FlowRole extrusion_role = surface.is_top() ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill); bool is_bridge = layer.id() > 0 && surface.is_bridge(); params.extruder = layerm.region().extruder(extrusion_role); + if (layer.id() == 0) + params.initial_layer_flow_ratio = region_config.initial_layer_flow_ratio.value; params.pattern = region_config.sparse_infill_pattern.value; params.density = float(region_config.sparse_infill_density); params.multiline = int(region_config.fill_multiline); diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp index 4a8ed0fe53..f8f2690b23 100644 --- a/src/libslic3r/Format/STEP.cpp +++ b/src/libslic3r/Format/STEP.cpp @@ -6,6 +6,7 @@ #include "STEP.hpp" #include +#include #include #include #include @@ -26,6 +27,7 @@ #include "XCAFDoc_ShapeTool.hxx" #include "XCAFApp_Application.hxx" #include "TopoDS_Solid.hxx" +#include "TopoDS_Shell.hxx" #include "TopoDS_Compound.hxx" #include "TopoDS_Builder.hxx" #include "TopoDS.hxx" @@ -172,7 +174,8 @@ static void getNamedSolids(const TopLoc_Location& location, const Handle(XCAFDoc_ShapeTool) shapeTool, const TDF_Label label, std::vector& namedSolids, - bool isSplitCompound = false) { + bool isSplitCompound = false, + std::vector* unclosed_shells = nullptr) { TDF_Label referredLabel{label}; if (shapeTool->IsReference(label)) shapeTool->GetReferredShape(label, referredLabel); @@ -191,7 +194,7 @@ static void getNamedSolids(const TopLoc_Location& location, TDF_LabelSequence components; if (shapeTool->GetComponents(referredLabel, components)) { for (Standard_Integer compIndex = 1; compIndex <= components.Length(); ++compIndex) { - getNamedSolids(localLocation, fullName, id, shapeTool, components.Value(compIndex), namedSolids, isSplitCompound); + getNamedSolids(localLocation, fullName, id, shapeTool, components.Value(compIndex), namedSolids, isSplitCompound, unclosed_shells); } } else { TopoDS_Shape shape; @@ -220,6 +223,15 @@ static void getNamedSolids(const TopLoc_Location& location, case TopAbs_SOLID: namedSolids.emplace_back(TopoDS::Solid(transform.Shape()), fullName); break; + case TopAbs_SHELL: { + const TopoDS_Shape& shellShape = transform.Shape(); + if (!BRep_Tool::IsClosed(shellShape) && unclosed_shells) { + if (std::find(unclosed_shells->begin(), unclosed_shells->end(), fullName) == unclosed_shells->end()) + unclosed_shells->push_back(fullName); + } + namedSolids.emplace_back(TopoDS::Shell(shellShape), fullName); + break; + } default: break; } @@ -471,7 +483,7 @@ Step::Step_Status Step::load() Standard_Integer topShapeLength = topLevelShapes.Length() + 1; for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { if (cb_cancel) return; - getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids); + getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids, false, &m_unclosed_shells); } progress = 10; load_result = true; diff --git a/src/libslic3r/Format/STEP.hpp b/src/libslic3r/Format/STEP.hpp index 2ce46b9636..e2f1f91012 100644 --- a/src/libslic3r/Format/STEP.hpp +++ b/src/libslic3r/Format/STEP.hpp @@ -110,6 +110,7 @@ class Step std::atomic m_stop_mesh; void update_process(int load_stage, int current, int total, bool& cancel); + const std::vector& get_unclosed_shells() const { return m_unclosed_shells; } private: std::string m_path; ImportStepProgressFn m_stepFn; @@ -118,6 +119,7 @@ class Step Handle(TDocStd_Document) m_doc; Handle(XCAFDoc_ShapeTool) m_shape_tool; std::vector m_name_solids; + std::vector m_unclosed_shells; }; }; // namespace Slic3r diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 9693271b68..f7e0f1a576 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3794,7 +3794,8 @@ namespace ProcessLayer unsigned int current_extruder_id, // ID of the first extruder printing this layer. unsigned int first_extruder_id, - const PrintConfig &config) + const PrintConfig &config, + bool unretract_before_custom_for_pa_pattern) { std::string gcode; // BBS @@ -3859,6 +3860,10 @@ namespace ProcessLayer else { // add tag for processor gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Custom_Code) + "\n"; + // PA pattern calibration G-code is generated with a fresh writer and assumes the nozzle starts + // unretracted; after change_layer() the main path may still be retracted (e.g. wipe). + if (unretract_before_custom_for_pa_pattern) + gcode += gcodegen.writer().unretract(); if (gcode_type == CustomGCode::Template) // Template Custom Gcode gcode += gcodegen.placeholder_parser_process("template_custom_gcode", config.template_custom_gcode, current_extruder_id); else // custom Gcode @@ -4205,7 +4210,8 @@ GCode::LayerResult GCode::process_layer( if (single_object_instance_idx == size_t(-1)) { // Normal (non-sequential) print. - gcode += ProcessLayer::emit_custom_gcode_per_print_z(*this, layer_tools.custom_gcode, m_writer.filament()->id(), first_extruder_id, print.config()); + gcode += ProcessLayer::emit_custom_gcode_per_print_z(*this, layer_tools.custom_gcode, m_writer.filament()->id(), first_extruder_id, print.config(), + print.calib_mode() == CalibMode::Calib_PA_Pattern); } // Extrude skirt at the print_z of the raft layers and normal object layers // not at the print_z of the interlaced support material layers. diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index e81044ba71..32cfa030b4 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1179,7 +1179,8 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st context.heating_rate, skippable_blocks, context.extruder_max_nozzle_count, - context.filament_cooling_before_tower, + context.filament_preheat_temperature_delta, + context.filament_max_temperature_drop_when_ec, machine_start_gcode_end_line_id, machine_end_gcode_start_line_id, context.extruder_types, @@ -1928,11 +1929,11 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_hotend_cooling_rate = config.hotend_cooling_rate.values; m_hotend_heating_rate = config.hotend_heating_rate.values; m_filament_pre_cooling_temp = config.filament_pre_cooling_temperature.values; + m_filament_preheat_temperature_delta = config.filament_preheat_temperature_delta.values; m_enable_pre_heating = config.enable_pre_heating; m_has_filament_switcher = config.has_filament_switcher; m_physical_extruder_map = config.physical_extruder_map.values; m_extruder_max_nozzle_count = config.extruder_max_nozzle_count.values; - m_filament_cooling_before_tower = config.filament_cooling_before_tower.values; m_extruder_offsets.resize(filament_count); m_extruder_colors.resize(filament_count); @@ -2063,6 +2064,11 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_filament_pre_cooling_temp = filament_pre_cooling_temp->values; } + const ConfigOptionFloatsNullable* filament_preheat_temperature_delta = config.option("filament_preheat_temperature_delta"); + if (filament_preheat_temperature_delta != nullptr) { + m_filament_preheat_temperature_delta = filament_preheat_temperature_delta->values; + } + const ConfigOptionBool* enable_pre_heating = config.option("enable_pre_heating"); if (enable_pre_heating != nullptr) { m_enable_pre_heating = enable_pre_heating->value; @@ -2083,11 +2089,6 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_extruder_max_nozzle_count = extruder_max_nozzle_count->values; } - const ConfigOptionFloatsNullable* filament_cooling_before_tower = config.option("filament_cooling_before_tower"); - if (filament_cooling_before_tower != nullptr) { - m_filament_cooling_before_tower = filament_cooling_before_tower->values; - } - const ConfigOptionInts* physical_extruder_map = config.option("physical_extruder_map"); if (physical_extruder_map != nullptr) { m_physical_extruder_map = physical_extruder_map->values; @@ -2464,6 +2465,7 @@ void GCodeProcessor::reset() m_forced_height = 0.0f; m_mm3_per_mm = 0.0f; m_fan_speed = 0.0f; + m_additional_fan_speed = 0.0f; m_extrusion_role = erNone; @@ -2707,7 +2709,7 @@ void GCodeProcessor::finalize(bool post_process) m_handle_hotend_as_extruder, m_has_filament_switcher, m_extruder_max_nozzle_count, - m_filament_cooling_before_tower, + m_filament_preheat_temperature_delta, m_result.extruder_types, m_nozzle_diameter ); @@ -5268,20 +5270,24 @@ void GCodeProcessor::process_M104(const GCodeReader::GCodeLine& line) { int filament_id = get_filament_id(); float new_temp; - float phy_extruder_id_temp; + if (!line.has_value('S', new_temp)) + return; + + float phy_extruder_id_temp; if (line.has_value('T', phy_extruder_id_temp)) { + // Map physical extruder id to logical extruder index int phy_extruder_id_temp_int = std::round(phy_extruder_id_temp); - auto it_temp = std::find(m_physical_extruder_map.begin(), m_physical_extruder_map.end(), phy_extruder_id_temp_int); - if (line.has_value('S', new_temp) && it_temp != m_physical_extruder_map.end()) { + auto it_temp = std::find(m_physical_extruder_map.begin(), m_physical_extruder_map.end(), phy_extruder_id_temp_int); + if (it_temp != m_physical_extruder_map.end()) { size_t extruder_index = std::distance(m_physical_extruder_map.begin(), it_temp); - for (size_t ii = 0; ii < m_filament_maps.size(); ii++) { - auto it_temp_2 = std::find(m_filament_maps.begin(), m_filament_maps.end(), extruder_index); - size_t filament_index = std::distance(m_filament_maps.begin(), it_temp_2); - if (filament_index > 0 && filament_index < m_extruder_temps.size()) m_extruder_temps[filament_index] = new_temp; + // Update temperature for all filaments assigned to this logical extruder + for (size_t ii = 0; ii < m_filament_maps.size() && ii < m_extruder_temps.size(); ii++) { + if (static_cast(m_filament_maps[ii]) == extruder_index) + m_extruder_temps[ii] = new_temp; } } } else { - if (line.has_value('S', new_temp)) m_extruder_temps[filament_id] = new_temp; + m_extruder_temps[filament_id] = new_temp; } } @@ -5301,12 +5307,23 @@ void GCodeProcessor::process_M106(const GCodeReader::GCodeLine& line) m_fan_speed = (100.0f / 255.0f) * new_fan_speed; else m_fan_speed = 100.0f; + } else if (line.has('P') && line.p() == 2.0f) { + // M106 P2: additional/auxiliary cooling fan (side fan) + float new_fan_speed; + if (line.has_value('S', new_fan_speed)) + m_additional_fan_speed = (100.0f / 255.0f) * new_fan_speed; + else + m_additional_fan_speed = 100.0f; } } void GCodeProcessor::process_M107(const GCodeReader::GCodeLine& line) { - m_fan_speed = 0.0f; + // M107: disable fan; without P or P1 = part fan, P2 = additional/side fan + if (!line.has('P') || (line.has('P') && line.p() == 1.0f)) + m_fan_speed = 0.0f; + else if (line.has('P') && line.p() == 2.0f) + m_additional_fan_speed = 0.0f; } void GCodeProcessor::process_M108(const GCodeReader::GCodeLine& line) @@ -5325,20 +5342,7 @@ void GCodeProcessor::process_M108(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M109(const GCodeReader::GCodeLine& line) { - int filament_id = get_filament_id(); - float new_temp; - if (line.has_value('R', new_temp)) { - float val; - if (line.has_value('T', val)) { - size_t eid = static_cast(val); - if (eid < m_extruder_temps.size()) - m_extruder_temps[eid] = new_temp; - } - else - m_extruder_temps[filament_id] = new_temp; - } - else if (line.has_value('S', new_temp)) - m_extruder_temps[filament_id] = new_temp; + process_M104(line); } void GCodeProcessor::process_VM109(const GCodeReader::GCodeLine& line) @@ -5964,6 +5968,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type) m_height, m_mm3_per_mm, m_fan_speed, + m_additional_fan_speed, m_extruder_temps[filament_id], static_cast(m_layer_id), //layer_duration: set later m_thermal_index.min, @@ -6394,12 +6399,12 @@ int GCodeProcessor::get_machine_config_idx(int filament_idx) const void GCodeProcessor::PreCoolingInjector::process_pre_cooling_and_heating(TimeProcessor::InsertedLinesMap& inserted_operation_lines) { bool is_multiple_nozzle = std::any_of(extruder_max_nozzle_count.begin(), extruder_max_nozzle_count.end(), [](auto& elem) {return elem > 1; }); - auto get_nozzle_temp = [this, is_multiple_nozzle](int filament_id, bool is_first_layer, bool from_or_to, bool consider_cooling_before_tower) { + auto get_nozzle_temp = [this, is_multiple_nozzle](int filament_id, bool is_first_layer, bool from_or_to, bool consider_preheat_temperature_delta) { if (filament_id == -1) return from_or_to ? 140 : 0; // default temp double temp = (is_first_layer ? filament_nozzle_temps_initial_layer[filament_id] : filament_nozzle_temps[filament_id]); - if (consider_cooling_before_tower) - return (int) (temp - filament_cooling_before_tower[filament_id]); + if (consider_preheat_temperature_delta) + return (int) (temp - filament_preheat_temperature_delta[filament_id]); else return (int)(temp); }; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 1508a2cf3f..513b24bd64 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -207,7 +207,8 @@ namespace Slic3r { float width{ 0.0f }; // mm float height{ 0.0f }; // mm float mm3_per_mm{ 0.0f }; - float fan_speed{ 0.0f }; // percentage + float fan_speed{ 0.0f }; // percentage (part cooling fan, M106 / M106 P1) + float additional_fan_speed{ 0.0f }; // percentage (auxiliary/side fan, M106 P2) float temperature{ 0.0f }; // Celsius degrees float layer_duration{ 0.0f }; // s (layer id before finalize) float thermal_index_min{0.0f}; @@ -754,7 +755,8 @@ namespace Slic3r { size_t total_layer_num; std::vector cooling_rate{ 2.f }; // Celsius degree per second std::vector heating_rate{ 2.f }; // Celsius degree per second - std::vector filament_cooling_before_tower {10.f}; // temperature drop before entering wipe tower + std::vector filament_preheat_temperature_delta{0.f}; // temperature delta applied during pre-heating + std::vector filament_max_temperature_drop_when_ec {0.f}; // max temperature drop when extruder change std::vector pre_cooling_temp{ 0 }; float inject_time_threshold{ 30.f }; // only active pre cooling & heating if time gap is bigger than threshold bool enable_pre_heating{ false }; @@ -780,7 +782,7 @@ namespace Slic3r { const bool handle_hotend_as_extruder_, const bool has_filament_switcher_, const std::vector& extruder_max_nozzle_count_, - const std::vector& filament_cooling_before_tower_, + const std::vector& filament_preheat_temperature_delta_, const std::vector& extruder_types_, const std::vector& nozzle_diameter_ ) : @@ -799,7 +801,7 @@ namespace Slic3r { has_filament_switcher(has_filament_switcher_), inject_time_threshold(inject_time_threshold_), extruder_max_nozzle_count(extruder_max_nozzle_count_), - filament_cooling_before_tower(filament_cooling_before_tower_), + filament_preheat_temperature_delta(filament_preheat_temperature_delta_), extruder_types(extruder_types_), nozzle_diameter(nozzle_diameter_) { @@ -904,7 +906,8 @@ namespace Slic3r { const std::vector& heating_rate_, const std::vector>& skippable_blocks_, const std::vector& extruder_max_nozzle_count_, - const std::vector& filament_cooling_before_tower_, + const std::vector& filament_preheat_temperature_delta_, + const std::vector& filament_max_temperature_drop_when_ec_, unsigned int machine_start_gcode_end_id_, unsigned int machine_end_gcode_start_id_, const std::vector& extruder_types_, @@ -925,7 +928,8 @@ namespace Slic3r { heating_rate(heating_rate_), skippable_blocks(skippable_blocks_), extruder_max_nozzle_count(extruder_max_nozzle_count_), - filament_cooling_before_tower(filament_cooling_before_tower_), + filament_preheat_temperature_delta(filament_preheat_temperature_delta_), + filament_max_temperature_drop_when_ec(filament_max_temperature_drop_when_ec_), machine_start_gcode_end_id(machine_start_gcode_end_id_), machine_end_gcode_start_id(machine_end_gcode_start_id_), extruder_types(extruder_types_), @@ -950,7 +954,8 @@ namespace Slic3r { const std::vector& filament_pre_cooling_temps; // target cooling temp during post extrusion const std::vector>& skippable_blocks; const std::vector& extruder_max_nozzle_count; - const std::vector& filament_cooling_before_tower; + const std::vector& filament_preheat_temperature_delta; + const std::vector& filament_max_temperature_drop_when_ec; const unsigned int machine_start_gcode_end_id; const unsigned int machine_end_gcode_start_id; const std::vector& extruder_types; @@ -1128,12 +1133,12 @@ namespace Slic3r { std::vector m_hotend_cooling_rate{ 2.f }; std::vector m_hotend_heating_rate{ 2.f }; std::vector m_filament_pre_cooling_temp{ 0 }; + std::vector m_filament_preheat_temperature_delta; bool m_enable_pre_heating{ false }; bool m_handle_hotend_as_extruder { false }; bool m_has_filament_switcher{ false }; std::vector m_physical_extruder_map; std::vector m_extruder_max_nozzle_count; - std::vector m_filament_cooling_before_tower; //BBS: x, y offset for gcode generated double m_x_offset{ 0 }; @@ -1151,7 +1156,8 @@ namespace Slic3r { float m_forced_width; // mm float m_forced_height; // mm float m_mm3_per_mm; - float m_fan_speed; // percentage + float m_fan_speed; // percentage (part cooling fan) + float m_additional_fan_speed; // percentage (auxiliary/side fan, M106 P2) ExtrusionRole m_extrusion_role; std::vector m_filament_maps; std::vector m_last_filament_id; diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index c238c20886..b0350df256 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -10,6 +10,7 @@ #include "PresetBundle.hpp" #include "MultiNozzleUtils.hpp" #include "FilamentMixer.hpp" +#include "LocalesUtils.hpp" #include "Utils.hpp" #include @@ -1323,6 +1324,7 @@ FilamentGroupContext build_filament_group_context( context.group_info.strategy = FGStrategy::BestCost; context.group_info.mode = fg_mode; context.group_info.ignore_ext_filament = ignore_ext_filament; + context.group_info.has_filament_switcher = print_config.has_filament_switcher.value; if(mode == FilamentMapMode::fmmManual) context.group_info.filament_volume_map = print_config.filament_volume_map.values; @@ -2035,6 +2037,7 @@ void ToolOrdering::resolve_mixed_filaments(const PrintConfig &config) continue; is_gradient[i] = true; if (i < gradient_range_strs.size() && !gradient_range_strs[i].empty()) { + CNumericLocalesSetter c_locale_setter; float v0 = 0, v1 = 0; if (std::sscanf(gradient_range_strs[i].c_str(), "%f,%f", &v0, &v1) == 2 && v0 > 0 && v0 < 1.0 && v1 > 0 && v1 < 1.0) { @@ -2136,6 +2139,8 @@ void ToolOrdering::resolve_mixed_filaments(const PrintConfig &config) size_t n = s.components.size(); std::vector sub_heights; + bool gradient_last_no_split = false; + unsigned int gradient_last_dominant_0b = 0; if (is_gradient[ext] && n == 2) { auto gr_it = gradient_runs.find(ext); if (gr_it != gradient_runs.end() && gr_it->second.current_run >= 0 && @@ -2148,6 +2153,22 @@ void ToolOrdering::resolve_mixed_filaments(const PrintConfig &config) double r2 = 1.0 - r1; sub_heights.push_back(r1 * lh); sub_heights.push_back(r2 * lh); + // The sublayer split path sorts components by physical ID ascending; + // the higher-ID component ends up on top (visible surface). If the + // gradient's dominant component has the lower physical ID, splitting + // would put the non-dominant color on the visible top surface. In + // that case, skip the split and print this final run-layer as pure + // dominant color to preserve the gradient appearance. + if (idx == N - 1) { + // When r1 == r2 (exactly 50/50), component[0] is treated as dominant. + size_t dominant = (r1 >= r2) ? 0 : 1; + unsigned int dom_0b = s.components[dominant] - 1; + unsigned int oth_0b = s.components[1 - dominant] - 1; + if (dom_0b < oth_0b) { + gradient_last_no_split = true; + gradient_last_dominant_0b = dom_0b; + } + } } else { for (double r : s.ratios) sub_heights.push_back(r * lh); @@ -2157,13 +2178,18 @@ void ToolOrdering::resolve_mixed_filaments(const PrintConfig &config) sub_heights.push_back(r * lh); } + if (gradient_last_no_split) { + lt.mixed_filament_resolution[ext] = gradient_last_dominant_0b; + new_extruders.push_back(gradient_last_dominant_0b); + continue; + } + LayerTools::MixedSubLayerGroup grp; grp.mixed_slot_0based = ext; grp.is_gradient = is_gradient[ext]; for (size_t k = 0; k < s.components.size(); ++k) { unsigned int comp_0based = s.components[k] - 1; grp.components_0based.push_back(comp_0based); - new_extruders.push_back(comp_0based); } grp.sub_heights = sub_heights; @@ -2219,6 +2245,8 @@ void ToolOrdering::resolve_mixed_filaments(const PrintConfig &config) } } + for (unsigned int comp : grp.components_0based) + new_extruders.push_back(comp); lt.mixed_sub_layer_groups.push_back(std::move(grp)); } else { // Deficit Round-Robin: pick one component per layer. @@ -2227,8 +2255,20 @@ void ToolOrdering::resolve_mixed_filaments(const PrintConfig &config) double lh = lt.print_z - prev_print_z; if (lh <= 0) lh = 0.2; long long lh_i = std::llround(lh * 1e6); - for (size_t k = 0; k < s.ratios.size(); ++k) - s.accum[k] += std::llround(s.ratios[k] * lh_i); + // For 2-component gradient on the first layer, use the gradient's + // starting ratio instead of the configured mixing ratio so the + // selected filament matches the gradient's "from" end. + // Only affects the first layer; when sublayer splitting is enabled + // (required for gradient), layers 1+ take the sublayer path and + // do not touch the DRR accumulator. + if (layer_idx == 0 && is_gradient[ext] && s.components.size() == 2) { + double r0 = gradient_info[ext].start; + s.accum[0] += std::llround(r0 * lh_i); + s.accum[1] += std::llround((1.0 - r0) * lh_i); + } else { + for (size_t k = 0; k < s.ratios.size(); ++k) + s.accum[k] += std::llround(s.ratios[k] * lh_i); + } size_t sel = 0; for (size_t k = 1; k < s.accum.size(); ++k) if (s.accum[k] > s.accum[sel]) @@ -2392,6 +2432,9 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first m_print->config().filament_map_mode.value ); + // 时间预估器中存储的材料在不同挤出机的打印时间是全局的,不适用于当前分区间的分组方法 + grouping_context.speed_info.group_with_time = false; + // TODO(山苍):逐件打印后面要考虑喷嘴状态 auto dynamic_plan_res = plan_filament_mapping_and_order_by_combo_ranges(m_print, grouping_context, diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 30e16d304c..8f6903f4f2 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -557,7 +557,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co w0.emit_comment(GCodeWriter::full_gcode_comment, "slope lift Z"); slop_move = w0.string(); } - else if (m_to_lift_type == LiftType::NormalLift) { + else if (m_to_lift_type == LiftType::NormalLift || (m_to_lift_type == LiftType::SpiralLift &&!this->is_current_position_clear())){ slop_move = _travel_to_z(target.z(), "normal lift Z"); } } diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 870ae80d4b..b3c84e1766 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -192,7 +192,8 @@ bool Layer::has_compatible_layer_regions(const PrintRegionConfig &config, const && config.seam_slope_conditional == other_config.seam_slope_conditional && config.seam_slope_entire_loop == other_config.seam_slope_entire_loop && config.seam_slope_steps == other_config.seam_slope_steps - && config.seam_slope_inner_walls == other_config.seam_slope_inner_walls; + && config.seam_slope_inner_walls == other_config.seam_slope_inner_walls + && (this->id() != 0 || config.initial_layer_flow_ratio == other_config.initial_layer_flow_ratio); } // Here the perimeters are created cummulatively for all layer regions sharing the same parameters influencing the perimeters. diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 1c0270f2df..6a9cebd122 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -191,7 +191,8 @@ Model Model::read_from_step(const std::string& std::function step_mesh_fn, double linear_defletion, double angle_defletion, - bool is_split_compound) + bool is_split_compound, + std::function&)> open_shell_warn_fn) { Model model; bool result = false; @@ -202,6 +203,9 @@ Model Model::read_from_step(const std::string& if(status != Step::Step_Status::LOAD_SUCCESS) { goto _finished; } + if (open_shell_warn_fn && !step_file.get_unclosed_shells().empty()) { + open_shell_warn_fn(step_file.get_unclosed_shells()); + } if (step_mesh_fn) { if (step_mesh_fn(step_file, linear_defletion, angle_defletion, is_split_compound) == -1) { status = Step::Step_Status::CANCEL; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 3104a51a11..e0ff3f9296 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1657,7 +1657,8 @@ class Model final : public ObjectBase std::function step_mesh_fn, double linear_defletion, double angle_defletion, - bool is_split_compound); + bool is_split_compound, + std::function&)> open_shell_warn_fn = nullptr); //BBS: add part plate related logic // BBS: backup diff --git a/src/libslic3r/MultiNozzleUtils.cpp b/src/libslic3r/MultiNozzleUtils.cpp index 048085b429..38ec7e1237 100644 --- a/src/libslic3r/MultiNozzleUtils.cpp +++ b/src/libslic3r/MultiNozzleUtils.cpp @@ -636,14 +636,11 @@ float calc_filament_change_gap_for_assignment( const std::vector& filament_change_seq, const std::vector& nozzle_change_seq, const std::vector& group_of_filament, - const FilamentChangeTimeParams& time_params) + const FilamentChangeTimeParams& time_params, + const std::vector& ams_preload_enabled) { if (logical_filaments.empty() || nozzle_list.empty() || filament_change_seq.empty() || nozzle_change_seq.empty()) return 0.0f; - // TODO: 当前固件所有退料都退到AMS,不支持退到选料器待机。 - // 待固件支持后,将此开关置为 true 以启用选料器待机优化。 - constexpr bool selector_park_enabled = false; - // 参数语义重新映射: // 输入参数中 standard = AMS->选料器->挤出机(全程),selector = 选料器->挤出机(短程) // 所以 AMS->选料器 = standard - selector @@ -669,12 +666,18 @@ float calc_filament_change_gap_for_assignment( return it != filament_to_group.end() ? it->second : -1; }; + const auto is_preload_enabled = [&](int group_id) -> bool { + if (group_id < 0 || group_id >= static_cast(ams_preload_enabled.size())) + return false; + return ams_preload_enabled[group_id]; + }; + // 料的位置状态 enum class Location { IN_AMS, IN_SELECTOR, IN_EXTRUDER }; std::unordered_map filament_location; // filament_id -> 当前位置 std::unordered_map filament_extruder; // filament_id -> 所在挤出机(仅IN_EXTRUDER时有效) std::unordered_map extruder_filament; // extruder_id -> 当前装载的料 - // group_id -> 当前占用了该AMS通道的料集合(IN_SELECTOR或IN_EXTRUDER),用于Step3快速查找需要让路的料 + // group_id -> 当前占用了该AMS通道的料集合(IN_SELECTOR或IN_EXTRUDER) std::unordered_map> ams_group_occupied; filament_location.reserve(logical_filaments.size()); @@ -700,6 +703,7 @@ float calc_filament_change_gap_for_assignment( int E = nozzle_iter->second; // 目标挤出机 + // Step 0: 计算切片预估时间 // 切片预估时间:模拟切片视角(无选料器意识) // 对应参考代码逻辑:nozzle_in_extruder_change || filament_in_nozzle_change 时计进退料 { @@ -726,24 +730,10 @@ float calc_filament_change_gap_for_assignment( A = it->second; } - // Step 2: A从E退出(A不为空且A!=B时) - if (A != -1 && A != B) { - if (!selector_park_enabled || get_group(A) == get_group(B)) { - // 当前固件不支持选料器待机,或同AMS需让路:A完整退回AMS - actual_time += unload_ext_to_selector + unload_ams_to_selector; - filament_location[A] = Location::IN_AMS; - ams_group_occupied[get_group(A)].erase(A); - } else { - // 不同AMS且支持选料器待机:A只退到选料器,仍占用AMS通道 - actual_time += unload_ext_to_selector; - filament_location[A] = Location::IN_SELECTOR; - } - extruder_filament.erase(E); - filament_extruder.erase(A); - } - - // Step 3: 若B的AMS通道被其他料X占用(X与B同AMS,且X在选料器或挤出机里),X必须退回AMS让路 int group_B = get_group(B); + int group_A = (A != -1) ? get_group(A) : -1; + + // Step 2: 清理B的AMS通道占用 auto group_it = ams_group_occupied.find(group_B); if (group_it != ams_group_occupied.end()) { for (int X : group_it->second) { @@ -755,7 +745,7 @@ float calc_filament_change_gap_for_assignment( int E2 = filament_extruder[X]; extruder_filament.erase(E2); filament_extruder.erase(X); - } else { // IN_SELECTOR + } else if (loc_X == Location::IN_SELECTOR) { actual_time += unload_ams_to_selector; } filament_location[X] = Location::IN_AMS; @@ -763,22 +753,69 @@ float calc_filament_change_gap_for_assignment( group_it->second.clear(); } - // Step 4: B推入E(根据B当前状态) - auto loc_it = filament_location.find(B); - Location loc_B = (loc_it != filament_location.end()) ? loc_it->second : Location::IN_AMS; + // Step 3: A从E退出(A仍在挤出机中时) + // Step 3.5: 预进料B(与Step 3并行) + // 实际耗时 = max(Step 3, Step 3.5) + bool step3_executed = false; + float step3_time = 0.0f; + if (A != -1 && A != B && filament_location[A] == Location::IN_EXTRUDER) { + if (is_preload_enabled(group_A) && group_A != group_B) { + step3_time = unload_ext_to_selector; + filament_location[A] = Location::IN_SELECTOR; + } else { + step3_time = unload_ext_to_selector + unload_ams_to_selector; + filament_location[A] = Location::IN_AMS; + ams_group_occupied[group_A].erase(A); + } + extruder_filament.erase(E); + filament_extruder.erase(A); + step3_executed = true; + } + + float step3_5_time = 0.0f; + if (step3_executed && + filament_location[B] == Location::IN_AMS && + group_A != group_B && + is_preload_enabled(group_B)) { + step3_5_time = load_ams_to_selector; + filament_location[B] = Location::IN_SELECTOR; + ams_group_occupied[group_B].insert(B); + } + + actual_time += std::max(step3_time, step3_5_time); + + // Step 4: B推入E + // Step 6: 预进料下一个料C(与Step 4并行) + // 实际耗时 = max(Step 4, Step 6) + float step4_time = 0.0f; + Location loc_B = filament_location[B]; if (loc_B == Location::IN_AMS) { - actual_time += load_ams_to_selector + load_selector_to_ext; + step4_time = load_ams_to_selector + load_selector_to_ext; } else if (loc_B == Location::IN_SELECTOR) { - // 仅在selector_park_enabled时B才可能处于IN_SELECTOR - actual_time += load_selector_to_ext; + step4_time = load_selector_to_ext; } - // IN_EXTRUDER且E==当前挤出机:B已经在目标挤出机,无需操作 // Step 5: 更新状态 extruder_filament[E] = B; filament_location[B] = Location::IN_EXTRUDER; filament_extruder[B] = E; ams_group_occupied[group_B].insert(B); + + float step6_time = 0.0f; + if (i + 1 < seq_len) { + int C = filament_change_seq[i + 1]; + int group_C = get_group(C); + if (filament_location[C] == Location::IN_AMS && + group_C != group_B && + is_preload_enabled(group_C) && + ams_group_occupied[group_C].empty()) { + step6_time = load_ams_to_selector; + filament_location[C] = Location::IN_SELECTOR; + ams_group_occupied[group_C].insert(C); + } + } + + actual_time += std::max(step4_time, step6_time); } return actual_time - sliced_time; diff --git a/src/libslic3r/MultiNozzleUtils.hpp b/src/libslic3r/MultiNozzleUtils.hpp index b1d7fde821..351fa149b0 100644 --- a/src/libslic3r/MultiNozzleUtils.hpp +++ b/src/libslic3r/MultiNozzleUtils.hpp @@ -242,7 +242,8 @@ float calc_filament_change_gap_for_assignment( const std::vector& filament_change_seq, const std::vector& nozzle_change_seq, const std::vector& group_of_filament, - const FilamentChangeTimeParams& time_params); + const FilamentChangeTimeParams& time_params, + const std::vector& ams_preload_enabled = {}); std::vector find_optimal_physical_assignment( const std::vector& logical_filaments, diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 33b57edfec..fa6d5962c6 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1065,6 +1065,7 @@ static std::vector s_Preset_filament_options {/*"filament_colour", "filament_overhang_4_4_speed", "filament_overhang_totally_speed", "override_process_overhang_speed", + "filament_preheat_temperature_delta", "filament_cooling_before_tower", "filament_tower_interface_pre_extrusion_dist", "filament_tower_interface_pre_extrusion_length", diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 7261480d0b..373b7d37a7 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -74,6 +74,7 @@ #define BBL_JSON_KEY_DEFAULT_MATERIALS "default_materials" #define BBL_JSON_KEY_NOT_SUPPORT_BED_TYPE "not_support_bed_type" #define BBL_JSON_KEY_MODEL_ID "model_id" +#define BBL_JSON_KEY_SUPPORT_SIDE_PANEL_FAN "support_side_panel_fan" //BBL: json path @@ -139,6 +140,7 @@ class VendorProfile std::string middle_texture_rect; std::string right_icon_offset_bed; std::string hotend_model; + std::string support_side_panel_fan{ "true" }; PrinterVariant* variant(const std::string &name) { for (auto &v : this->variants) if (v.name == name) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 3f69df0561..bdb1556652 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -5421,6 +5421,8 @@ VendorProfile::PrinterModel PresetBundle::load_vendor_configs_from_json(const st } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": invalid not_support_bed_types %1% for Vendor") % not_support_bed_type_field; } + } else if (boost::iequals(it.key(), BBL_JSON_KEY_SUPPORT_SIDE_PANEL_FAN)) { + model.support_side_panel_fan = it.value(); } } } catch (nlohmann::detail::parse_error &err) { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index b5a8e92dea..8f9d12f1fc 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1373,7 +1373,10 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* layer_height_profiles.assign(m_objects.size(), std::vector()); std::vector &profile = layer_height_profiles[print_object_idx]; if (profile.empty()) - PrintObject::update_layer_height_profile(*print_object.model_object(), print_object.slicing_parameters(), profile); + { + bool nozzle_range_reset = false; + PrintObject::update_layer_height_profile(*print_object.model_object(), print_object.slicing_parameters(), profile, nozzle_range_reset); + } return profile; }; @@ -2254,6 +2257,40 @@ void Print::process(std::unordered_map* slice_time, bool } auto objectExtruderMap = getObjectExtruderMap(*this); + // Resolve mixed filament virtual slots to physical components so brim + // extruder matching works correctly (mixed slot IDs are not present + // in printExtruders after ToolOrdering::resolve_mixed_filaments). + { + const LayerTools *first_lt = nullptr; + if (!is_sequential_print() && !tool_ordering.layer_tools().empty()) + first_lt = &tool_ordering.layer_tools().front(); + + std::map obj_by_id; + if (m_sequential_print_data) { + for (const PrintObject *obj : m_objects) + obj_by_id[obj->id()] = obj; + } + + for (auto &[obj_id, ext_1based] : objectExtruderMap) { + if (ext_1based == 0) + continue; + const LayerTools *lt = first_lt; + if (!lt && m_sequential_print_data) { + auto oid_it = obj_by_id.find(obj_id); + if (oid_it != obj_by_id.end()) { + auto it = m_sequential_print_data->object_tool_ordering_map.find(oid_it->second); + if (it != m_sequential_print_data->object_tool_ordering_map.end() + && !it->second.layer_tools().empty()) + lt = &it->second.layer_tools().front(); + } + } + if (lt) { + auto it = lt->mixed_filament_resolution.find(ext_1based - 1); + if (it != lt->mixed_filament_resolution.end()) + ext_1based = it->second + 1; + } + } + } std::vector> objPrintVec; for (const PrintInstance* instance : print_object_instances_ordering) { const ObjectID& print_object_ID = instance->print_object->id(); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4df1ae0853..dd9485ccb7 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -459,7 +459,7 @@ class PrintObject : public PrintObjectBaseWithState &layer_height_profile); + static bool update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector &layer_height_profile, bool &out_nozzle_range_reset); // Collect the slicing parameters, to be used by variable layer thickness algorithm, // by the interactive layer height editor and by the printing process itself. @@ -967,7 +967,7 @@ class Print : public PrintBaseWithState std::unordered_map> get_filament_print_time() const { return m_filament_print_time; } void set_nozzle_group_result(const std::shared_ptr result) { m_nozzle_group_result = result; } - const std::shared_ptr get_nozzle_group_result() { return m_nozzle_group_result; } + const std::shared_ptr get_nozzle_group_result() const { return m_nozzle_group_result; } std::shared_ptr get_layered_nozzle_group_result() { return std::dynamic_pointer_cast(m_nozzle_group_result); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index a66c1ff6d5..6c5d2bce37 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2597,6 +2597,14 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionFloats{60.}); + def = this->add("filament_preheat_temperature_delta", coFloats); + def->label = L("Preheat temperature delta"); + def->tooltip = L("Temperature delta applied during pre-heating before tool change."); + def->sidetext = "°C"; + def->mode = comDevelop; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{0}); + def = this->add("filament_cooling_before_tower", coFloats); def->label = L("Wipe tower cooling"); def->tooltip = L("Temperature drop before entering filament tower"); @@ -7069,6 +7077,7 @@ std::set filament_options_with_variant = { "override_process_overhang_speed", "volumetric_speed_coefficients", "filament_adaptive_volumetric_speed", + "filament_preheat_temperature_delta", "filament_cooling_before_tower", "slow_down_min_speed" }; @@ -9618,6 +9627,11 @@ CLIMiscConfigDef::CLIMiscConfigDef() def->cli_params = "level"; def->set_default_value(new ConfigOptionInt(1)); + def = this->add("estimate_mode", coBool); + def->label = "Estimate mode"; + def->tooltip = "When enabled, automatically fill filament presets and extruder state for machine estimation after machine switch"; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("enable_timelapse", coBool); def->label = "Enable timeplapse for print"; def->tooltip = "If enabled, this slicing will be considered using timelapse"; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4af4002542..6793118a2e 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1510,6 +1510,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloats, hole_limit_max)) ((ConfigOptionFloats, filament_prime_volume)) ((ConfigOptionFloats, filament_prime_volume_nc)) + ((ConfigOptionFloatsNullable, filament_preheat_temperature_delta)) ((ConfigOptionFloatsNullable, filament_cooling_before_tower)) ((ConfigOptionFloats, filament_tower_interface_pre_extrusion_dist)) ((ConfigOptionFloats, filament_tower_interface_pre_extrusion_length)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index e1a2e7ae2a..b22bfea1f5 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -3243,9 +3243,10 @@ std::vector PrintObject::object_extruders() const return extruders; } -bool PrintObject::update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector &layer_height_profile) +bool PrintObject::update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector &layer_height_profile, bool &out_nozzle_range_reset) { bool updated = false; + out_nozzle_range_reset = false; if (layer_height_profile.empty()) { // use the constructor because the assignement is crashing on ASAN OsX @@ -3262,6 +3263,18 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_max + slicing_parameters.object_print_z_min) > 1e-3)) layer_height_profile.clear(); + // Verify that all layer height values are within the allowed range for the current nozzle. + if (!layer_height_profile.empty()) { + for (size_t i = 1; i < layer_height_profile.size(); i += 2) { + if (layer_height_profile[i] < slicing_parameters.min_layer_height - EPSILON || + layer_height_profile[i] > slicing_parameters.max_layer_height + EPSILON) { + out_nozzle_range_reset = true; + layer_height_profile.clear(); + break; + } + } + } + bool not_match_flag = !slicing_parameters.has_raft(); // if there is raft layer_height_profile[1] could also be adaptive not_match_flag &= !layer_height_profile.empty() && (layer_height_profile[1] != slicing_parameters.first_object_layer_height); if (layer_height_profile.empty() || not_match_flag) { diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 1033f50203..1d90b71c18 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -795,7 +795,12 @@ void PrintObject::slice() //BBS: add flag to reload scene for shell rendering m_print->set_status(5, L("Slicing mesh"), PrintBase::SlicingStatus::RELOAD_SCENE); std::vector layer_height_profile; - this->update_layer_height_profile(*this->model_object(), m_slicing_params, layer_height_profile); + bool nozzle_range_reset = false; + this->update_layer_height_profile(*this->model_object(), m_slicing_params, layer_height_profile, nozzle_range_reset); + if (nozzle_range_reset) + this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, + L("The variable layer height profile has been reset because some layer heights " + "exceed the allowed range of the current nozzle.")); m_print->throw_if_canceled(); m_typed_slices = false; this->clear_layers(); @@ -1145,7 +1150,7 @@ void PrintObject::slice_volumes() // Is any ModelVolume MMU painted? if (const auto& volumes = this->model_object()->volumes; m_print->config().filament_diameter.size() > 1 && // BBS - std::find_if(volumes.begin(), volumes.end(), [](const ModelVolume* v) { return !v->mmu_segmentation_facets.empty(); }) != volumes.end()) { + std::find_if(volumes.begin(), volumes.end(), [](const ModelVolume *v) { return v->is_model_part() && !v->mmu_segmentation_facets.empty(); }) != volumes.end()) { // If XY Size compensation is also enabled, notify the user that XY Size compensation // would not be used because the object is multi-material painted. diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index c76ad8b773..9e935c556a 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -3458,8 +3458,9 @@ first_pass_next:; to_outside = projection_onto(next_collision, next_node->position); direction_to_outer = to_outside - node.position; double dist_to_outer = unscale_(direction_to_outer.cast().norm()); - next_node->radius = next_node->print_z < DO_NOT_MOVER_UNDER_MM ? node.radius + max_move_distance : - std ::max(node.radius, std::min(next_node->radius, dist_to_outer)); + next_node->radius = (next_node->print_z < DO_NOT_MOVER_UNDER_MM && node.dist_mm_to_top > DO_NOT_MOVER_UNDER_MM) ? + node.radius + max_move_distance : + std ::max(node.radius, std::min(next_node->radius, dist_to_outer)); get_max_move_dist(next_node); m_ts_data->m_mutex.lock(); contact_nodes[layer_nr_next].push_back(next_node); diff --git a/src/platform/osx/entitlements.plist b/src/platform/osx/entitlements.plist index 59274f955f..3eafb60fd4 100644 --- a/src/platform/osx/entitlements.plist +++ b/src/platform/osx/entitlements.plist @@ -5,5 +5,9 @@ com.apple.security.cs.disable-library-validation + + + com.apple.security.cs.allow-unsigned-executable-memory + - + \ No newline at end of file diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 8a707348d8..25a4313212 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -640,6 +640,8 @@ set(SLIC3R_GUI_SOURCES add_subdirectory(GUI/DeviceCore) add_subdirectory(GUI/DeviceTab) +add_subdirectory(GUI/fila_manager) +add_subdirectory(GUI/DeviceWeb) if (WIN32) list(APPEND SLIC3R_GUI_SOURCES @@ -683,6 +685,13 @@ if (UNIX AND NOT APPLE) endif () add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) + +#if (MSVC) +# target_compile_options(libslic3r_gui PRIVATE /Od /Zi) +#else () +# target_compile_options(libslic3r_gui PRIVATE -O0 -g) +#endif () + target_include_directories(libslic3r_gui PRIVATE Utils) if (WIN32) diff --git a/src/slic3r/GUI/.vscode/settings.json b/src/slic3r/GUI/.vscode/settings.json new file mode 100644 index 0000000000..976ac974ad --- /dev/null +++ b/src/slic3r/GUI/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.sourceDirectory": "D:/dev/bamboo_slicer/src/slic3r/GUI/DeviceCore" +} \ No newline at end of file diff --git a/src/slic3r/GUI/AmsMappingPopup.cpp b/src/slic3r/GUI/AmsMappingPopup.cpp index d14787e69d..6b2946bef8 100644 --- a/src/slic3r/GUI/AmsMappingPopup.cpp +++ b/src/slic3r/GUI/AmsMappingPopup.cpp @@ -124,6 +124,14 @@ void MaterialItem::set_nozzle_info(const wxString& mapped_nozzle_str) } } +void MaterialItem::set_material_cols(int ctype, const std::vector& cols) { + if (m_material_ctype != ctype || m_material_cols != cols) { + m_material_ctype = ctype; + m_material_cols = cols; + Refresh(); + } +} + void MaterialItem::reset_ams_info() { m_ams_name = "-"; m_ams_coloul = wxColour(0xCE, 0xCE, 0xCE); @@ -290,12 +298,77 @@ void MaterialItem::doRender(wxDC& dc) //top dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(wxBrush(mcolor)); - dc.DrawRoundedRectangle(0, 0, size.x, FromDIP(20), 5); + if (m_material_cols.size() > 1 && IsEnabled()) { + int top_h = FromDIP(20); + bool drawn = false; + + wxGraphicsContext* gc = dc.GetGraphicsContext(); + if (gc) { + double r = FromDIP(5); + auto make_path = [&](double x, double w, bool left_round, bool right_round) { + wxGraphicsPath p = gc->CreatePath(); + double rl = left_round ? std::min(r, std::min(w, top_h)) : 0.0; + double rr = right_round ? std::min(r, std::min(w, top_h)) : 0.0; + p.MoveToPoint(x, top_h); + p.AddLineToPoint(x, rl); + if (rl > 0) p.AddArc(x + rl, rl, rl, M_PI, -M_PI / 2, true); + p.AddLineToPoint(x + w - rr, 0); + if (rr > 0) p.AddArc(x + w - rr, rr, rr, -M_PI / 2, 0, true); + p.AddLineToPoint(x + w, top_h); + p.CloseSubpath(); + return p; + }; + + if (m_material_ctype == 0) { + wxGraphicsPath path = make_path(0, size.x, true, true); + wxGraphicsGradientStops stops(m_material_cols.front(), m_material_cols.back()); + for (size_t i = 1; i + 1 < m_material_cols.size(); i++) { + float pos = (float)i / (m_material_cols.size() - 1); + stops.Add(m_material_cols[i], pos); + } + gc->SetBrush(gc->CreateLinearGradientBrush(0, 0, size.x, 0, stops)); + gc->FillPath(path); + } else { + int cols_size = m_material_cols.size(); + for (int i = 0; i < cols_size; i++) { + double x0 = (double)size.x * i / cols_size; + double w = (i == cols_size - 1) ? (size.x - x0) : ((double)size.x / cols_size); + wxGraphicsPath seg = make_path(x0, w, i == 0, i == cols_size - 1); + gc->SetBrush(gc->CreateBrush(wxBrush(m_material_cols[i]))); + gc->FillPath(seg); + } + } + drawn = true; + } - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(wxBrush(mcolor)); - dc.DrawRectangle(0, FromDIP(10), size.x, FromDIP(10)); + if (!drawn) { + if (m_material_ctype == 0) { + int seg = m_material_cols.size() - 1; + int gw = std::round((double)size.x / seg); + for (int i = 0; i < seg; i++) { + int x0 = gw * i; + int w = (i == seg - 1) ? (size.x - x0) : gw; + dc.GradientFillLinear(wxRect(x0, 0, w, top_h), m_material_cols[i], m_material_cols[i + 1], wxEAST); + } + } else { + int cols_size = m_material_cols.size(); + int cw = std::round((double)size.x / cols_size); + for (int i = 0; i < cols_size; i++) { + dc.SetBrush(wxBrush(m_material_cols[i])); + int x0 = cw * i; + int w = (i == cols_size - 1) ? (size.x - x0) : cw; + dc.DrawRectangle(x0, 0, w, top_h); + } + } + } + } else { + dc.SetBrush(wxBrush(mcolor)); + dc.DrawRoundedRectangle(0, 0, size.x, FromDIP(20), 5); + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(wxBrush(mcolor)); + dc.DrawRectangle(0, FromDIP(10), size.x, FromDIP(10)); + } // materials name auto up = 0; diff --git a/src/slic3r/GUI/AmsMappingPopup.hpp b/src/slic3r/GUI/AmsMappingPopup.hpp index 4f071a0d5f..1944089c6f 100644 --- a/src/slic3r/GUI/AmsMappingPopup.hpp +++ b/src/slic3r/GUI/AmsMappingPopup.hpp @@ -104,6 +104,9 @@ class MaterialItem: public wxPanel void set_ams_info(wxColour col, wxString txt, int ctype = 0, std::vector cols = std::vector(), bool record_back_info = false); + + void set_material_cols(int ctype, const std::vector& cols); + void reset_ams_info(); virtual void reset_valid_info(); @@ -127,6 +130,8 @@ class MaterialItem: public wxPanel std::string m_filament_id; wxColour m_material_coloul; + int m_material_ctype = 0; + std::vector m_material_cols; wxString m_material_name; wxString m_mapped_nozzle_str; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index ff63bde2fd..0f4332a54b 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -559,6 +559,8 @@ bool BackgroundSlicingProcess::stop() BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ", enter"<state_mutex() shall NOT be held. Unfortunately there is no interface to test for it. std::unique_lock lck(m_mutex); + // Always clear the one-shot post-process skip flag regardless of the return path. + struct SkipFlagGuard { bool& f; ~SkipFlagGuard() { f = false; } } skip_flag_guard{ m_skip_post_process_once }; if (m_state == STATE_INITIAL) { // m_export_path.clear(); return false; @@ -815,9 +817,26 @@ bool BackgroundSlicingProcess::invalidate_all_steps() return m_step_state.invalidate_all([this](){ this->stop_internal(); }); } +void BackgroundSlicingProcess::set_skip_post_process_once(bool skip) +{ + std::unique_lock lck(m_mutex); + m_skip_post_process_once = skip; +} + //Call post-processing script for the last step during slicing void BackgroundSlicingProcess::finalize_gcode() { + bool skip = false; + { + std::unique_lock lck(m_mutex); + skip = m_skip_post_process_once; + m_skip_post_process_once = false; + } + if (skip) { + m_print->set_status(100, _utf8(L("Slicing complete"))); + return; + } + m_print->set_status(95, _utf8(L("Running post-processing scripts"))); run_post_process_scripts(m_temp_output_path, false, "File", m_temp_output_path, m_fff_print->full_print_config()); @@ -828,6 +847,12 @@ void BackgroundSlicingProcess::finalize_gcode() if (post_process && !post_process->values.empty() && m_gcode_result) { m_print->set_status(97, _utf8(L("Updating preview with post-processed G-code"))); GCodeProcessor processor; + // Apply the plate origin offset so move coordinates in the result are + // relative to the correct plate, not always plate 0. Without this, + // slicing any plate other than the first one shifts the preview geometry + // by the plate's XY origin, causing the model to appear outside the bed. + const Vec3d origin = m_fff_print->get_plate_origin(); + processor.set_xy_offset(origin(0), origin(1)); processor.process_file(m_temp_output_path); *m_gcode_result = std::move(processor.extract_result()); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index 723a79fe3f..8a12355437 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -154,6 +154,9 @@ class BackgroundSlicingProcess // Apply config over the print. Returns false, if the new config values caused any of the already // processed steps to be invalidated, therefore the task will need to be restarted. PrintBase::ApplyStatus apply(const Model &model, const DynamicPrintConfig &config); + // If set before the current slicing run reaches finalize_gcode(), external post-processing scripts are not run (user chose "Do not execute" in Plater). Cleared when consumed or when stop() runs. + // Guarded by m_mutex so the background slicing thread (finalize_gcode) and the UI thread (reslice) don't race on this flag. + void set_skip_post_process_once(bool skip); // After calling the apply() function, set_task() may be called to limit the task to be processed by process(). // This is useful for calculating SLA supports for a single object only. void set_task(const PrintBase::TaskParams ¶ms); @@ -299,6 +302,7 @@ class BackgroundSlicingProcess GUI::PartPlate* m_current_plate; PrinterTechnology m_printer_tech = ptUnknown; bool m_internal_cancelled = false; + bool m_skip_post_process_once = false; PrintState m_step_state; bool set_step_started(BackgroundSlicingProcessStep step); diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 7755a981f4..1d1d93db38 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #ifdef __WXGTK2__ // Broken alpha workaround @@ -22,6 +24,23 @@ namespace Slic3r { namespace GUI { +static std::string dark_version(const std::string &bitmap_name) +{ + static std::unordered_set cache; + auto dark_bitmap_name = bitmap_name + "_dark"; + + auto it = cache.find(dark_bitmap_name); + if (it != cache.end()) return *it; + + boost::system::error_code ec; + if (boost::filesystem::exists(Slic3r::var(dark_bitmap_name) + ".svg", ec)) { + cache.insert(dark_bitmap_name); + return dark_bitmap_name; + } + + return {}; +} + BitmapCache::BitmapCache() { #ifdef __APPLE__ @@ -307,9 +326,12 @@ NSVGimage* BitmapCache::nsvgParseFromFileWithReplace(const char* filename, const return NULL; } -wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_width, unsigned target_height, +wxBitmap* BitmapCache::load_svg(const std::string &light_bitmap_name, unsigned target_width, unsigned target_height, const bool grayscale/* = false*/, const bool dark_mode/* = false*/, const std::string& new_color /*= ""*/, const float scale_in_center/* = 0*/) { + const std::string dark_bitmap_name = dark_mode ? dark_version(light_bitmap_name) : ""; + const std::string bitmap_name = dark_bitmap_name.empty() ? light_bitmap_name : dark_bitmap_name; + std::string bitmap_key = bitmap_name + ( target_height !=0 ? "-h" + std::to_string(target_height) : "-w" + std::to_string(target_width)) @@ -322,9 +344,10 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_ if (it != m_map.end()) return it->second; + // if dark version icon not available, we make one from the light version by replacing some predefined colors // map of color replaces std::map replaces; - if (dark_mode) { + if (dark_mode && dark_bitmap_name.empty()) { replaces["\"#262E30\""] = "\"#EFEFF0\""; replaces["\"#323A3D\""] = "\"#B3B3B5\""; replaces["\"#808080\""] = "\"#818183\""; diff --git a/src/slic3r/GUI/CaliHistoryDialog.cpp b/src/slic3r/GUI/CaliHistoryDialog.cpp index ad7651c755..e5944a4c87 100644 --- a/src/slic3r/GUI/CaliHistoryDialog.cpp +++ b/src/slic3r/GUI/CaliHistoryDialog.cpp @@ -915,7 +915,7 @@ NewCalibrationHistoryDialog::NewCalibrationHistoryDialog(wxWindow *parent, const m_comboBox_nozzle_type = new ::ComboBox(top_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, NEW_HISTORY_DIALOG_INPUT_SIZE, 0, nullptr, wxCB_READONLY); m_comboBox_nozzle_type->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &NewCalibrationHistoryDialog::on_select_nozzle_volume, this); - for (auto [volume_type, diameters] : CalibUtils::get_supported_nozzle_volume_and_diameters(curr_obj)) { + for (auto [volume_type, diameters] : CalibUtils::get_supported_nozzle_volume_and_diameters(curr_obj, false)) { m_comboBox_nozzle_type->Append(DevNozzle::GetNozzleVolumeTypeStr(volume_type), wxNullBitmap, new int{volume_type}); } m_comboBox_nozzle_type->SetSelection(-1); @@ -1063,12 +1063,10 @@ void NewCalibrationHistoryDialog::on_select_nozzle_volume(wxCommandEvent &event) m_comboBox_nozzle_diameter->Clear(); - auto volume_diamters_map = CalibUtils::get_supported_nozzle_volume_and_diameters(curr_obj); + auto volume_diamters_map = CalibUtils::get_supported_nozzle_volume_and_diameters(curr_obj, false); if (volume_diamters_map.find(volume_type) == volume_diamters_map.end()) return; for (auto diameter : volume_diamters_map[volume_type]) { - if (is_high_volume(volume_type) && diameter == NozzleDiameterType::NOZZLE_DIAMETER_0_2) continue; - m_comboBox_nozzle_diameter->Append(wxString::Format("%1.1f mm", DevNozzle::ToNozzleDiameterFloat(diameter)), wxNullBitmap, new int{diameter}); } diff --git a/src/slic3r/GUI/Calibration.cpp b/src/slic3r/GUI/Calibration.cpp index d4b1f5e001..ac241780a9 100644 --- a/src/slic3r/GUI/Calibration.cpp +++ b/src/slic3r/GUI/Calibration.cpp @@ -122,7 +122,7 @@ CalibrationDialog::CalibrationDialog(Plater *plater) wxBoxSizer *cali_right_sizer_h = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *cali_right_sizer_v = new wxBoxSizer(wxVERTICAL); - auto cali_right_panel = new StaticBox(body_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(182), FromDIP(200))); + auto cali_right_panel = new StaticBox(body_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(182), -1)); cali_right_panel->SetBackgroundColor(BG_COLOR); cali_right_panel->SetBorderColor(BG_COLOR); @@ -282,7 +282,7 @@ void CalibrationDialog::update_cali(MachineObject *obj) m_calibration_flow->Refresh(); Layout(); - + Fit(); } if (is_stage_list_info_changed(obj)) { // change items if stage_list_info changed diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.cpp b/src/slic3r/GUI/CalibrationWizardSavePage.cpp index 6c3f390b0d..8bf4461259 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.cpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.cpp @@ -55,36 +55,6 @@ static wxString get_default_name(wxString filament_name, CalibMode mode){ return filament_name; } -static wxString get_tray_name_by_tray_id(int tray_id) -{ - wxString tray_name; - - DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager(); - if (!dev) return tray_name; - - MachineObject *obj = dev->get_selected_machine(); - if (!obj) return tray_name; - - auto tray_ams_slot_map = obj->GetFilaSystem()->GetTrayIndexMap(); - - if (tray_id == VIRTUAL_TRAY_MAIN_ID || tray_id == VIRTUAL_TRAY_DEPUTY_ID) { - tray_name = "Ext"; - } else if (tray_ams_slot_map.find(tray_id) != tray_ams_slot_map.end()) { - int ams_id = tray_ams_slot_map[tray_id].first; - int slot_id = tray_ams_slot_map[tray_id].second; - - if (ams_id >= 128 && ams_id < 153) { - char prefix = 'A' + ams_id - 128; - tray_name = std::string(1, prefix); - } else { - char prefix = 'A' + ams_id; - char suffix = '0' + 1 + slot_id; - tray_name = std::string(1, prefix) + std::string(1, suffix); - } - } - return tray_name; -} - CalibrationCommonSavePage::CalibrationCommonSavePage(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : CalibrationWizardPage(parent, id, pos, size, style) { @@ -296,7 +266,7 @@ void CaliPASaveAutoPanel::sync_cali_result(const std::vector& cal wxBoxSizer* column_data_sizer = new wxBoxSizer(wxVERTICAL); auto tray_title = new Label(m_grid_panel, ""); tray_title->SetFont(Label::Head_14); - wxString tray_name = get_tray_name_by_tray_id(item.tray_id); + wxString tray_name = m_obj->GetFilaSystem()->GetTrayNameByTrayId(item.tray_id); tray_title->SetLabel(tray_name); auto k_value = new GridTextInput(m_grid_panel, "", "", CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, GridTextInputType::K, MAIN_EXTRUDER_ID); @@ -512,7 +482,7 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< m_multi_extruder_grid_panel->SetSizer(grid_sizer, true); m_multi_extruder_grid_panel->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { SetFocusIgnoringChildren(); }); - std::string cwsp_pt = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); + const std::string& cwsp_pt = m_obj->printer_type; wxStaticBoxSizer *left_sizer = new wxStaticBoxSizer(wxVERTICAL, m_multi_extruder_grid_panel, _L(DevPrinterConfigUtil::get_toolhead_display_name(cwsp_pt, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::SentenceCase))); wxStaticBoxSizer *right_sizer = new wxStaticBoxSizer(wxVERTICAL, m_multi_extruder_grid_panel, _L(DevPrinterConfigUtil::get_toolhead_display_name(cwsp_pt, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::SentenceCase))); grid_sizer->Add(left_sizer); @@ -633,7 +603,7 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< m_is_all_failed = false; } - wxString tray_name = get_tray_name_by_tray_id(item.tray_id); + wxString tray_name = m_obj->GetFilaSystem()->GetTrayNameByTrayId(item.tray_id); wxButton *tray_title = new wxButton(m_multi_extruder_grid_panel, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), wxBU_EXACTFIT | wxBU_AUTODRAW | wxBORDER_NONE); tray_title->SetBackgroundColour(*wxWHITE); tray_title->SetBitmap(*get_extruder_color_icon(full_filament_ams_list[item.tray_id].opt_string("filament_colour", 0u), tray_name.ToStdString(), FromDIP(20), FromDIP(20))); @@ -1395,7 +1365,7 @@ void CalibrationFlowX1SavePage::create_page(wxWindow* parent) m_top_sizer->Add(m_action_panel, 0, wxEXPAND, 0); } -void CalibrationFlowX1SavePage::sync_cali_result(const std::vector& cali_result) +void CalibrationFlowX1SavePage::sync_cali_result(MachineObject* obj, const std::vector& cali_result) { m_save_results.clear(); m_grid_panel->DestroyChildren(); @@ -1430,7 +1400,7 @@ void CalibrationFlowX1SavePage::sync_cali_result(const std::vectorSetFont(Label::Head_14); - wxString tray_name = get_tray_name_by_tray_id(item.tray_id); + wxString tray_name = obj->GetFilaSystem()->GetTrayNameByTrayId(item.tray_id); tray_title->SetLabel(tray_name); auto flow_ratio_value = new GridTextInput(m_grid_panel, "", "", CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, GridTextInputType::FlowRatio, MAIN_EXTRUDER_ID); @@ -1568,7 +1538,7 @@ bool CalibrationFlowX1SavePage::get_result(std::vectorGetCalib()->GetFlowRatioResult()); + sync_cali_result(curr_obj, curr_obj->GetCalib()->GetFlowRatioResult()); } } return wxPanel::Show(show); diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.hpp b/src/slic3r/GUI/CalibrationWizardSavePage.hpp index ed1aebcf56..e3c7a12a39 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.hpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.hpp @@ -216,7 +216,7 @@ class CalibrationFlowX1SavePage : public CalibrationCommonSavePage void create_page(wxWindow* parent); // sync widget value from cali flow rate result - void sync_cali_result(const std::vector& cali_result); + void sync_cali_result(MachineObject* obj, const std::vector& cali_result); void save_to_result_from_widgets(wxWindow* window, bool* out_is_valid, wxString* out_msg); bool get_result(std::vector>& out_results); bool is_all_failed() { return m_is_all_failed; } diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 8bfcb8f8cf..f991c30df9 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -1209,10 +1209,7 @@ bool build_support_recommended_config(const std::string& support_material, const const auto& rec_params = rec_params_opt.value(); - // Iterate all recommended params and set to config - for (const auto &[key, value] : rec_params.params.params) { - // Copy key to local variable for lambda capture (required for some compilers) - const std::string param_key = key; + for (const auto &[param_key, value] : rec_params.params.params) { auto opt_def_it = print_config_def.options.find(param_key); if (opt_def_it == print_config_def.options.end()) { @@ -1220,55 +1217,35 @@ bool build_support_recommended_config(const std::string& support_material, const continue; } - const ConfigOptionDef &opt_def = opt_def_it->second; + const ConfigOptionDef& opt_def = opt_def_it->second; - std::visit([&](auto &&val) { + std::string serialized = std::visit([](auto &&val) -> std::string { using T = std::decay_t; - - if constexpr (std::is_same_v) { - if (opt_def.type == coFloat || opt_def.type == coFloatOrPercent) { - out_config.set_key_value(param_key, new ConfigOptionFloat(val)); - } else if (opt_def.type == coPercent) { - out_config.set_key_value(param_key, new ConfigOptionPercent(val)); - } else if (opt_def.type == coInt) { - out_config.set_key_value(param_key, new ConfigOptionInt(static_cast(val))); - } + if constexpr (std::is_same_v) { + return val; } else if constexpr (std::is_same_v) { - if (opt_def.type == coBool) { - out_config.set_key_value(param_key, new ConfigOptionBool(val)); - } - } else if constexpr (std::is_same_v) { - if (opt_def.type == coString) { - out_config.set_key_value(param_key, new ConfigOptionString(val)); - } else if (opt_def.type == coEnum) { - ConfigOption *opt = opt_def.create_default_option(); - if (opt && opt->deserialize(val)) { - out_config.set_key_value(param_key, opt); - } else { - delete opt; - BOOST_LOG_TRIVIAL(warning) << "Failed to deserialize enum value for " << param_key << ": " << val; - } - } - } else if constexpr (std::is_same_v) { - if (opt_def.type == coInt) { - out_config.set_key_value(param_key, new ConfigOptionInt(val)); - } else if (opt_def.type == coFloat) { - out_config.set_key_value(param_key, new ConfigOptionFloat(static_cast(val))); - } + return val ? "1" : "0"; } else if constexpr (std::is_same_v>) { - if (opt_def.type == coFloats) { - out_config.set_key_value(param_key, new ConfigOptionFloats(val)); - } else if (opt_def.type == coFloatsOrPercents) { - std::vector fop_vec; - for (double v : val) { - fop_vec.push_back(FloatOrPercent{v, false}); - } - out_config.set_key_value(param_key, new ConfigOptionFloatsOrPercents(fop_vec)); - } else if (opt_def.type == coPercents) { - out_config.set_key_value(param_key, new ConfigOptionPercents(val)); + std::ostringstream ss; + for (size_t i = 0; i < val.size(); ++i) { + if (i > 0) ss << ","; + ss << val[i]; } + return ss.str(); + } else { + std::ostringstream ss; + ss << val; + return ss.str(); } }, value); + + ConfigOption *opt = opt_def.create_default_option(); + if (opt && opt->deserialize(serialized)) { + out_config.set_key_value(param_key, opt); + }else { + delete opt; + BOOST_LOG_TRIVIAL(warning) << "Failed to deserialize recommended param " << param_key << ": " << serialized; + } } return true; diff --git a/src/slic3r/GUI/DeviceCore/DevCalib.h b/src/slic3r/GUI/DeviceCore/DevCalib.h index d89841422b..4dadfdf976 100644 --- a/src/slic3r/GUI/DeviceCore/DevCalib.h +++ b/src/slic3r/GUI/DeviceCore/DevCalib.h @@ -29,7 +29,7 @@ class DevCalib protected: bool m_support_new_auto_cali{false}; int m_calib_version {-1}; - int m_last_calib_version {-1}; + int m_last_calib_version {0}; public: DevCalib(MachineObject *obj) : m_owner(obj){}; @@ -53,7 +53,7 @@ class DevCalib int GetCalibVersion() const {return m_calib_version;} void SyncCalibVersion() { m_last_calib_version = m_calib_version;} - void ResetCalibVersion() {m_last_calib_version = -1;} + void ResetCalibVersion() {m_last_calib_version = 0;} bool IsVersionExpired() const; bool IsVersionInited() const { return m_calib_version > -1;} diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp b/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp index 7a301d2bd7..06c3d61bed 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp @@ -384,6 +384,30 @@ int DevFilaSystem::GetTrayIdByAmsSlotId(int ams_id, int slot_id) return -1; } +std::string DevFilaSystem::GetTrayNameByTrayId(int tray_id) +{ + std::string tray_name; + + auto tray_ams_slot_map = GetTrayIndexMap(); + + if (tray_id == VIRTUAL_TRAY_MAIN_ID || tray_id == VIRTUAL_TRAY_DEPUTY_ID) { + tray_name = "Ext"; + } else if (tray_ams_slot_map.find(tray_id) != tray_ams_slot_map.end()) { + int ams_id = tray_ams_slot_map[tray_id].first; + int slot_id = tray_ams_slot_map[tray_id].second; + + if (ams_id >= 128 && ams_id < 153) { + char prefix = 'A' + ams_id - 128; + tray_name = std::string(1, prefix); + } else { + char prefix = 'A' + ams_id; + char suffix = '0' + 1 + slot_id; + tray_name = std::string(1, prefix) + std::string(1, suffix); + } + } + return tray_name; +} + int DevFilaSystem::GetExtruderIdByAmsId(const std::string& ams_id) const { auto it = amsList.find(ams_id); diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSystem.h b/src/slic3r/GUI/DeviceCore/DevFilaSystem.h index dc63826cb7..aa00cc841c 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaSystem.h +++ b/src/slic3r/GUI/DeviceCore/DevFilaSystem.h @@ -282,6 +282,7 @@ class DevFilaSystem std::map GetTrayIndexMap(); int GetTrayIdByAmsSlotId(int ams_id, int slot_id); + std::string GetTrayNameByTrayId(int tray_id); // extruder int GetExtruderIdByAmsId(const std::string& ams_id) const; diff --git a/src/slic3r/GUI/DeviceCore/DevManager.cpp b/src/slic3r/GUI/DeviceCore/DevManager.cpp index 177084e451..add253964b 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.cpp +++ b/src/slic3r/GUI/DeviceCore/DevManager.cpp @@ -15,6 +15,8 @@ #include "slic3r/GUI/DeviceManager.hpp" #include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/MainFrame.hpp" +#include "slic3r/GUI/DeviceWeb/DeviceWebPage.hpp" #include "slic3r/Utils/BBLUtil.hpp" #include "libslic3r/Time.hpp" @@ -844,6 +846,15 @@ namespace Slic3r GUI::wxGetApp().sidebar().update_sync_status(obj_); GUI::wxGetApp().sidebar().load_ams_list(obj_); }; + + // F4.7: keep the filament-manager web page in sync with the + // Studio-wide machine selection. Safe to call during early startup / + // shutdown: the target pointers may be null and we check every hop. + if (GUI::MainFrame* mf = GUI::wxGetApp().mainframe) { + if (GUI::DeviceWebPage* web = mf->web_device()) { + web->NotifyFilamentMachineChanged(); + } + } } void DeviceManager::reload_printer_settings() diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index f21bfb91a2..82a1fff1f7 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -2973,6 +2973,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ is_enable_ams_np = get_flag_bits(flag3, 9); is_support_fila_change_abort = get_flag_bits(flag3, 13); is_support_ext_change_assist_old = get_flag_bits(flag3, 16); + is_support_filament_32_colors = get_flag_bits(flag3, 17); } } if (!key_field_only) { @@ -4181,6 +4182,14 @@ bool MachineObject::check_enable_np(const json& print) const return false; } +int MachineObject::get_max_filament_color_count() const +{ + if (is_support_filament_32_colors) return 32; + if (is_enable_ams_np && !is_series_x()) return 20; + if (!is_series_x() && !is_series_o()) return 16; + return 0; +} + void MachineObject::parse_new_info(json print) { is_enable_np = check_enable_np(print); @@ -4297,6 +4306,7 @@ void MachineObject::parse_new_info(json print) is_support_remote_dry = (get_flag_bits_no_border(fun2, 5) == 1); is_support_active_arc_fitting = (get_flag_bits_no_border(fun2, 8) == 1); is_support_check_track_switch_match_slice_printer = (get_flag_bits_no_border(fun2, 19) == 1); + ams_preload_version = static_cast(get_flag_bits_no_border(fun2, 21, 2)); if (DevPrinterConfigUtil::support_print_check_firmware_for_tpu_left(printer_type)) { m_firmware_support_print_tpu_left = DevUtil::get_flag_bits_no_border(fun2, 7) == 1; @@ -4507,7 +4517,7 @@ void MachineObject::update_filament_list() for (auto it = filament_list.begin(); it != filament_list.end(); it++) { if (m_filament_list.find(it->first) != m_filament_list.end()) { - assert(it->first.size() == 8 && it->first[0] == 'P'); + // assert(it->first.size() == 8 && it->first[0] == 'P'); if (it->second.first != m_filament_list[it->first].first) { BOOST_LOG_TRIVIAL(info) << "old min temp is not equal to new min temp and filament id: " << it->first; diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 02683eeea7..6dc8337ee3 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -557,6 +557,7 @@ class MachineObject bool is_support_active_arc_fitting{false}; bool is_support_liveview_preview{false}; bool is_support_check_track_switch_match_slice_printer{ false }; + int ams_preload_version{0}; bool installed_upgrade_kit{false}; int bed_temperature_limit = -1; @@ -759,6 +760,11 @@ class MachineObject /*for more extruder*/ bool is_enable_np{ false }; bool is_enable_ams_np{ false }; + bool is_support_filament_32_colors{ false }; + + // Returns the maximum filament color count allowed to be sent to this printer. + // Returns 0 when there is no explicit upper bound (legacy behavior for is_enable_np). + int get_max_filament_color_count() const; /*vi slot data*/ std::vector vt_slot; diff --git a/src/slic3r/GUI/DeviceWeb/CMakeLists.txt b/src/slic3r/GUI/DeviceWeb/CMakeLists.txt new file mode 100644 index 0000000000..3ac816c8b7 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/CMakeLists.txt @@ -0,0 +1,20 @@ +# GUI/DeviceWeb +# usage -- GUI about device web for BambuStudio +# date -- 2025.01.01 +# status -- Building + +list(APPEND SLIC3R_GUI_SOURCES + GUI/DeviceWeb/DeviceHttpServer.cpp + GUI/DeviceWeb/DeviceHttpServer.hpp + GUI/DeviceWeb/DeviceWebPage.cpp + GUI/DeviceWeb/DeviceWebPage.hpp + GUI/DeviceWeb/DeviceWebBridge.cpp + GUI/DeviceWeb/DeviceWebBridge.hpp + GUI/DeviceWeb/DeviceWebModel.hpp + GUI/DeviceWeb/IViewModel.hpp + GUI/DeviceWeb/DeviceWebManager.cpp + GUI/DeviceWeb/DeviceWebManager.hpp + GUI/DeviceWeb/FilaManagerVM.cpp + GUI/DeviceWeb/FilaManagerVM.hpp +) +set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceWeb/DeviceHttpServer.cpp b/src/slic3r/GUI/DeviceWeb/DeviceHttpServer.cpp new file mode 100644 index 0000000000..c604b77419 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceHttpServer.cpp @@ -0,0 +1,244 @@ +#include "DeviceHttpServer.hpp" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "libslic3r/Utils.hpp" + +namespace Slic3r { namespace GUI { + +// --------------------------------------------------------------------------- +// HTTP helpers (file-local) +// --------------------------------------------------------------------------- + +static std::string mime_type(const std::string &ext) +{ + static const std::unordered_map tbl = { + {".html","text/html"}, {".htm","text/html"}, + {".css","text/css"}, + {".js","application/javascript"}, + {".png","image/png"}, {".jpg","image/jpeg"}, {".jpeg","image/jpeg"}, + {".gif","image/gif"}, {".svg","image/svg+xml"} + }; + auto it = tbl.find(ext); + return (it != tbl.end()) ? it->second : "application/octet-stream"; +} + +static std::string response_404() +{ + std::string body = "

404 Not Found

"; + std::ostringstream ss; + ss << "HTTP/1.1 404 Not Found\r\n" + << "Content-Type: text/html\r\n" + << "Content-Length: " << body.size() << "\r\n\r\n" + << body; + return ss.str(); +} + +// --------------------------------------------------------------------------- +// DeviceHttpHeaders — simple HTTP/1.1 request parser +// --------------------------------------------------------------------------- + +class DeviceHttpHeaders +{ + std::string method; + std::string url; + std::string version; + std::map headers; + +public: + std::string get_response() + { + std::filesystem::path root = resources_dir() + "/web/device_page/dist"; + + if (url.empty() || url.find("..") != std::string::npos) + return response_404(); + + // Strip query string before resolving file path + std::string path = url; + auto qpos = path.find('?'); + if (qpos != std::string::npos) + path = path.substr(0, qpos); + + std::filesystem::path rel = (path == "/") ? "/index.html" : path; + std::filesystem::path full = std::filesystem::weakly_canonical(root / rel.relative_path()); + + if (full.generic_string().rfind(std::filesystem::weakly_canonical(root).generic_string(), 0) != 0) + return response_404(); + + std::ifstream file(full, std::ios::binary); + if (!file) + return response_404(); + + std::string body((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + std::ostringstream ss; + ss << "HTTP/1.1 200 OK\r\n" + << "Content-Type: " << mime_type(full.extension().string()) << "\r\n" + << "Content-Length: " << body.size() << "\r\n\r\n" + << body; + return ss.str(); + } + + int content_length() + { + auto it = headers.find("content-length"); + if (it != headers.end()) { + int len = 0; + std::istringstream(it->second) >> len; + return len; + } + return 0; + } + + void on_read_header(const std::string &line) + { + auto pos = line.find(':'); + if (pos != std::string::npos) + headers[line.substr(0, pos)] = line.substr(pos + 1); + } + + void on_read_request_line(const std::string &line) + { + std::istringstream ss(line); + ss >> method >> url >> version; + } +}; + +// --------------------------------------------------------------------------- +// DeviceSession — one accepted connection +// --------------------------------------------------------------------------- + +class DeviceSession : public std::enable_shared_from_this +{ + boost::asio::ip::tcp::socket socket_; + boost::asio::streambuf buff_; + DeviceHttpHeaders headers_; + + void read_first_line() + { + auto self = shared_from_this(); + boost::asio::async_read_until(socket_, buff_, '\r', + [self](const boost::system::error_code &ec, std::size_t) { + if (ec) return; + std::istream stream{&self->buff_}; + std::string line, ignore; + std::getline(stream, line, '\r'); + std::getline(stream, ignore, '\n'); + self->headers_.on_read_request_line(line); + self->read_next_line(); + }); + } + + void read_next_line() + { + auto self = shared_from_this(); + boost::asio::async_read_until(socket_, buff_, '\r', + [self](const boost::system::error_code &ec, std::size_t) { + if (ec) return; + std::istream stream{&self->buff_}; + std::string line, ignore; + std::getline(stream, line, '\r'); + std::getline(stream, ignore, '\n'); + self->headers_.on_read_header(line); + + if (line.empty()) { + self->send_response(); + } else { + self->read_next_line(); + } + }); + } + + void send_response() + { + auto self = shared_from_this(); + auto resp = std::make_shared(headers_.get_response()); + boost::asio::async_write(socket_, boost::asio::buffer(*resp), + [self, resp](const boost::system::error_code &, std::size_t) { + boost::system::error_code ec; + self->socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + }); + } + +public: + explicit DeviceSession(boost::asio::ip::tcp::socket socket) + : socket_(std::move(socket)) {} + + void start() { read_first_line(); } +}; + +// --------------------------------------------------------------------------- +// DeviceHttpServer +// --------------------------------------------------------------------------- + +DeviceHttpServer::DeviceHttpServer() = default; + +DeviceHttpServer::~DeviceHttpServer() +{ + stop(); +} + +void DeviceHttpServer::start() +{ + BOOST_LOG_TRIVIAL(info) << "[DeviceHttpServer] starting on port " << DEVICE_LOCALHOST_PORT; + if (running_.exchange(true)) + return; // already running + + using tcp = boost::asio::ip::tcp; + guard_ = std::make_unique(io_.get_executor()); + + boost::system::error_code ec; + tcp::endpoint ep{tcp::v4(), DEVICE_LOCALHOST_PORT}; + acceptor_.open(ep.protocol(), ec); + if (ec) { BOOST_LOG_TRIVIAL(error) << "[DeviceHttpServer] open failed: " << ec.message(); running_ = false; return; } + acceptor_.set_option(tcp::acceptor::reuse_address(true), ec); + acceptor_.bind(ep, ec); + if (ec) { BOOST_LOG_TRIVIAL(error) << "[DeviceHttpServer] bind failed: " << ec.message(); acceptor_.close(); running_ = false; return; } + acceptor_.listen(boost::asio::socket_base::max_listen_connections, ec); + if (ec) { BOOST_LOG_TRIVIAL(error) << "[DeviceHttpServer] listen failed: " << ec.message(); acceptor_.close(); running_ = false; return; } + + do_accept(); + worker_ = boost::thread([this] { io_.run(); }); + BOOST_LOG_TRIVIAL(info) << "[DeviceHttpServer] started"; +} + +void DeviceHttpServer::stop() +{ + if (!running_.exchange(false)) + return; // not running + + BOOST_LOG_TRIVIAL(info) << "[DeviceHttpServer] stopping"; + boost::system::error_code ec; + acceptor_.close(ec); + io_.stop(); + if (guard_) guard_.reset(); + if (worker_.joinable()) worker_.join(); + io_.restart(); // allow re-start if needed + BOOST_LOG_TRIVIAL(info) << "[DeviceHttpServer] stopped"; +} + +void DeviceHttpServer::do_accept() +{ + acceptor_.async_accept( + [this](boost::system::error_code ec, boost::asio::ip::tcp::socket socket) { + if (!ec && running_) { + std::make_shared(std::move(socket))->start(); + } + if (running_) { + do_accept(); + } + }); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceWeb/DeviceHttpServer.hpp b/src/slic3r/GUI/DeviceWeb/DeviceHttpServer.hpp new file mode 100644 index 0000000000..2a3c76d8af --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceHttpServer.hpp @@ -0,0 +1,42 @@ +#ifndef __DEVICE_HTTP_SERVER_HPP__ +#define __DEVICE_HTTP_SERVER_HPP__ + +#include +#include +#include + +#include +#include +#include +#include + +#define DEVICE_LOCALHOST_PORT 13628 +#define DEVICE_LOCALHOST_URL "http://localhost:" + +namespace Slic3r { namespace GUI { + +class DeviceHttpServer +{ +public: + DeviceHttpServer(); + ~DeviceHttpServer(); + + bool is_started() const { return running_.load(); } + void start(); + void stop(); + +private: + void do_accept(); + + using work_guard_t = boost::asio::executor_work_guard; + + std::atomic_bool running_{false}; + boost::asio::io_context io_{1}; + std::unique_ptr guard_; + boost::asio::ip::tcp::acceptor acceptor_{io_}; + boost::thread worker_; +}; + +}} // namespace Slic3r::GUI + +#endif //__DEVICE_HTTP_SERVER_HPP__ diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebBridge.cpp b/src/slic3r/GUI/DeviceWeb/DeviceWebBridge.cpp new file mode 100644 index 0000000000..1da6ad8b32 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebBridge.cpp @@ -0,0 +1,196 @@ +#include "DeviceWebBridge.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include + +namespace Slic3r { namespace GUI { + +DeviceWebBridge::DeviceWebBridge(wxWebView* webView) +{ + #if !BBL_RELEASE_TO_PUBLIC + webView->EnableAccessToDevTools(true); + webView->EnableContextMenu(true); + #endif + + m_web = webView; + m_web->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &DeviceWebBridge::OnWebMsg, this); + m_web->Bind(wxEVT_WEBVIEW_NAVIGATING, &DeviceWebBridge::OnWebNav, this); + m_web->Bind(wxEVT_WEBVIEW_LOADED, &DeviceWebBridge::OnWebLoaded, this); +} + +DeviceWebBridge::~DeviceWebBridge() +{ + if (m_web) { + m_web->Unbind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &DeviceWebBridge::OnWebMsg, this); + m_web->Unbind(wxEVT_WEBVIEW_NAVIGATING, &DeviceWebBridge::OnWebNav, this); + m_web->Unbind(wxEVT_WEBVIEW_LOADED, &DeviceWebBridge::OnWebLoaded, this); + } +} + +void DeviceWebBridge::OnWebLoaded(wxWebViewEvent& /*e*/) +{ + InitBridge(); +} + +void DeviceWebBridge::InitBridge() +{ + std::string bridge = R"JS( + if (!window.__cppPush) { + window.__cppPush = function(pkt){ + try { + document.dispatchEvent( + new CustomEvent('cpp:' + pkt.event, { detail: pkt }) + ); + } catch(e){ console.error(e); } + }; + } + )JS"; + +#if !BBL_RELEASE_TO_PUBLIC + // Internal build: signal to the frontend that debug panel should be shown + // regardless of whether init() succeeds or the user is logged in. + bridge += R"JS( + window.__internalBuild = true; + )JS"; +#endif + + WebView::RunScript(m_web, wxString(bridge)); +} + +bool DeviceWebBridge::ValidateJson(const nlohmann::json& j) +{ + if (j.is_discarded()) { + BOOST_LOG_TRIVIAL(warning) << "json from web command parse error"; + return false; + } + if (!j.contains("head")) { + BOOST_LOG_TRIVIAL(warning) << "json from web missing head field"; + return false; + } + if (!j.contains("body")) { + BOOST_LOG_TRIVIAL(warning) << "json from web missing body field"; + return false; + } + return true; +} + +void DeviceWebBridge::OnWebNav(wxWebViewEvent& e) +{ + auto url = e.GetURL(); + if (!url.StartsWith("app://")) return; + + // The JS side sends: iframe.src = "app://" + encodeURIComponent(json) + // We cannot rely on wxURI::GetPath() because "app://" makes + // wxURI treat the encoded JSON as the host/authority part (after "//"). + // Instead, directly strip the "app://" prefix and URL-decode the rest. + wxString payload = url.Mid(6); // skip "app://" + std::string raw = wxURI::Unescape(payload).ToUTF8().data(); + + nlohmann::json j = nlohmann::json::parse(raw, nullptr, false); + if (ValidateJson(j)) { + DispatchWebCommand(j["head"], j["body"]); + } + + e.Veto(); +} + +void DeviceWebBridge::OnWebMsg(wxWebViewEvent& e) +{ + // ToStdString() uses the current C locale, which on Windows CJK builds + // mangles non-ASCII characters (Chinese notes, emoji, etc.) before the + // JSON parser sees them. Force UTF-8 to match the C++->JS direction + // (SendMsg uses wxString::FromUTF8). + const std::string raw = e.GetString().ToUTF8().data(); + nlohmann::json j = nlohmann::json::parse(raw, nullptr, false); + if (ValidateJson(j)) { + DispatchWebCommand(j["head"], j["body"]); + } +} + +bool DeviceWebBridge::ValidateHeader(const Header& head) +{ + if (head.version != DEVICE_WEB_BRIDGE_VERSION) { + BOOST_LOG_TRIVIAL(warning) << "web command version not support"; + return false; + } + return true; +} + +void DeviceWebBridge::DispatchWebCommand(const nlohmann::json& header, const nlohmann::json& body) +{ + Header head; + try { + head = header.get
(); + } catch (const nlohmann::json::exception& e) { + BOOST_LOG_TRIVIAL(warning) << "DeviceWebBridge: malformed header: " << e.what(); + return; + } + if (head.type != MsgType::Request) return; + if (!ValidateHeader(head)) return; + +#if !BBL_RELEASE_TO_PUBLIC + if (body.value("module", std::string()) == "filament") { + wxGetApp().emit_fila_debug_log( + "bridge", + "info", + "Web request received by C++", + "DeviceWebBridge accepted a filament request from the web page", + { + {"submod", body.value("submod", std::string())}, + {"action", body.value("action", std::string())}, + {"payload", body.contains("payload") ? body["payload"] : nlohmann::json::object()} + }); + } +#endif + + // Wrap the dispatch in a catch-all so an exception inside a ViewModel + // (e.g. FilamentSpool::from_json on malformed payload) cannot silently + // swallow the response: the web side would otherwise wait until its 5s + // request timeout with no clue why the call failed. + if (m_vm_mgr) { + try { + auto result = m_vm_mgr->Dispatch(body); + if (result.has_value()) { + ResponseMsg(head, result.value()); + return; + } + } catch (const std::exception& e) { + const std::string mod = body.value("module", std::string("(unknown)")); + const std::string submod = body.value("submod", std::string("(unknown)")); + const std::string action = body.value("action", std::string("(unknown)")); + BOOST_LOG_TRIVIAL(error) << "DeviceWebBridge: exception while dispatching " + << mod << "/" << submod << "/" << action + << ": " << e.what(); + if (mod == "filament") { + wxGetApp().emit_fila_debug_log( + "bridge", "error", + "C++ dispatch threw", + "A ViewModel threw while handling a web request; an error response was returned so the UI does not stall", + { + {"submod", submod}, {"action", action}, + {"what", e.what()}, + {"payload", body.contains("payload") ? body["payload"] : nlohmann::json::object()} + }); + } + nlohmann::json err_resp = { + {"module", mod}, {"submod", submod}, {"action", action}, + {"error_code", 2}, + {"message", std::string("C++ exception: ") + e.what()} + }; + ResponseMsg(head, err_resp); + return; + } + } + +#if !BBL_RELEASE_TO_PUBLIC + std::string mod = body.value("module", "(unknown)"); + std::string submod = body.value("func", "(unknown)"); + BOOST_LOG_TRIVIAL(warning) << "DeviceWebBridge: no handler for module='" << mod << "' submod='" << submod << "'"; +#endif + nlohmann::json err_resp = { + {"error_code", 1}, + {"message", "unknown module or submod"} + }; + ResponseMsg(head, err_resp); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebBridge.hpp b/src/slic3r/GUI/DeviceWeb/DeviceWebBridge.hpp new file mode 100644 index 0000000000..98e0c3d437 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebBridge.hpp @@ -0,0 +1,79 @@ +#ifndef DEVICEWEBBRIDGE_HPP +#define DEVICEWEBBRIDGE_HPP + +#include "wx/webview.h" + +#if wxUSE_WEBVIEW_EDGE +#include "wx/msw/webview_edge.h" +#endif + +#include +#include +#include +#include +#include + +#include "slic3r/GUI/Widgets/WebView.hpp" +#include "DeviceWebModel.hpp" +#include "DeviceWebManager.hpp" + +namespace Slic3r { namespace GUI { + +static constexpr const char* DEVICE_WEB_BRIDGE_VERSION = "1.0"; + +class DeviceWebBridge +{ +private: + std::atomic m_seq{0}; + wxWebView* m_web{nullptr}; + DeviceWebManager* m_vm_mgr{nullptr}; + + static inline std::uint64_t TimeNowMs() { + return static_cast(std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count()); + } + + template + void SendMsg(const Header& head, T&& params) + { + nlohmann::json j; + j["event"] = "device"; + j["head"] = head; + j["body"] = std::forward(params); + std::string script = "window.__cppPush(" + j.dump() + ");"; + WebView::RunScript(m_web, wxString::FromUTF8(script)); + } + + void InitBridge(); + void OnWebLoaded(wxWebViewEvent& e); + void OnWebNav(wxWebViewEvent& e); + void OnWebMsg(wxWebViewEvent& e); + bool ValidateJson(const nlohmann::json& j); + bool ValidateHeader(const Header& head); + void DispatchWebCommand(const nlohmann::json& header, const nlohmann::json& body); + +public: + DeviceWebBridge(wxWebView* webView); + ~DeviceWebBridge(); + + void SetManager(DeviceWebManager* mgr) { m_vm_mgr = mgr; } + + /* C++ → Web: report state change */ + template + void ReportMsg(T&& params) { + Header head{DEVICE_WEB_BRIDGE_VERSION, MsgType::Report, m_seq++, TimeNowMs()}; + SendMsg(head, std::forward(params)); + } + + /* C++ → Web: respond to a frontend request (ack) */ + template + void ResponseMsg(Header head, T&& params) { + head.type = MsgType::Response; + head.ts = TimeNowMs(); + SendMsg(head, std::forward(params)); + } +}; + +}} // namespace Slic3r::GUI + +#endif // DEVICEWEBBRIDGE_HPP diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebManager.cpp b/src/slic3r/GUI/DeviceWeb/DeviceWebManager.cpp new file mode 100644 index 0000000000..de42210065 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebManager.cpp @@ -0,0 +1,65 @@ +// src/slic3r/GUI/DeviceWeb/DeviceWebManager.cpp +#include "DeviceWebManager.hpp" +#include "IViewModel.hpp" +#include "DeviceWebBridge.hpp" + +#include + +namespace Slic3r { namespace GUI { + +void DeviceWebManager::Register(std::unique_ptr vm) +{ + auto mod = vm->GetModule(); + BOOST_LOG_TRIVIAL(info) << "DeviceWebManager: register module '" << mod << "'"; + m_vms[mod] = std::move(vm); +} + +std::optional DeviceWebManager::Dispatch(const nlohmann::json& body) +{ + if (!body.contains("module") || !body.contains("submod") || !body.contains("action")) { + BOOST_LOG_TRIVIAL(warning) << "DeviceWebManager: missing module/submod/action in body"; + return std::nullopt; + } + + std::string mod = body["module"].get(); + std::string submod = body["submod"].get(); + std::string action = body["action"].get(); + + auto it = m_vms.find(mod); + if (it == m_vms.end()) { + BOOST_LOG_TRIVIAL(warning) << "DeviceWebManager: unknown module '" << mod << "'"; + return std::nullopt; + } + + nlohmann::json payload = body.contains("payload") ? body["payload"] : nlohmann::json::object(); + return it->second->OnCommand(submod, action, payload); +} + +void DeviceWebManager::SetBridge(DeviceWebBridge* bridge) +{ + for (auto& [name, vm] : m_vms) { + vm->SetBridge(bridge); + } +} + +void DeviceWebManager::NotifyColorChanged() +{ + for (auto& [name, vm] : m_vms) { + vm->OnSysColorChanged(); + } +} + +void DeviceWebManager::NotifyState(const std::string& module, + const std::string& submod, + const std::string& action) +{ + auto it = m_vms.find(module); + if (it == m_vms.end()) { + BOOST_LOG_TRIVIAL(warning) << "DeviceWebManager: cannot notify unknown module '" << module << "'"; + return; + } + + it->second->ReportState(submod, action); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebManager.hpp b/src/slic3r/GUI/DeviceWeb/DeviceWebManager.hpp new file mode 100644 index 0000000000..d134326e17 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebManager.hpp @@ -0,0 +1,47 @@ +// src/slic3r/GUI/DeviceWeb/DeviceWebManager.hpp +#ifndef DEVICEWEBMANAGER_HPP +#define DEVICEWEBMANAGER_HPP + +#include +#include +#include +#include +#include + +namespace Slic3r { namespace GUI { + +class IViewModel; +class DeviceWebBridge; + +class DeviceWebManager { +public: + DeviceWebManager() = default; + ~DeviceWebManager() = default; + + // Register a ViewModel. The manager takes ownership. + void Register(std::unique_ptr vm); + + // Route a web command to the matching ViewModel. + // Returns the response body JSON, or nullopt if no module matched. + std::optional Dispatch( + const nlohmann::json& body + ); + + // Set the SDK reference on all registered ViewModels. + void SetBridge(DeviceWebBridge* bridge); + + // Notify all registered ViewModels that the system colour mode changed. + void NotifyColorChanged(); + + // Ask one module to push its current state to the frontend bridge. + void NotifyState(const std::string& module, + const std::string& submod, + const std::string& action); + +private: + std::unordered_map> m_vms; +}; + +}} // namespace Slic3r::GUI + +#endif // DEVICEWEBMANAGER_HPP diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebModel.hpp b/src/slic3r/GUI/DeviceWeb/DeviceWebModel.hpp new file mode 100644 index 0000000000..327e8ac36d --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebModel.hpp @@ -0,0 +1,70 @@ +#ifndef DEVICEWEBMODEL_H +#define DEVICEWEBMODEL_H + +#include +#include +#include + +namespace Slic3r { +namespace GUI { + +enum class MsgType { Request, Response, Report }; + +/** + * Message header — the "envelope" wrapping every C++ <-> Web packet. + * + * Wire format (JSON): + * { "version": "1.0", "type": "request", "seq": 42, "ts": 1713300000000 } + * + * Fields: + * version Protocol version string. Both sides must match. + * type Message direction: + * "request" — Web -> C++ (frontend initiates a command) + * "response" — C++ -> Web (reply to a specific request, matched by seq) + * "report" — C++ -> Web (unsolicited push, e.g. state update) + * seq Sequence number. Assigned by the sender; responses echo the + * request's seq so the frontend can match Promise callbacks. + * ts Timestamp in milliseconds since epoch. Informational only. + */ +struct Header +{ + std::string version; + MsgType type{MsgType::Request}; + std::uint64_t seq{0}; + std::uint64_t ts{0}; +}; + +inline void to_json(nlohmann::json& j, const Header& h) +{ + std::string type_str; + switch (h.type) { + case MsgType::Request: type_str = "request"; break; + case MsgType::Response: type_str = "response"; break; + case MsgType::Report: type_str = "report"; break; + default: throw nlohmann::detail::other_error::create(501, "invalid MsgType value", nlohmann::json{}); + } + j = nlohmann::json{ + {"version", h.version}, + {"type", type_str}, + {"seq", h.seq}, + {"ts", h.ts} + }; +} + +inline void from_json(const nlohmann::json& j, Header& h) +{ + j.at("version").get_to(h.version); + j.at("seq").get_to(h.seq); + j.at("ts").get_to(h.ts); + + std::string type_str; + j.at("type").get_to(type_str); + if (type_str == "response") h.type = MsgType::Response; + else if (type_str == "report") h.type = MsgType::Report; + else if (type_str == "request") h.type = MsgType::Request; + else throw nlohmann::detail::other_error::create(501, "unknown MsgType: " + type_str, j); +} + +}} // namespace Slic3r::GUI + +#endif // DEVICEWEBMODEL_H diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebPage.cpp b/src/slic3r/GUI/DeviceWeb/DeviceWebPage.cpp new file mode 100644 index 0000000000..2dfc3ade6f --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebPage.cpp @@ -0,0 +1,131 @@ +#include "slic3r/GUI/wxExtensions.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/MainFrame.hpp" +#include "libslic3r/Utils.hpp" +#include "libslic3r_version.h" +#include "DeviceWebPage.hpp" + +#if defined(__WXOSX__) +#include "slic3r/Utils/MacDarkMode.hpp" +#endif + +#include +#include +#include + +namespace Slic3r { namespace GUI { + +// In release builds, always use file:// protocol. +// In debug builds, enable HTTP server toolbar for hot-reload development. +#if !BBL_RELEASE_TO_PUBLIC +#define DEVICE_USE_HTTP_SERVER +#endif + +DeviceWebPage::DeviceWebPage(wxWindow *parent): wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) +{ +#ifdef DEVICE_USE_HTTP_SERVER + m_device_http_server = std::make_unique(); +#endif + + m_device_webview = new PrinterWebView(this); + m_device_web_bridge = std::make_unique(m_device_webview->GetWebView()); + + // Create ViewModel infrastructure + m_device_web_mgr = std::make_unique(); + m_device_web_mgr->Register(std::make_unique()); + m_device_web_mgr->SetBridge(m_device_web_bridge.get()); + + m_device_web_bridge->SetManager(m_device_web_mgr.get()); + + auto web_sizer = new wxBoxSizer(wxVERTICAL); + web_sizer->Add(m_device_webview, 1, wxEXPAND); + + LoadUrl(); + + SetSizer(web_sizer); + Layout(); + Fit(); +} + +DeviceWebPage::~DeviceWebPage() +{ + // Disconnect cross-references before destruction + if (m_device_web_bridge) m_device_web_bridge->SetManager(nullptr); + if (m_device_web_mgr) m_device_web_mgr->SetBridge(nullptr); + + // unique_ptr members are released automatically in reverse declaration order +} + +void DeviceWebPage::LoadUrl() +{ + // Get current studio language for frontend i18n + std::string lang = wxGetApp().app_config->get("language"); + if (lang.empty()) lang = "en"; + + // Load the web app +#ifdef DEVICE_USE_HTTP_SERVER + if(!m_device_http_server->is_started()){ + m_device_http_server->start(); + } + wxString url = wxString::Format("http://localhost:13628/index.html?lang=%s", lang); +#else + wxString url = wxString::Format("file://%s/web/device_page/dist/index.html?lang=%s", from_u8(resources_dir()), lang); +#endif + + m_device_webview->load_url(url); +} + +void DeviceWebPage::on_sys_color_changed() +{ + if (m_device_web_mgr) + m_device_web_mgr->NotifyColorChanged(); +} + +void DeviceWebPage::msw_rescale() +{ + // WebView content scales via browser zoom — no native wx controls to rescale +} + +void DeviceWebPage::NavigateTo(const std::string& path) +{ +#if defined(__WXOSX__) + // macOS: wxWebView::RunScript can block the UI thread for a long time on WKWebView (STUDIO-18111). + // Use async evaluateJavaScript; other platforms keep synchronous RunScript. + wxWebView* wv = m_device_webview ? m_device_webview->GetWebView() : nullptr; + if (!wv) + return; + const wxString p = wxString::FromUTF8(path); + const wxString script = wxString::Format( + "try{var t='#%s';if(window.location.hash!==t)window.location.hash=t;}catch(e){}", p); + void* native = wv->GetNativeBackend(); + if (native) + WKWebView_evaluateJavaScript(native, script, nullptr); + else + wv->RunScript(script); +#else + if (auto* wv = m_device_webview->GetWebView()) { + const wxString p = wxString::FromUTF8(path); + wv->RunScript(wxString::Format( + "try{var t='#%s';if(window.location.hash!==t)window.location.hash=t;}catch(e){}", p)); + } +#endif +} + +void DeviceWebPage::NotifyFilamentSessionState() +{ + if (!m_device_web_mgr) + return; + + m_device_web_mgr->NotifyState("filament", "sync", "state"); + m_device_web_mgr->NotifyState("filament", "spool", "list"); +} + +void DeviceWebPage::NotifyFilamentMachineChanged() +{ + if (!m_device_web_mgr) + return; + + m_device_web_mgr->NotifyState("filament", "machine", "selected_changed"); +} + +}} diff --git a/src/slic3r/GUI/DeviceWeb/DeviceWebPage.hpp b/src/slic3r/GUI/DeviceWeb/DeviceWebPage.hpp new file mode 100644 index 0000000000..0b40d6000a --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/DeviceWebPage.hpp @@ -0,0 +1,57 @@ +#ifndef DEVICEWEBPAGE_H +#define DEVICEWEBPAGE_H + + +#include + +#include + +#include "DeviceHttpServer.hpp" +#include "DeviceWebBridge.hpp" +#include "DeviceWebManager.hpp" +#include "FilaManagerVM.hpp" +#include "slic3r/GUI/PrinterWebView.hpp" + +namespace Slic3r { +namespace GUI { + + +class DeviceWebPage: public wxPanel { +public: + DeviceWebPage(wxWindow *parent); + ~DeviceWebPage(); + + void LoadUrl(); + + void NavigateTo(const std::string& path); + + // Re-broadcast auth-sensitive filament state to the current web page. + void NotifyFilamentSessionState(); + + // F4.7: broadcast the Studio-wide selected-machine change to the web + // page so the "Read from AMS" dialog can mirror Studio's current + // printer (driven by DeviceManager::OnSelectedMachineChanged). + void NotifyFilamentMachineChanged(); + + void on_sys_color_changed(); + + void msw_rescale(); + + wxWebView *GetWebView() const { + if (m_device_webview) return m_device_webview->GetWebView(); + return nullptr; + } + +private: + PrinterWebView* m_device_webview{nullptr}; // owned by wx parent + std::unique_ptr m_device_http_server; + std::unique_ptr m_device_web_bridge; + std::unique_ptr m_device_web_mgr; + +}; + +} // GUI +} // Slic3r + + +#endif // DEVICEWEBPAGE_H \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceWeb/FilaManagerVM.cpp b/src/slic3r/GUI/DeviceWeb/FilaManagerVM.cpp new file mode 100644 index 0000000000..2368e039be --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/FilaManagerVM.cpp @@ -0,0 +1,754 @@ +// src/slic3r/GUI/DeviceWeb/FilaManagerVM.cpp +#include "FilaManagerVM.hpp" +#include "DeviceWebBridge.hpp" + +#include +#include +#include + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/DeviceCore/DevManager.h" +#include "slic3r/GUI/DeviceCore/DevConfigUtil.h" +#include "slic3r/GUI/DeviceCore/DevExtruderSystem.h" +#include "slic3r/GUI/DeviceCore/DevFilaSystem.h" +#include "slic3r/GUI/DeviceManager.hpp" +#include "slic3r/GUI/fila_manager/wgtFilaManagerStore.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.h" +#include "slic3r/Utils/NetworkAgent.hpp" +#include "libslic3r/PresetBundle.hpp" + +#include +#include +#include + +namespace Slic3r { namespace GUI { + +namespace { + +bool is_spool_cloud_write_action(const std::string& action) +{ + return action == "add" + || action == "batch_add" + || action == "update" + || action == "remove" + || action == "batch_remove"; +} + +bool can_write_spool_to_cloud(NetworkAgent* agent) +{ + return agent && agent->is_user_login() && agent->is_server_connected(); +} + +} // namespace + +FilaManagerVM::FilaManagerVM() +{ +#if !BBL_RELEASE_TO_PUBLIC + wxGetApp().set_fila_debug_sink([this](const nlohmann::json& payload) { + if (m_bridge) { + m_bridge->ReportMsg(MakeResp("debug", "log", 0, "", payload)); + } + }); +#endif + // Subscribe to dispatcher state changes so we can push reports to the web. + if (auto* disp = wxGetApp().fila_manager_cloud_disp()) { + disp->set_on_state_changed([this]() { publish_sync_state(); }); + disp->set_on_pull_done([this](int added, int updated) { + publish_pull_done(added, updated); + }); + disp->set_on_push_failed([this](const std::string& id, + const std::string& op, + int code, + const std::string& msg) { + publish_push_failed(id, op, code, msg); + }); + // Cloud is the source of truth: whenever a local push succeeds we + // immediately enqueue a pull so the next spool list the web sees is + // whatever the cloud just acknowledged. The dispatcher is single-slot + // so the pull runs right after this push op returns to idle. + disp->set_on_push_done([this](const std::string& id, + const std::string& op) { + if (m_bridge) { + m_bridge->ReportMsg(MakeResp("spool", "list", 0, "", build_spool_list())); + } + publish_push_done(id, op); + // If create returned an id, the dispatcher has already inserted + // the accepted cloud row locally. The follow-up pull will see no + // size delta, so carry the create count into publish_pull_done. + if (op == "create" && !id.empty()) { + m_pending_pull_added_hint += 1; + } + if (auto* d = wxGetApp().fila_manager_cloud_disp()) { + d->enqueue_pull(); + } + }); + } +} + +FilaManagerVM::~FilaManagerVM() +{ +#if !BBL_RELEASE_TO_PUBLIC + wxGetApp().set_fila_debug_sink(nullptr); +#endif + // Detach observer callbacks — we don't want the dispatcher to hold a + // dangling this-pointer when VM dies before GUI_App shuts down. + if (auto* disp = wxGetApp().fila_manager_cloud_disp()) { + disp->set_on_state_changed(nullptr); + disp->set_on_pull_done(nullptr); + disp->set_on_push_failed(nullptr); + disp->set_on_push_done(nullptr); + } +} + +nlohmann::json FilaManagerVM::OnCommand( + const std::string& submod, + const std::string& action, + const nlohmann::json& payload) +{ + BOOST_LOG_TRIVIAL(info) << "FilaManagerVM::OnCommand submod=" << submod + << " action=" << action; + + if (submod == "init") return HandleInit(action, payload); + if (submod == "spool") return HandleSpool(action, payload); + if (submod == "preset") return HandlePreset(action, payload); + if (submod == "machine") return HandleMachine(action, payload); + if (submod == "ams") return HandleAms(action, payload); + if (submod == "sync") return HandleSync(action, payload); + if (submod == "config") return HandleConfig(action, payload); + + return MakeResp(submod, action, -1, "unknown submod"); +} + +void FilaManagerVM::ReportState(const std::string& submod, const std::string& action) +{ + if (!m_bridge) return; + + if (submod == "spool") { + nlohmann::json body = MakeResp("spool", "list", 0, "", build_spool_list()); + m_bridge->ReportMsg(body); + return; + } + + // F4.7: broadcast the Studio-wide machine selection change so the + // "Read from AMS" dialog can stay in sync with whatever printer the + // rest of Studio is pointing at (triggered by + // DeviceManager::OnSelectedMachineChanged). + if (submod == "machine" && action == "selected_changed") { + nlohmann::json payload; + payload["machines"] = build_machine_list(); + payload["ams"] = build_ams_data(); + // Keep a flat convenience field at the top of the payload so the + // frontend does not need to peek into the nested objects. + payload["selected_dev_id"] = payload["ams"].value("selected_dev_id", std::string()); + nlohmann::json body = MakeResp("machine", "selected_changed", 0, "", payload); + m_bridge->ReportMsg(body); + return; + } +} + +/* ================================================================ + * Resource handlers + * ================================================================ */ + +nlohmann::json FilaManagerVM::HandleInit(const std::string& action, const nlohmann::json& /*payload*/) +{ + bool dark = wxGetApp().app_config->get("dark_color_mode") == "1"; + nlohmann::json data; + data["theme"] = dark ? "dark" : "light"; + data["spools"] = build_spool_list(); + data["presets"] = build_preset_options(); + // Include current login/sync state so the frontend can render the correct + // UI immediately without waiting for a separate fetchCloudSyncStatus() call. + data["cloud_sync"] = build_sync_state(); +#if !BBL_RELEASE_TO_PUBLIC + data["debug_enabled"] = true; +#else + data["debug_enabled"] = false; +#endif + return MakeResp("init", action, 0, "", data); +} + +nlohmann::json FilaManagerVM::HandleSpool(const std::string& action, const nlohmann::json& payload) +{ + auto* store = wxGetApp().fila_manager_store(); + auto* disp = wxGetApp().fila_manager_cloud_disp(); + auto* agent = wxGetApp().getAgent(); + + if (action == "list") { + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (is_spool_cloud_write_action(action) && (!store || !disp || !can_write_spool_to_cloud(agent))) { + return MakeResp("spool", action, -2, "cloud sync requires sign-in and network"); + } + if (action == "add") { + // Breadcrumbs: when the UI reports "add didn't take effect / no HTTP + // fired", the debug log lets us see which of (parse / insert / save / + // enqueue) silently threw. Each step is wrapped in its own try/catch + // so a failure in save() still lets us return a response to the web + // layer instead of stalling the UI for 5s. + publish_debug_log("data", "info", "HandleSpool add: enter", + "Begin processing spool/add on C++ side", + {{"has_store", store != nullptr}}); + + FilamentSpool s; + try { + s = FilamentSpool::from_json(payload); + } catch (const std::exception& e) { + publish_debug_log("data", "error", "HandleSpool add: from_json threw", + "Failed to parse incoming spool payload", + {{"what", e.what()}, {"payload", payload}}); + return MakeResp("spool", action, 3, std::string("from_json: ") + e.what()); + } + s.cloud_synced = false; + + publish_debug_log("data", "info", "Spool create queued", + "A new spool create request was queued for cloud", + {{"action", "add"}}); + if (disp) disp->enqueue_push_create(s); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "batch_add") { + std::vector new_spools; + int qty = payload.value("quantity", 1); + nlohmann::json sd = payload.contains("spool") ? payload["spool"] : nlohmann::json::object(); + for (int i = 0; i < qty; ++i) { + FilamentSpool s = FilamentSpool::from_json(sd); + s.cloud_synced = false; + new_spools.push_back(s); + } + publish_debug_log("data", "info", "Spool batch create queued", + "Multiple spool create requests were queued for cloud", + {{"action", "batch_add"}, {"count", qty}}); + if (disp) for (auto& spool : new_spools) disp->enqueue_push_create(spool); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "update") { + // 前端应当只传 {spool_id, 本次变更的字段...}。做 selective merge, + // 不再整体覆盖 —— 这样 entry_method / tag_uid / created_at / bound_* / + // cloud_synced 等系统字段不会被清空(STUDIO-17964 Problem A)。 + const std::string updated_id = payload.value("spool_id", ""); + bool can_update = false; + if (store && !updated_id.empty()) { + can_update = store->get_spool(updated_id) != nullptr; + if (can_update) { + publish_debug_log("data", "info", "Spool update queued", + "A spool update request was queued for cloud", + {{"action", "update"}, + {"spool_id", updated_id}, + {"patch_keys", static_cast(payload.is_object() ? + payload.size() : 0)}}); + } else { + publish_debug_log("data", "warn", "Local spool patch skipped", + "apply_patch could not find the target spool", + {{"action", "update"}, {"spool_id", updated_id}}); + } + } + if (disp && can_update) disp->enqueue_push_update(updated_id, payload); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "remove") { + std::string sid = payload.value("spool_id", ""); + if (store && !sid.empty() && store->get_spool(sid)) { + publish_debug_log("data", "info", "Spool delete queued", + "A spool delete request was queued for cloud", + {{"action", "remove"}, {"spool_id", sid}}); + } + if (disp && !sid.empty()) disp->enqueue_push_delete({sid}); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "batch_remove") { + std::vector ids; + if (payload.contains("spool_ids")) { + for (auto& sid : payload["spool_ids"]) ids.push_back(sid.get()); + } + if (store) { + publish_debug_log("data", "info", "Spool batch delete queued", + "Multiple spool delete requests were queued for cloud", + {{"action", "batch_remove"}, + {"count", static_cast(ids.size())}, + {"spool_ids", ids}}); + } + if (disp && !ids.empty()) disp->enqueue_push_delete(ids); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "mark_empty") { + std::string sid; + if (store) { + const FilamentSpool* sp = store->get_spool(payload.value("spool_id", "")); + if (sp) { + FilamentSpool u = *sp; + u.status = "empty"; u.remain_percent = 0; + u.cloud_synced = false; + store->update_spool(u); store->save(); + sid = u.spool_id; + publish_debug_log("data", "info", "Spool marked empty", + "A spool was marked empty in the local store", + {{"action", "mark_empty"}, {"spool_id", sid}}); + } + } + // status / remain_percent 都是本地专有字段,不在云端 Update 白名单内: + // 传空 patch,dispatcher 会直接把本条标记为 cloud_synced,不发空 PUT。 + if (disp && !sid.empty()) disp->enqueue_push_update(sid, nlohmann::json::object()); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "toggle_favorite") { + std::string sid; + if (store) { + const FilamentSpool* sp = store->get_spool(payload.value("spool_id", "")); + if (sp) { + FilamentSpool u = *sp; + u.favorite = !u.favorite; + u.cloud_synced = false; + store->update_spool(u); store->save(); + sid = u.spool_id; + publish_debug_log("data", "info", "Spool favorite toggled", + "A spool favorite flag changed in the local store", + {{"action", "toggle_favorite"}, {"spool_id", sid}, {"favorite", u.favorite}}); + } + } + // favorite 仅本地字段,传空 patch;dispatcher 会跳过 PUT。 + if (disp && !sid.empty()) disp->enqueue_push_update(sid, nlohmann::json::object()); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + if (action == "archive") { + std::string sid; + if (store) { + const FilamentSpool* sp = store->get_spool(payload.value("spool_id", "")); + if (sp) { + FilamentSpool u = *sp; + u.status = "archived"; + u.cloud_synced = false; + store->update_spool(u); store->save(); + sid = u.spool_id; + publish_debug_log("data", "info", "Spool archived", + "A spool was archived in the local store", + {{"action", "archive"}, {"spool_id", sid}}); + } + } + // status 仅本地字段("archived"),传空 patch;dispatcher 会跳过 PUT。 + if (disp && !sid.empty()) disp->enqueue_push_update(sid, nlohmann::json::object()); + publish_sync_state(); + return MakeResp("spool", action, 0, "", build_spool_list()); + } + + return MakeResp("spool", action, -1, "unknown action"); +} + +nlohmann::json FilaManagerVM::HandleSync(const std::string& action, const nlohmann::json& payload) +{ + auto* disp = wxGetApp().fila_manager_cloud_disp(); + + if (action == "status") { + return MakeResp("sync", action, 0, "", build_sync_state()); + } + if (action == "pull") { + if (!disp) return MakeResp("sync", action, -1, "cloud disabled"); + publish_debug_log("data", "info", "Manual pull requested", + "The web page requested a cloud pull", + {{"action", "pull"}}); + disp->enqueue_pull(); + return MakeResp("sync", action, 0, "", build_sync_state()); + } + + return MakeResp("sync", action, -1, "unknown action"); +} + +nlohmann::json FilaManagerVM::HandleConfig(const std::string& action, const nlohmann::json& payload) +{ + auto* sync = wxGetApp().fila_manager_cloud_sync(); + + if (action == "fetch") { + const bool force = payload.value("force", false); + if (!force && !m_cached_cloud_config.empty()) { + publish_debug_log("data", "info", "Cloud config served from cache", + "Returning cached filament config to the web page", + {{"action", "config.fetch"}, {"cached", true}}); + return MakeResp("config", action, 0, "cached", m_cached_cloud_config); + } + + if (!sync) return MakeResp("config", action, -1, "cloud disabled"); + + // fetch_filament_config is async; we synthesize an immediate "pending" + // response, then report the actual config via a 'config/fetched' + // report when the HTTP call returns. + sync->fetch_filament_config([this](const nlohmann::json& cfg) { + m_cached_cloud_config = cfg; + publish_debug_log("http", "info", "Cloud config fetched", + "Filament config returned from cloud", + {{"action", "config.fetch"}, {"keys", cfg.is_object() ? static_cast(cfg.size()) : 0}}); + if (m_bridge) { + m_bridge->ReportMsg(MakeResp("config", "fetched", 0, "", cfg)); + } + }); + publish_debug_log("data", "info", "Cloud config fetch requested", + "The web page requested filament config from cloud", + {{"action", "config.fetch"}, {"cached", false}, {"force", force}}); + return MakeResp("config", action, 0, "pending", nlohmann::json::object()); + } + + return MakeResp("config", action, -1, "unknown action"); +} + +nlohmann::json FilaManagerVM::HandlePreset(const std::string& action, const nlohmann::json& /*payload*/) +{ + if (action == "list") { + return MakeResp("preset", action, 0, "", build_preset_options()); + } + return MakeResp("preset", action, -1, "unknown action"); +} + +nlohmann::json FilaManagerVM::HandleMachine(const std::string& action, const nlohmann::json& payload) +{ + if (action == "list") { + return MakeResp("machine", action, 0, "", build_machine_list()); + } + if (action == "request_pushall") { + // User pressed the refresh button next to the Printer dropdown in the + // "Read from AMS" dialog. Mirror what SelectMachineDialog does when a + // printer is picked: ask the device to resend its full state package + // (get_version + pushall) so the dialog's AMS tray snapshot converges + // on the current tray RFID / weight / remain without having to wait + // for the next spontaneous push. + // + // This is read-only with respect to Studio's globally selected + // machine: we do NOT call set_selected_machine here. A separate + // ams/list { switch_selected:true } call is responsible for that and + // it is only sent when the user actually picks a different printer in + // the dropdown. + std::string dev_id = payload.value("dev_id", ""); + auto* mgr = wxGetApp().getDeviceManager(); + if (!mgr) { + return MakeResp("machine", action, -1, "device manager not ready"); + } + MachineObject* obj = nullptr; + if (!dev_id.empty()) { + obj = mgr->get_my_machine(dev_id); + } else if (MachineObject* sel = mgr->get_selected_machine()) { + obj = sel; + dev_id = sel->get_dev_id(); + } + if (!obj) { + return MakeResp("machine", action, -2, "machine not found"); + } + obj->command_get_version(); + obj->command_request_push_all(/*request_now=*/true); + return MakeResp("machine", action, 0, "", {{"dev_id", dev_id}}); + } + return MakeResp("machine", action, -1, "unknown action"); +} + +nlohmann::json FilaManagerVM::HandleAms(const std::string& action, const nlohmann::json& payload) +{ + if (action == "list") { + // ams/list has two callers: + // 1) User picks a different printer in the "Read from AMS" + // dropdown -> frontend sends { dev_id, switch_selected:true } + // and we actually call DeviceManager::set_selected_machine, + // which changes Studio's globally selected machine. + // 2) The 1.5s poll while the dialog is open / the mirror of an + // external machine switch / any pure tray-snapshot refresh -> + // frontend omits switch_selected, and we only return the AMS + // snapshot of whatever machine is currently selected without + // touching global state. + // Before this split, every poll tick carrying dev_id fell through + // to set_selected_machine and flooded the log with "set current + // printer" requests. + std::string dev_id = payload.value("dev_id", ""); + bool switch_selected = payload.value("switch_selected", false); + if (switch_selected && !dev_id.empty()) { + auto* mgr = wxGetApp().getDeviceManager(); + if (mgr) { + MachineObject* cur = mgr->get_selected_machine(); + if (!cur || cur->get_dev_id() != dev_id) { + mgr->set_selected_machine(dev_id); + } + } + } + return MakeResp("ams", action, 0, "", build_ams_data()); + } + return MakeResp("ams", action, -1, "unknown action"); +} + +/* ================================================================ + * Theme + * ================================================================ */ + +void FilaManagerVM::OnSysColorChanged() +{ + if (!m_bridge) return; + bool dark = wxGetApp().app_config->get("dark_color_mode") == "1"; + nlohmann::json data; + data["theme"] = dark ? "dark" : "light"; + m_bridge->ReportMsg(MakeResp("init", "theme_changed", 0, "", data)); +} + +/* ================================================================ + * Helper + * ================================================================ */ + +nlohmann::json FilaManagerVM::MakeResp( + const std::string& submod, const std::string& action, + int code, const std::string& msg, const nlohmann::json& payload) +{ + return MakeResponse("filament", submod, action, code, msg, payload); +} + +/* ================================================================ + * Cloud sync state + * ================================================================ */ + +nlohmann::json FilaManagerVM::build_sync_state() const +{ + auto* disp = wxGetApp().fila_manager_cloud_disp(); + auto* agent = wxGetApp().getAgent(); + const bool logged_in = agent && agent->is_user_login(); + nlohmann::json s; + s["logged_in"] = logged_in; + s["is_syncing"] = disp ? disp->is_busy() : false; + s["is_pulling"] = disp ? disp->is_pulling() : false; + s["last_synced_at"] = disp ? disp->last_synced_at() : std::string(); + s["last_error"] = { + {"code", disp ? disp->last_error_code() : 0}, + {"message", disp ? disp->last_error_message() : std::string()}, + }; + return s; +} + +void FilaManagerVM::publish_sync_state() +{ + if (!m_bridge) return; + m_bridge->ReportMsg(MakeResp("sync", "state", 0, "", build_sync_state())); +} + +void FilaManagerVM::publish_pull_done(int added, int updated) +{ + if (!m_bridge) return; + + // STUDIO-17956: when create success already inserted the cloud row locally, + // the reconciliation pull observes before_sz == after_sz. Consume the + // pending create hint so the toast reports "+N added" instead of "+0". + if (m_pending_pull_added_hint > 0) { + const int hint = m_pending_pull_added_hint; + m_pending_pull_added_hint = 0; + added += hint; + updated = std::max(0, updated - hint); + } + + nlohmann::json body; + body["added"] = added; + body["updated"] = updated; + body["state"] = build_sync_state(); + body["spools"] = build_spool_list(); + m_bridge->ReportMsg(MakeResp("sync", "pull_done", 0, "", body)); +} + +void FilaManagerVM::publish_push_failed(const std::string& spool_id, + const std::string& op, + int code, + const std::string& message) +{ + if (auto* disp = wxGetApp().fila_manager_cloud_disp()) { + disp->enqueue_pull(); + } + if (!m_bridge) return; + nlohmann::json body; + body["spool_id"] = spool_id; + body["op"] = op; + body["code"] = code; + body["message"] = message; + body["state"] = build_sync_state(); + m_bridge->ReportMsg(MakeResp("sync", "push_failed", 0, "", body)); +} + +void FilaManagerVM::publish_push_done(const std::string& spool_id, const std::string& op) +{ + if (!m_bridge) return; + nlohmann::json body; + body["spool_id"] = spool_id; + body["op"] = op; + body["state"] = build_sync_state(); + m_bridge->ReportMsg(MakeResp("sync", "push_done", 0, "", body)); +} + +void FilaManagerVM::publish_debug_log(const std::string& category, + const std::string& level, + const std::string& title, + const std::string& summary, + const nlohmann::json& detail) +{ + wxGetApp().emit_fila_debug_log(category, level, title, summary, detail); +} + +/* ================================================================ + * Data builders (migrated from wgtFilaManagerPanel) + * ================================================================ */ + +nlohmann::json FilaManagerVM::build_spool_list() +{ + auto* store = wxGetApp().fila_manager_store(); + auto* agent = wxGetApp().getAgent(); + if (!agent || !agent->is_user_login()) + return nlohmann::json::array(); + return store ? store->spools_to_json() : nlohmann::json::array(); +} + +nlohmann::json FilaManagerVM::build_preset_options() +{ + auto* bundle = wxGetApp().preset_bundle; + if (!bundle) + return {{"vendors", nlohmann::json::array()}}; + + // STUDIO-18134: 添加/编辑耗材的品牌/类型下拉应当呈现完整的本地预设清单, + // 不能再按当前选中打印机的型号 + 喷嘴口径 + compatible_printers 过滤。 + // 旧逻辑会让 Mac 上选中某台机器后大量第三方 vendor(HATCHBOX / INLAND / + // OVERTURE / Anycubic 等)的 preset 被剔,导致品牌下拉与 Win 表现不一致。 + // 这里收集的是"用户能选什么品牌/类型"的元数据,不参与切片兼容性判断。 + + auto& filaments = bundle->filaments; + std::map>> vendor_type_items; + std::set filament_id_set; + for (auto it = filaments.begin(); it != filaments.end(); ++it) { + Preset& preset = *it; + if (filaments.get_preset_base(*it) != &preset) + continue; + + std::string vendor = it->config.get_filament_vendor(); + std::string type = it->config.get_filament_type(); + if (vendor.empty()) continue; + if (type.empty()) type = "Other"; + + const std::string dedupe_key = it->filament_id.empty() + ? (vendor + "\n" + type + "\n" + it->name) + : it->filament_id; + if (!filament_id_set.insert(dedupe_key).second) + continue; + + std::string shown_name = filaments.get_preset_alias(*it, true); + if (shown_name.empty()) + shown_name = it->display_name(); + if (shown_name.empty()) + continue; + + vendor_type_items[vendor][type].push_back({ + {"name", shown_name}, + {"series", shown_name}, + {"filament_id", it->filament_id}, + {"setting_id", it->setting_id} + }); + } + + nlohmann::json vendors_arr = nlohmann::json::array(); + for (auto& [vname, type_map] : vendor_type_items) { + nlohmann::json types_arr = nlohmann::json::array(); + for (auto& [tname, items] : type_map) { + nlohmann::json series_arr = nlohmann::json::array(); + nlohmann::json items_arr = nlohmann::json::array(); + for (const auto& item : items) { + const std::string name = item.value("name", ""); + if (!name.empty()) series_arr.push_back(name); + items_arr.push_back(item); + } + types_arr.push_back({{"name", tname}, {"series", series_arr}, {"items", items_arr}}); + } + vendors_arr.push_back({{"name", vname}, {"types", types_arr}}); + } + + return {{"vendors", vendors_arr}}; +} + +nlohmann::json FilaManagerVM::build_machine_list() +{ + // F4.7: include the Studio-wide selected machine so the web "Read from + // AMS" tab can default to the same printer the rest of Studio is using, + // instead of picking the first online device in the list. + nlohmann::json result = {{"machines", nlohmann::json::array()}, + {"selected_dev_id", ""}}; + try { + auto* dev_mgr = wxGetApp().getDeviceManager(); + if (!dev_mgr) return result; + + std::map ml = dev_mgr->get_my_machine_list(); + for (auto& [id, obj] : dev_mgr->get_user_machinelist()) { + if (obj && ml.find(id) == ml.end()) ml[id] = obj; + } + + nlohmann::json arr = nlohmann::json::array(); + for (auto& [id, obj] : ml) { + if (!obj) continue; + std::string name = obj->get_dev_name(); + if (name.empty()) name = id; + // is_lan mirrors SelectMachineDialog's "(LAN)" convention so + // the web Printer dropdown can label LAN-mode printers the same + // way the native Send-to-printer dialog does. + arr.push_back({{"dev_id", id}, + {"dev_name", name}, + {"is_online", obj->is_online()}, + {"is_lan", obj->is_lan_mode_printer()}}); + } + result["machines"] = arr; + + MachineObject* sel = dev_mgr->get_selected_machine(); + if (sel) result["selected_dev_id"] = sel->get_dev_id(); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilamentVM] build_machine_list: " << e.what(); + } + return result; +} + +nlohmann::json FilaManagerVM::build_ams_data() +{ + nlohmann::json empty = {{"selected_dev_id", ""}, {"ams_units", nlohmann::json::array()}}; + try { + auto* dev_mgr = wxGetApp().getDeviceManager(); + if (!dev_mgr) return empty; + + MachineObject* sel = dev_mgr->get_selected_machine(); + std::string sel_id = sel ? sel->get_dev_id() : ""; + + nlohmann::json ams_arr = nlohmann::json::array(); + if (sel) { + auto fila_sys = sel->GetFilaSystem(); + if (fila_sys) { + for (auto& [ams_id, ams] : fila_sys->GetAmsList()) { + if (!ams) continue; + nlohmann::json trays = nlohmann::json::array(); + for (auto& [slot_id, tray] : ams->GetTrays()) { + nlohmann::json t; + t["slot_id"] = slot_id; + t["is_exists"] = tray && tray->is_exists; + if (tray && tray->is_exists) { + t["tag_uid"] = tray->tag_uid; + t["setting_id"] = tray->setting_id; + t["fila_type"] = tray->m_fila_type; + t["sub_brands"] = tray->sub_brands; + std::string color = tray->color; + if (!color.empty() && color[0] != '#') color = "#" + color; + t["color"] = color; + t["weight"] = tray->weight; + t["remain"] = tray->remain; + t["diameter"] = tray->diameter; + t["is_bbl"] = tray->is_bbl; + } + trays.push_back(t); + } + ams_arr.push_back({{"ams_id", ams_id}, {"ams_type", static_cast(ams->GetAmsType())}, {"trays", trays}}); + } + } + } + return {{"selected_dev_id", sel_id}, {"ams_units", ams_arr}}; + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilamentVM] build_ams_data: " << e.what(); + return empty; + } +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceWeb/FilaManagerVM.hpp b/src/slic3r/GUI/DeviceWeb/FilaManagerVM.hpp new file mode 100644 index 0000000000..5f8aea3470 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/FilaManagerVM.hpp @@ -0,0 +1,83 @@ +// src/slic3r/GUI/DeviceWeb/FilaManagerVM.hpp +#ifndef FILAMANAGERVM_HPP +#define FILAMANAGERVM_HPP + +#include "IViewModel.hpp" +#include +#include + +namespace Slic3r { namespace GUI { + +class FilaManagerVM : public IViewModel { +public: + FilaManagerVM(); + ~FilaManagerVM() override; + + std::string GetModule() const override { return "filament"; } + + nlohmann::json OnCommand( + const std::string& submod, + const std::string& action, + const nlohmann::json& payload + ) override; + + void ReportState(const std::string& submod, const std::string& action) override; + + void OnSysColorChanged() override; + +private: + nlohmann::json MakeResp(const std::string& submod, const std::string& action, + int code, const std::string& msg = "", + const nlohmann::json& payload = nlohmann::json::object()); + + // Resource handlers + nlohmann::json HandleSpool(const std::string& action, const nlohmann::json& payload); + nlohmann::json HandlePreset(const std::string& action, const nlohmann::json& payload); + nlohmann::json HandleMachine(const std::string& action, const nlohmann::json& payload); + nlohmann::json HandleAms(const std::string& action, const nlohmann::json& payload); + nlohmann::json HandleInit(const std::string& action, const nlohmann::json& payload); + nlohmann::json HandleSync(const std::string& action, const nlohmann::json& payload); + nlohmann::json HandleConfig(const std::string& action, const nlohmann::json& payload); + + // Data builders (migrated from wgtFilaManagerPanel) + nlohmann::json build_spool_list(); + nlohmann::json build_preset_options(); + nlohmann::json build_machine_list(); + nlohmann::json build_ams_data(); + + // Cloud state helpers + nlohmann::json build_sync_state() const; + void publish_sync_state(); + void publish_pull_done(int added, int updated); + void publish_push_failed(const std::string& spool_id, + const std::string& op, + int code, + const std::string& message); + // F4.5 self-test follow-up: front-end needs an explicit success signal so + // it can confirm the cloud round-trip rather than inferring it from + // `sync/state` timestamps alone. + void publish_push_done(const std::string& spool_id, const std::string& op); + void publish_debug_log(const std::string& category, + const std::string& level, + const std::string& title, + const std::string& summary, + const nlohmann::json& detail = nlohmann::json::object()); + + // Cached cloud filament config (brands / types) — populated by + // HandleConfig("fetch") and returned verbatim on subsequent calls. + nlohmann::json m_cached_cloud_config = nlohmann::json::object(); + + // STUDIO-17956: counter of "create" push ops that have succeeded since the + // last pull_done, used to correct publish_pull_done's `added`/`updated`. + // Dispatcher may insert an accepted create response before the follow-up + // pull, so the pull's size-diff estimate can be 0. Each create push_done + // that already has a cloud id bumps this counter by 1; the next + // publish_pull_done consumes and clears it, so the toast shows "+1 added". + // Only touched on the wx UI thread (dispatcher callbacks are UI-thread + // CallAfter), so no locking is needed. + int m_pending_pull_added_hint = 0; +}; + +}} // namespace Slic3r::GUI + +#endif // FILAMANAGERVM_HPP diff --git a/src/slic3r/GUI/DeviceWeb/IViewModel.hpp b/src/slic3r/GUI/DeviceWeb/IViewModel.hpp new file mode 100644 index 0000000000..11593eda08 --- /dev/null +++ b/src/slic3r/GUI/DeviceWeb/IViewModel.hpp @@ -0,0 +1,90 @@ +// src/slic3r/GUI/DeviceWeb/IViewModel.hpp +#ifndef IVIEWMODEL_HPP +#define IVIEWMODEL_HPP + +#include +#include + +namespace Slic3r { namespace GUI { + +class DeviceWebBridge; + +class IViewModel { +public: + virtual ~IViewModel() = default; + + virtual std::string GetModule() const = 0; + + // Handle a command from the web frontend. + // Returns the response body JSON (containing code, message, payload). + virtual nlohmann::json OnCommand( + const std::string& submod, + const std::string& action, + const nlohmann::json& payload + ) = 0; + + // Report current state for the given submod to the frontend. + virtual void ReportState(const std::string& submod, const std::string& action) = 0; + + void SetBridge(DeviceWebBridge* bridge) { m_bridge = bridge; } + + // Called when the system colour mode (dark/light) changes. + // Default implementation pushes a theme_changed report to the frontend via bridge. + virtual void OnSysColorChanged() {} + +protected: + DeviceWebBridge* m_bridge{nullptr}; + + /** + * Build a standard response/report body. + * + * Wire format (JSON): + * { + * "module": "calibration", + * "submod": "pa_history", + * "action": "list", + * "error_code": 0, + * "message": "", + * "payload": { ... } + * } + * + * Fields: + * module Top-level feature module (matches IViewModel::GetModule()). + * Used by DeviceWebManager to route requests to the right ViewModel. + * Examples: "calibration", "filament" + * + * submod Sub-module within the module — identifies which functional + * group the command targets. Each ViewModel dispatches on this. + * Examples: "pa_history", "spool", "preset", "ams" + * + * action The operation to perform on the sub-module. + * Examples: "list", "add", "update", "delete" + * + * error_code Result status. 0 = success, non-zero = error. + * + * message Human-readable error description (empty on success). + * + * payload The actual data. Structure depends on module/submod/action. + */ + static nlohmann::json MakeResponse( + const std::string& module, + const std::string& submod, + const std::string& action, + int code, + const std::string& message = "", + const nlohmann::json& payload = nlohmann::json::object()) + { + return { + {"module", module}, + {"submod", submod}, + {"action", action}, + {"error_code", code}, + {"message", message}, + {"payload", payload} + }; + } +}; + +}} // namespace Slic3r::GUI + +#endif // IVIEWMODEL_HPP diff --git a/src/slic3r/GUI/FilamentMapDialog.cpp b/src/slic3r/GUI/FilamentMapDialog.cpp index e9b8bdd6b5..1418a8b030 100644 --- a/src/slic3r/GUI/FilamentMapDialog.cpp +++ b/src/slic3r/GUI/FilamentMapDialog.cpp @@ -12,7 +12,7 @@ #include -namespace Slic3r { namespace GUI { +namespace Slic3r::GUI { class SmartFilamentPanel : public wxPanel { @@ -79,18 +79,6 @@ class SmartFilamentPanel : public wxPanel CheckBox *m_smart_filament_checkbox{}; }; -static bool get_pop_up_remind_flag() -{ - auto &app_config = wxGetApp().app_config; - return app_config->get_bool("pop_up_filament_map_dialog"); -} - -static void set_pop_up_remind_flag(bool remind) -{ - auto &app_config = wxGetApp().app_config; - app_config->set_bool("pop_up_filament_map_dialog", remind); -} - static std::vector normalize_auto_modes(const std::vector& modes) { std::vector result; @@ -276,27 +264,25 @@ static const StateColor btn_bd_white(std::pair(wxColour(38, 46, 4 static const StateColor btn_text_white(std::pair(wxColour(38, 46, 48), StateColor::Normal)); -FilamentMapDialog::FilamentMapDialog(wxWindow *parent, - const std::vector &filament_color, - const std::vector &filament_type, - const std::vector &filament_map, - const std::vector &filament_volume_map, - const std::vector &filaments, - const FilamentMapMode mode, - bool machine_synced, - bool show_default, - bool with_checkbox, - const std::vector& available_modes) +FilamentMapDialog::FilamentMapDialog(wxWindow *parent, + const std::vector &filament_color, + const std::vector &filament_type, + const std::vector &filament_map, + const std::vector &filament_volume_map, + const std::vector &filaments, + const FilamentMapMode mode, + bool machine_synced, + bool show_default, + bool with_checkbox, + const std::vector &available_modes) : wxDialog(parent, wxID_ANY, _L("Filament grouping"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) - , m_filament_color(filament_color) - , m_filament_type(filament_type) , m_filament_map(filament_map) , m_filament_volume_map(filament_volume_map) + , m_filament_color(filament_color) + , m_filament_type(filament_type) { SetBackgroundColour(*wxWHITE); - SetMinSize(wxSize(FromDIP(580), -1)); - std::vector modes_to_use = normalize_auto_modes(available_modes); if (modes_to_use.empty()) modes_to_use = get_default_auto_modes(); @@ -305,81 +291,91 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent, if (is_auto_filament_map_mode(mode)) m_page_type = PageType::ptAuto; - else if (mode == fmmManual) - m_page_type = PageType::ptManual; else - m_page_type = PageType::ptDefault; + m_page_type = PageType::ptManual; wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); - main_sizer->AddSpacer(FromDIP(22)); + make_header(main_sizer, only_saving_mode); + make_body(main_sizer, only_saving_mode, modes_to_use, filaments, mode, machine_synced); + make_footer(main_sizer, mode); + + SetSizer(main_sizer); + + // we dont want width changes when switching modes + auto width = std::max({GetBestSize().GetWidth(), FromDIP(580)}); + SetMinClientSize({width, -1}); + + Fit(); + CenterOnParent(); + wxGetApp().UpdateDlgDarkUI(this); +} +void FilamentMapDialog::make_header(wxBoxSizer *main_sizer, bool only_saving_mode) +{ wxBoxSizer *mode_sizer = new wxBoxSizer(wxHORIZONTAL); - wxString auto_btn_label = only_saving_mode ? _L("Fila Saving") : _L("Auto"); - m_auto_btn = new CapsuleButton(this, PageType::ptAuto, auto_btn_label, false); + m_auto_btn = new CapsuleButton(this, PageType::ptAuto, only_saving_mode ? _L("Fila Saving") : _L("Auto"), false); m_manual_btn = new CapsuleButton(this, PageType::ptManual, _L("Custom"), false); - if (show_default) - m_default_btn = new CapsuleButton(this, PageType::ptDefault, _L("Same as Global"), true); - else - m_default_btn = nullptr; + + m_auto_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this); + m_manual_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this); const int button_padding = FromDIP(2); mode_sizer->AddStretchSpacer(); mode_sizer->Add(m_auto_btn, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, button_padding); mode_sizer->Add(m_manual_btn, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, button_padding); - if (show_default) mode_sizer->Add(m_default_btn, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, button_padding); mode_sizer->AddStretchSpacer(); + main_sizer->AddSpacer(FromDIP(22)); main_sizer->Add(mode_sizer, 0, wxEXPAND); main_sizer->AddSpacer(FromDIP(24)); +} - auto panel_sizer = new wxBoxSizer(wxHORIZONTAL); - +void FilamentMapDialog::make_body( + wxBoxSizer *sizer, bool only_saving_mode, const std::vector &modes_to_use, const std::vector &filaments, const FilamentMapMode mode, bool machine_synced) +{ FilamentMapMode default_auto_mode = is_auto_filament_map_mode(mode) ? mode : fmmAutoForFlush; if (!machine_synced && default_auto_mode == fmmAutoForMatch) default_auto_mode = fmmAutoForFlush; if (std::find(modes_to_use.begin(), modes_to_use.end(), default_auto_mode) == modes_to_use.end()) default_auto_mode = modes_to_use.front(); - m_manual_map_panel = new FilamentMapManualPanel(this, m_filament_color, m_filament_type, filaments, filament_map, filament_volume_map); - m_auto_map_panel = new FilamentMapAutoPanel(this, default_auto_mode, machine_synced, modes_to_use); - m_saving_panel = only_saving_mode ? new FilamentMapSavingPanel(this) : nullptr; - if (show_default) - m_default_map_panel = new FilamentMapDefaultPanel(this); - else - m_default_map_panel = nullptr; + m_manual_panel = new FilamentMapManualPanel(this, m_filament_color, m_filament_type, filaments, m_filament_map, m_filament_volume_map); + m_manual_panel->Bind(wxEVT_INVALID_MANUAL_MAP, [this](wxCommandEvent &event) { + if (m_page_type != PageType::ptManual) { + if (!m_ok_btn->IsEnabled()) { m_ok_btn->Enable(); } + return; + } + if (event.GetInt()) { + if (!m_ok_btn->IsEnabled()) { m_ok_btn->Enable(); } + } else { + if (m_ok_btn->IsEnabled()) { m_ok_btn->Disable(); } + } + }); - panel_sizer->Add(m_manual_map_panel, 0, wxALIGN_CENTER | wxEXPAND); - panel_sizer->Add(m_auto_map_panel, 1, wxALIGN_CENTER | wxEXPAND); - if (m_saving_panel) - panel_sizer->Add(m_saving_panel, 1, wxALIGN_CENTER | wxEXPAND); - if (show_default) panel_sizer->Add(m_default_map_panel, 0, wxALIGN_CENTER | wxEXPAND); - main_sizer->Add(panel_sizer, 1, wxEXPAND); + if (only_saving_mode) + m_auto_panel = new FilamentMapSavingPanel(this); + else + m_auto_panel = new FilamentMapAutoPanel(this, default_auto_mode, machine_synced, modes_to_use); - wxPanel* bottom_panel = new wxPanel(this); - bottom_panel->SetBackgroundColour(*wxWHITE); - wxBoxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL); - bottom_panel->SetSizer(bottom_sizer); - bottom_sizer->Fit(bottom_panel); + auto flags = wxSizerFlags().CenterHorizontal(); + sizer->Add(m_auto_panel, flags); + sizer->Add(m_manual_panel, flags); +} +void FilamentMapDialog::make_footer(wxBoxSizer *main_sizer, const FilamentMapMode mode) +{ if (m_fila_switch_ready) { smart_filament = new SmartFilamentPanel(this); smart_filament->Show(mode == fmmAutoForFlush); - main_sizer->Add(smart_filament); + main_sizer->Add(smart_filament, wxSizerFlags().Expand()); } - if (with_checkbox) { - auto* checkbox_sizer = new wxBoxSizer(wxHORIZONTAL); - m_checkbox = new CheckBox(bottom_panel); - m_checkbox->Bind(wxEVT_TOGGLEBUTTON, &FilamentMapDialog::on_checkbox, this); - checkbox_sizer->Add(m_checkbox, 0, wxALIGN_CENTER, 0); - - auto* checkbox_label = new Label(bottom_panel, _L("Don't remind me again")); - checkbox_label->SetFont(Label::Body_12); - checkbox_sizer->Add(checkbox_label, 0, wxLEFT| wxALIGN_CENTER , FromDIP(3)); - - bottom_sizer->Add(checkbox_sizer, 0 , wxALIGN_CENTER | wxALL, FromDIP(15)); - } + wxPanel *bottom_panel = new wxPanel(this); + bottom_panel->SetBackgroundColour(*wxWHITE); + wxBoxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL); + bottom_panel->SetSizer(bottom_sizer); + bottom_sizer->Fit(bottom_panel); bottom_sizer->AddStretchSpacer(); @@ -407,66 +403,12 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent, m_ok_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_ok, this); m_cancel_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_cancle, this); - - m_auto_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this); - m_manual_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this); - if (show_default) m_default_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this); - - m_manual_map_panel->Bind(wxEVT_INVALID_MANUAL_MAP, [this](wxCommandEvent& event) { - if (m_page_type != PageType::ptManual) { - if (!m_ok_btn->IsEnabled()) { - m_ok_btn->Enable(); - } - return; - } - if (event.GetInt()) { - if (!m_ok_btn->IsEnabled()) { - m_ok_btn->Enable(); - } - } - else { - if (m_ok_btn->IsEnabled()) { - m_ok_btn->Disable(); - } - } - }); - - SetSizer(main_sizer); - Layout(); - { - const int target_w = std::max(FromDIP(580), m_manual_map_panel->GetMinWidth()); - int best_h = std::max({m_auto_map_panel->GetBestSize().GetHeight(), m_manual_map_panel->GetBestSize().GetHeight()}); - if (m_saving_panel) best_h = std::max(m_saving_panel->GetBestSize().GetHeight(), best_h); - - int current_panel_h = m_manual_map_panel->GetSize().GetHeight(); - if (m_page_type == PageType::ptAuto) { - if (m_fila_switch_ready && m_saving_panel) - current_panel_h = m_saving_panel->GetBestSize().GetHeight(); - else if (m_auto_map_panel) - current_panel_h = m_auto_map_panel->GetBestSize().GetHeight(); - } - - int top_bottom_extra = GetBestSize().GetHeight() - current_panel_h; - int target_h = top_bottom_extra + best_h; - - SetMinSize(wxSize(target_w, target_h)); - SetMaxSize(wxSize(target_w, target_h)); - SetSize(wxSize(target_w, target_h)); - } - - CenterOnParent(); - wxGetApp().UpdateDlgDarkUI(this); } FilamentMapMode FilamentMapDialog::get_mode() { - if (m_page_type == PageType::ptAuto) { - if (m_saving_panel) - return fmmAutoForFlush; - return m_auto_map_panel->GetMode(); - } - if (m_page_type == PageType::ptManual) return fmmManual; - return fmmDefault; + if (m_page_type == PageType::ptAuto) return m_auto_panel->GetMode(); + return fmmManual; } int FilamentMapDialog::ShowModal() @@ -475,26 +417,12 @@ int FilamentMapDialog::ShowModal() return wxDialog::ShowModal(); } -void FilamentMapDialog::on_checkbox(wxCommandEvent &event) -{ - bool is_checked = m_checkbox->GetValue(); - m_checkbox->SetValue(is_checked); - set_pop_up_remind_flag(!is_checked); - - if (is_checked) { - MessageDialog dialog(nullptr, _L("No further pop-up will appear. You can reopen it in 'Preferences'"), _L("Tips"), wxICON_INFORMATION | wxOK); - dialog.ShowModal(); - this->Close(); - } - - event.Skip(); -} - void FilamentMapDialog::on_ok(wxCommandEvent &event) { if (m_page_type == PageType::ptManual) { - m_filament_map = m_manual_map_panel->GetFilamentMaps(); - m_filament_volume_map = m_manual_map_panel->GetFilamentVolumeMaps(); + auto manual = dynamic_cast(m_manual_panel); + m_filament_map = manual->GetFilamentMaps(); + m_filament_volume_map = manual->GetFilamentVolumeMaps(); } EndModal(wxID_OK); @@ -504,44 +432,20 @@ void FilamentMapDialog::on_cancle(wxCommandEvent &event) { EndModal(wxID_CANCEL) void FilamentMapDialog::update_panel_status(PageType page) { - std::vectorbutton_list = { m_default_btn,m_manual_btn,m_auto_btn }; - for (auto p : button_list) { - if (p && p->IsSelected()) { - p->Select(false); - } - } - std::vectorpanel_list = { m_default_map_panel,m_manual_map_panel,m_auto_map_panel,m_saving_panel }; - for (auto p : panel_list) { - if (p && p->IsShown()) { - p->Hide(); - } - } + const bool is_manual = (page == PageType::ptManual); - if (page == PageType::ptDefault) { - if (m_default_btn && m_default_map_panel) { - m_default_btn->Select(true); - m_default_map_panel->Show(); - } - } - if (page == PageType::ptManual) { - m_manual_btn->Select(true); - m_manual_map_panel->Show(); - } - if (page == PageType::ptAuto) { - m_auto_btn->Select(true); - if (m_fila_switch_ready && m_saving_panel) { - m_saving_panel->Show(); - } else if (m_auto_map_panel) { - m_auto_map_panel->Show(); - } - if (!m_ok_btn->IsEnabled()) { - m_ok_btn->Enable(); - } - } + m_manual_btn->Select(is_manual); + m_auto_btn->Select(!is_manual); + + m_manual_panel->Show(is_manual); + m_auto_panel->Show(!is_manual); + + if (!is_manual) m_ok_btn->Enable(true); if (smart_filament) smart_filament->Show(get_mode() == fmmAutoForFlush); Layout(); + Fit(); } void FilamentMapDialog::on_switch_mode(wxCommandEvent &event) @@ -552,11 +456,4 @@ void FilamentMapDialog::on_switch_mode(wxCommandEvent &event) update_panel_status(m_page_type); event.Skip(); } - -void FilamentMapDialog::set_modal_btn_labels(const wxString &ok_label, const wxString &cancel_label) -{ - m_ok_btn->SetLabel(ok_label); - m_cancel_btn->SetLabel(cancel_label); -} - -}} // namespace Slic3r::GUI +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/FilamentMapDialog.hpp b/src/slic3r/GUI/FilamentMapDialog.hpp index 05c37af1be..4337471b2a 100644 --- a/src/slic3r/GUI/FilamentMapDialog.hpp +++ b/src/slic3r/GUI/FilamentMapDialog.hpp @@ -1,25 +1,18 @@ -#ifndef slic3r_FilamentMapDialog_hpp_ -#define slic3r_FilamentMapDialog_hpp_ +#pragma once #include #include "CapsuleButton.hpp" -#include "Widgets/CheckBox.hpp" -#include "libslic3r/PrintConfig.hpp" class Button; namespace Slic3r { -class DynamicPrintConfig; class Print; +} -namespace GUI { -class DragDropPanel; +namespace Slic3r::GUI { class Plater; class PartPlate; -class FilamentMapManualPanel; -class FilamentMapAutoPanel; -class FilamentMapDefaultPanel; -class FilamentMapSavingPanel; +class FilamentMapPanel; class SmartFilamentPanel; /** @@ -34,16 +27,12 @@ class SmartFilamentPanel; * @return whether continue slicing */ bool try_pop_up_before_slice(bool is_slice_all, Plater* plater_ref, PartPlate* partplate_ref, bool force_pop_up = false); -std::vector resolve_available_auto_modes(Print* print_obj, const std::vector& requested_modes, bool machine_synced); - +std::vector resolve_available_auto_modes(Print *print_obj, const std::vector &requested_modes, bool machine_synced); class FilamentMapDialog : public wxDialog { - enum PageType { - ptAuto, - ptManual, - ptDefault - }; + enum PageType { ptAuto, ptManual }; + public: FilamentMapDialog(wxWindow *parent, const std::vector& filament_color, @@ -71,44 +60,43 @@ class FilamentMapDialog : public wxDialog return {}; } - int ShowModal(); - void set_modal_btn_labels(const wxString& left_label, const wxString& right_label); + int ShowModal() override; + private: - void make_smart_filament_section(wxBoxSizer *sizer); + void make_header(wxBoxSizer *sizer, bool only_saving_mode); + void make_body(wxBoxSizer *sizer, + bool only_saving_mode, + const std::vector &modes_to_use, + const std::vector &filaments, + const FilamentMapMode mode, + bool machine_synced); + void make_footer(wxBoxSizer *sizer, const FilamentMapMode mode); void on_ok(wxCommandEvent &event); void on_cancle(wxCommandEvent &event); void on_switch_mode(wxCommandEvent &event); - void on_checkbox(wxCommandEvent &event); void on_smart_filament_checkbox(wxCommandEvent &event); void update_panel_status(PageType page); private: - FilamentMapManualPanel* m_manual_map_panel; - FilamentMapAutoPanel* m_auto_map_panel; - FilamentMapDefaultPanel* m_default_map_panel; - FilamentMapSavingPanel* m_saving_panel; + FilamentMapPanel *m_auto_panel{}; + FilamentMapPanel *m_manual_panel{}; + SmartFilamentPanel *smart_filament{}; - CapsuleButton* m_auto_btn; - CapsuleButton* m_manual_btn; - CapsuleButton* m_default_btn; + CapsuleButton *m_auto_btn; + CapsuleButton *m_manual_btn; - Button *m_ok_btn{}; - Button *m_cancel_btn{}; - CheckBox *m_checkbox{}; - SmartFilamentPanel *smart_filament{}; + Button *m_ok_btn{}; + Button *m_cancel_btn{}; - PageType m_page_type; - bool m_fila_switch_ready{false}; + PageType m_page_type; + bool m_fila_switch_ready{false}; -private: - std::vector m_filament_map; - std::vector m_filament_volume_map; - std::vector m_filament_color; - std::vector m_filament_type; + std::vector m_filament_map; + std::vector m_filament_volume_map; + std::vector m_filament_color; + std::vector m_filament_type; }; -}} // namespace Slic3r::GUI - -#endif /* slic3r_FilamentMapDialog_hpp_ */ +} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/FilamentMapPanel.cpp b/src/slic3r/GUI/FilamentMapPanel.cpp index a4272e0ac2..5aa49827c2 100644 --- a/src/slic3r/GUI/FilamentMapPanel.cpp +++ b/src/slic3r/GUI/FilamentMapPanel.cpp @@ -9,7 +9,7 @@ #include #include -namespace Slic3r { namespace GUI { +namespace Slic3r::GUI { static const wxColour BgNormalColor = wxColour("#FFFFFF"); static const wxColour BgSelectColor = wxColour("#EBF9F0"); @@ -200,8 +200,8 @@ void FilamentMapManualPanel::SyncPanelHeights() auto curr_left = m_left_panel->GetMinSize(); auto curr_right = m_right_panel->GetMinSize(); - m_left_panel->SetMinSize(wxSize(FromDIP(260), -1)); - m_right_panel->SetMinSize(wxSize(FromDIP(260), -1)); + m_left_panel->SetMinSize(wxSize(FromDIP(260), FromDIP(110))); + m_right_panel->SetMinSize(wxSize(FromDIP(260), FromDIP(110))); m_left_panel->Layout(); m_left_panel->Fit(); @@ -249,7 +249,12 @@ FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *p const std::vector &filament_list, const std::vector &filament_map, const std::vector &filament_volume_map) - : wxPanel(parent), m_filament_map(filament_map), m_filament_color(color), m_filament_type(type), m_filament_list(filament_list), m_filament_volume_map(filament_volume_map) + : FilamentMapPanel(parent) + , m_filament_map(filament_map) + , m_filament_volume_map(filament_volume_map) + , m_filament_list(filament_list) + , m_filament_color(color) + , m_filament_type(type) { SetName(wxT("FilamentMapManualPanel")); SetBackgroundColour(BgNormalColor); @@ -283,16 +288,12 @@ FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *p m_right_panel->AddColorBlock(color, type, idx + 1, is_high_flow); } } - m_left_panel->SetMinSize({ FromDIP(260),-1 }); - m_right_panel->SetMinSize({ FromDIP(260),-1 }); + m_left_panel->SetMinSize({FromDIP(260), FromDIP(110)}); + m_right_panel->SetMinSize({FromDIP(260), FromDIP(110)}); - drag_sizer->AddStretchSpacer(); drag_sizer->Add(m_left_panel, 1, wxALIGN_CENTER | wxEXPAND); - drag_sizer->AddSpacer(FromDIP(7)); - drag_sizer->Add(m_switch_btn, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(1)); - drag_sizer->AddSpacer(FromDIP(7)); + drag_sizer->Add(m_switch_btn, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(8)); drag_sizer->Add(m_right_panel, 1, wxALIGN_CENTER | wxEXPAND); - drag_sizer->AddStretchSpacer(); top_sizer->Add(drag_sizer, 0, wxALIGN_CENTER | wxEXPAND); @@ -343,16 +344,12 @@ FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *p SetMinSize(wxSize(FromDIP(580), -1)); Layout(); Fit(); - if (GetParent()) { - GetParent()->Layout(); - GetParent()->Fit(); - } GUI::wxGetApp().UpdateDarkUIWin(this); } void FilamentMapManualPanel::UpdateNozzleVolumeType() { - auto check_separation = [this]() { + auto check_separation = []() { auto preset_bundle = wxGetApp().preset_bundle; auto nozzle_volume_values = preset_bundle->project_config.option("nozzle_volume_type")->values; if (nozzle_volume_values.size() <= 1) @@ -367,10 +364,6 @@ void FilamentMapManualPanel::UpdateNozzleVolumeType() Layout(); Fit(); - if (GetParent()) { - GetParent()->Layout(); - GetParent()->Fit(); - } } void FilamentMapManualPanel::UpdateNozzleCountDisplay() @@ -418,7 +411,7 @@ void FilamentMapManualPanel::OnSwitchFilament(wxCommandEvent &) } this->GetParent()->Layout(); this->GetParent()->Fit(); - + if (m_right_panel->IsUseSeparation()) { m_left_panel->Layout(); m_left_panel->Fit(); @@ -428,24 +421,47 @@ void FilamentMapManualPanel::OnSwitchFilament(wxCommandEvent &) } } -void FilamentMapManualPanel::Hide() +bool FilamentMapManualPanel::Show(bool show) { - m_left_panel->Hide(); - m_right_panel->Hide(); - m_switch_btn->Hide(); - wxPanel::Hide(); - m_timer->Stop(); + m_force_validation = show; + if (show) + m_timer->Start(500); + else + m_timer->Stop(); + + return FilamentMapPanel::Show(show); } -void FilamentMapManualPanel::Show() +class FilamentMapBtnPanel : public wxPanel { - m_left_panel->Show(); - m_right_panel->Show(); - m_switch_btn->Show(); - wxPanel::Show(); - m_force_validation = true; - m_timer->Start(500); -} +public: + FilamentMapBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon_path); + void Select(bool selected); + bool Enable(bool enable) override; + bool IsEnabled() const { return m_enabled; } + +protected: + void OnPaint(wxPaintEvent &event); + +private: + void OnEnterWindow(wxMouseEvent &event); + void OnLeaveWindow(wxMouseEvent &evnet); + void OnSize(wxSizeEvent &event); + + void UpdateStatus(); + + wxBitmap icon_enabled; + wxBitmap icon_disabled; + + wxBitmapButton *m_btn; + wxStaticText *m_label; + Label *m_disable_tip; + Label *m_detail; + std::string m_icon_path; + bool m_enabled{true}; // override system enable state, to get consistent UI + bool m_hover{false}; + bool m_selected{false}; +}; GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon) : wxPanel(parent) { @@ -453,8 +469,6 @@ GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString & SetBackgroundStyle(wxBG_STYLE_PAINT); m_hover = false; - const int horizontal_margin = FromDIP(12); - auto sizer = new wxBoxSizer(wxVERTICAL); icon_enabled = create_scaled_bitmap(icon, nullptr, 20); @@ -474,8 +488,8 @@ GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString & label_sizer->AddStretchSpacer(); auto label_width = label_sizer->GetMinSize().GetWidth(); - auto pwidth = label_width + FromDIP(24) * 2; - const int panel_width = std::max(FromDIP(160), pwidth); + auto min_width = label_width + FromDIP(24) * 2; + min_width = std::max(FromDIP(160), min_width); m_disable_tip = new Label(this, _L("(Sync with printer)")); @@ -484,23 +498,15 @@ GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString & sizer->Add(m_disable_tip, 0, wxALIGN_CENTER); sizer->AddSpacer(FromDIP(3)); - //auto detail_sizer = new wxBoxSizer(wxVERTICAL); - m_detail = new Label(this, detail); + m_detail = new Label(this, detail); m_detail->SetFont(Label::Body_12); m_detail->SetForegroundColour(TextNormalGreyColor); - int text_width = panel_width - horizontal_margin * 2; - m_detail->SetMaxSize(wxSize(text_width, -1)); - m_detail->Wrap(text_width); - - //detail_sizer->AddStretchSpacer(); - //detail_sizer->Add(m_detail, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, horizontal_margin); - //detail_sizer->AddStretchSpacer(); sizer->Add(m_detail, 1, wxALIGN_CENTER | wxEXPAND); sizer->AddSpacer(FromDIP(10)); SetSizer(sizer); - SetMinSize(wxSize(panel_width, -1)); + SetMinSize(wxSize(min_width, -1)); Layout(); Fit(); @@ -519,6 +525,7 @@ GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString & Bind(wxEVT_PAINT, &FilamentMapBtnPanel::OnPaint, this); Bind(wxEVT_ENTER_WINDOW, &FilamentMapBtnPanel::OnEnterWindow, this); Bind(wxEVT_LEAVE_WINDOW, &FilamentMapBtnPanel::OnLeaveWindow, this); + Bind(wxEVT_SIZE, &FilamentMapBtnPanel::OnSize, this); } void FilamentMapBtnPanel::OnPaint(wxPaintEvent &event) @@ -565,8 +572,7 @@ void FilamentMapBtnPanel::UpdateStatus() m_btn->SetForegroundColour(BgDisableColor); m_label->SetForegroundColour(TextDisableColor); m_detail->SetForegroundColour(TextDisableColor); - } - else { + } else { m_disable_tip->SetLabel(""); m_disable_tip->SetForegroundColour(TextNormalBlackColor); m_btn->SetBitmap(icon_enabled); @@ -575,6 +581,7 @@ void FilamentMapBtnPanel::UpdateStatus() m_detail->SetForegroundColour(TextNormalGreyColor); } GUI::wxGetApp().UpdateDarkUIWin(this); + Refresh(); } void FilamentMapBtnPanel::OnEnterWindow(wxMouseEvent &event) @@ -582,7 +589,6 @@ void FilamentMapBtnPanel::OnEnterWindow(wxMouseEvent &event) if (!m_hover && m_enabled) { m_hover = true; UpdateStatus(); - Refresh(); event.Skip(); } } @@ -594,16 +600,25 @@ void FilamentMapBtnPanel::OnLeaveWindow(wxMouseEvent &event) if (this->GetClientRect().Contains(pos)) return; m_hover = false; UpdateStatus(); - Refresh(); event.Skip(); } } +void FilamentMapBtnPanel::OnSize(wxSizeEvent &event) +{ + event.Skip(); + const int horizontal_margin = FromDIP(12); + int text_width = event.GetSize().GetWidth() - horizontal_margin * 2; + if (text_width > 0) { + m_detail->SetMaxSize(wxSize(text_width, -1)); + m_detail->Wrap(text_width); + } +} + bool FilamentMapBtnPanel::Enable(bool enable) { m_enabled = enable; UpdateStatus(); - Refresh(); return true; } @@ -611,25 +626,10 @@ void FilamentMapBtnPanel::Select(bool selected) { m_selected = selected; UpdateStatus(); - Refresh(); } -void GUI::FilamentMapBtnPanel::Hide() -{ - m_btn->Hide(); - m_label->Hide(); - m_detail->Hide(); - wxPanel::Hide(); -} -void GUI::FilamentMapBtnPanel::Show() -{ - m_btn->Show(); - m_label->Show(); - m_detail->Show(); - wxPanel::Show(); -} - -FilamentMapAutoPanel::FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode, bool machine_synced, const std::vector& available_modes) : wxPanel(parent) +FilamentMapAutoPanel::FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode, bool machine_synced, const std::vector &available_modes) + : FilamentMapPanel(parent) { std::string pt_auto = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); wxString main_nz_auto = _L(DevPrinterConfigUtil::get_toolhead_display_name(pt_auto, MAIN_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::LowerCase)); @@ -681,71 +681,27 @@ FilamentMapAutoPanel::FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mod }); } - // Calculate width based on number of modes - int num_modes = m_mode_panels.size(); - if (num_modes > 0) { - int dialog_width = FromDIP(580); - if (GetParent() != nullptr) { - int parent_width = GetParent()->GetClientSize().GetWidth(); - if (parent_width > 0) - dialog_width = parent_width; - } - int spacer_width = FromDIP(20); - int side_margin = FromDIP(30); - int total_spacer_width = spacer_width * (num_modes - 1); - int available_width = dialog_width - total_spacer_width - side_margin * 2; - if (available_width <= 0) - available_width = dialog_width; - int panel_width = available_width / num_modes; - - int max_width = FromDIP(160); - panel_width = std::min(panel_width, max_width); - - sizer->AddStretchSpacer(); - - int max_height = 0; - for (size_t i = 0; i < m_mode_panels.size(); ++i) { - int best_h = m_mode_panels[i]->GetBestSize().GetHeight(); - max_height = std::max(best_h, max_height); - } - - for (size_t i = 0; i < m_mode_panels.size(); ++i) { - if (i > 0) { - sizer->AddSpacer(spacer_width); - } - auto* panel = m_mode_panels[i]; - sizer->Add(panel, 1, wxEXPAND | wxFIXED_MINSIZE, 0); - panel->SetMinSize(wxSize(panel->GetMinSize().GetWidth(), max_height)); - panel->SetMaxSize(wxSize(panel->GetMaxSize().GetWidth(), max_height)); - } - sizer->AddStretchSpacer(); + int spacer_width = FromDIP(20); + sizer->AddSpacer(spacer_width); + for (size_t i = 0; i < m_mode_panels.size(); ++i) { + if (i > 0) + sizer->AddSpacer(spacer_width); + sizer->Add(m_mode_panels[i], 1, wxEXPAND); } + sizer->AddSpacer(spacer_width); UpdateStatus(); - // Set sizer and fit - SetSizerAndFit(sizer); + SetSizer(sizer); + // First layout assigns equal widths, triggering OnSize which re-wraps + // detail text. Second Fit/Layout picks up the updated heights. + Layout(); + Fit(); Layout(); GUI::wxGetApp().UpdateDarkUIWin(this); } -void FilamentMapAutoPanel::Hide() -{ - for (auto panel : m_mode_panels) { - panel->Hide(); - } - wxPanel::Hide(); -} - -void FilamentMapAutoPanel::Show() -{ - for (auto panel : m_mode_panels) { - panel->Show(); - } - wxPanel::Show(); -} - void FilamentMapAutoPanel::UpdateStatus() { assert(m_mode_panels.size() == m_available_modes.size()); @@ -773,37 +729,7 @@ std::string FilamentMapAutoPanel::GetIconForMode(FilamentMapMode mode) } } -FilamentMapDefaultPanel::FilamentMapDefaultPanel(wxWindow *parent) : wxPanel(parent) -{ - auto sizer = new wxBoxSizer(wxHORIZONTAL); - - m_label = new Label(this, _L("The filament grouping method for current plate is determined by the dropdown option at the slicing plate button.")); - m_label->SetFont(Label::Body_14); - m_label->SetBackgroundColour(*wxWHITE); - m_label->Wrap(FromDIP(500)); - - sizer->AddStretchSpacer(); - sizer->Add(m_label, 1, wxEXPAND | wxALIGN_CENTER); - sizer->AddStretchSpacer(); - - SetSizerAndFit(sizer); - Layout(); - GUI::wxGetApp().UpdateDarkUIWin(this); -} - -void FilamentMapDefaultPanel::Hide() -{ - m_label->Hide(); - wxPanel::Hide(); -} - -void FilamentMapDefaultPanel::Show() -{ - m_label->Show(); - wxPanel::Show(); -} - -FilamentMapSavingPanel::FilamentMapSavingPanel(wxWindow *parent) : wxPanel(parent) +FilamentMapSavingPanel::FilamentMapSavingPanel(wxWindow *parent) : FilamentMapPanel(parent) { SetBackgroundColour(*wxWHITE); @@ -827,5 +753,4 @@ FilamentMapSavingPanel::FilamentMapSavingPanel(wxWindow *parent) : wxPanel(paren SetSizer(saving_sizer); } -} // namespace GUI -} // namespace Slic3r +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/FilamentMapPanel.hpp b/src/slic3r/GUI/FilamentMapPanel.hpp index 32d45d8212..a414047643 100644 --- a/src/slic3r/GUI/FilamentMapPanel.hpp +++ b/src/slic3r/GUI/FilamentMapPanel.hpp @@ -1,16 +1,22 @@ - -#ifndef FILAMENT_MAP_PANEL_HPP -#define FILAMENT_MAP_PANEL_HPP +#pragma once #include "GUI.hpp" #include "DragDropPanel.hpp" -#include "Widgets/SwitchButton.hpp" +#include -namespace Slic3r { namespace GUI { +namespace Slic3r::GUI { wxDECLARE_EVENT(wxEVT_INVALID_MANUAL_MAP, wxCommandEvent); +class FilamentMapBtnPanel; + +class FilamentMapPanel : public wxPanel +{ +public: + FilamentMapPanel(wxWindow *parent) : wxPanel(parent) {}; + virtual FilamentMapMode GetMode() const = 0; +}; -class FilamentMapManualPanel : public wxPanel +class FilamentMapManualPanel : public FilamentMapPanel { public: FilamentMapManualPanel(wxWindow *parent, @@ -31,8 +37,9 @@ class FilamentMapManualPanel : public wxPanel void UpdateNozzleVolumeType(); void UpdateNozzleCountDisplay(); - void Hide(); - void Show(); + bool Show(bool show = true) override; + + FilamentMapMode GetMode() const override { return FilamentMapMode::fmmManual; } private: void OnTimer(wxTimerEvent &evt); @@ -60,43 +67,11 @@ class FilamentMapManualPanel : public wxPanel bool m_force_validation{ false }; }; -class FilamentMapBtnPanel : public wxPanel -{ -public: - FilamentMapBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon_path); - void Hide(); - void Show(); - void Select(bool selected); - bool Enable(bool enable); - bool IsEnabled() const { return m_enabled; } -protected: - void OnPaint(wxPaintEvent &event); -private: - void OnEnterWindow(wxMouseEvent &event); - void OnLeaveWindow(wxMouseEvent &evnet); - - void UpdateStatus(); - - wxBitmap icon_enabled; - wxBitmap icon_disabled; - - wxBitmapButton *m_btn; - wxStaticText *m_label; - Label *m_disable_tip; - Label *m_detail; - std::string m_icon_path; - bool m_enabled{ true }; - bool m_hover{false}; - bool m_selected{false}; -}; - -class FilamentMapAutoPanel : public wxPanel +class FilamentMapAutoPanel : public FilamentMapPanel { public: - FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode, bool machine_synced, const std::vector& available_modes = {}); - void Hide(); - void Show(); - FilamentMapMode GetMode() const { return m_mode; } + FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode, bool machine_synced, const std::vector &available_modes = {}); + FilamentMapMode GetMode() const override { return m_mode; } private: void OnModeSwitch(FilamentMapMode mode); @@ -106,27 +81,16 @@ class FilamentMapAutoPanel : public wxPanel std::vector m_mode_panels; std::vector m_available_modes; - FilamentMapMode m_mode; - bool m_machine_synced; -}; -class FilamentMapDefaultPanel : public wxPanel -{ -public: - FilamentMapDefaultPanel(wxWindow *parent); - void Hide(); - void Show(); - -private: - Label *m_label; + FilamentMapMode m_mode; + bool m_machine_synced; }; -class FilamentMapSavingPanel : public wxPanel +class FilamentMapSavingPanel : public FilamentMapPanel { public: FilamentMapSavingPanel(wxWindow *parent); + FilamentMapMode GetMode() const override { return FilamentMapMode::fmmAutoForFlush; } }; -}} // namespace Slic3r::GUI - -#endif \ No newline at end of file +} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp b/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp index ae7d66e0c5..a3cffe6c2a 100644 --- a/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp +++ b/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp @@ -38,6 +38,11 @@ namespace rt.x() = 8.0f; break; } + case Slic3r::GUI::gcode::EViewType::AdditionalFanSpeed: + { + rt.x() = 12.0f; + break; + } case Slic3r::GUI::gcode::EViewType::Temperature: { rt.x() = 9.0f; @@ -96,6 +101,10 @@ namespace { return t_move.fan_speed; } + case Slic3r::GUI::gcode::EViewType::AdditionalFanSpeed: + { + return t_move.additional_fan_speed; + } case Slic3r::GUI::gcode::EViewType::Temperature: { return t_move.temperature; @@ -325,6 +334,8 @@ namespace Slic3r case EViewType::Height: case EViewType::Width: case EViewType::Feedrate: + case EViewType::FanSpeed: + case EViewType::AdditionalFanSpeed: case EViewType::Temperature: case EViewType::LayerTime: case EViewType::VolumetricRate: @@ -1204,6 +1215,7 @@ namespace Slic3r case EViewType::Width: case EViewType::Feedrate: case EViewType::FanSpeed: + case EViewType::AdditionalFanSpeed: case EViewType::Temperature: case EViewType::LayerTime: case EViewType::VolumetricRate: @@ -1457,6 +1469,8 @@ namespace Slic3r return m_p_extrusions->ranges.feedrate; case Slic3r::GUI::gcode::EViewType::FanSpeed: return m_p_extrusions->ranges.fan_speed; + case Slic3r::GUI::gcode::EViewType::AdditionalFanSpeed: + return m_p_extrusions->ranges.additional_fan_speed; case Slic3r::GUI::gcode::EViewType::Temperature: return m_p_extrusions->ranges.temperature; case Slic3r::GUI::gcode::EViewType::LayerTime: diff --git a/src/slic3r/GUI/GCodeRenderer/BaseRenderer.cpp b/src/slic3r/GUI/GCodeRenderer/BaseRenderer.cpp index e9cea41c9f..f12630d48e 100644 --- a/src/slic3r/GUI/GCodeRenderer/BaseRenderer.cpp +++ b/src/slic3r/GUI/GCodeRenderer/BaseRenderer.cpp @@ -27,6 +27,8 @@ namespace return _u8L("Speed"); else if (view_type == Slic3r::GUI::gcode::EViewType::FanSpeed) return _u8L("Fan Speed"); + else if (view_type == Slic3r::GUI::gcode::EViewType::AdditionalFanSpeed) + return _u8L("AUX Fan Speed"); else if (view_type == Slic3r::GUI::gcode::EViewType::Temperature) return _u8L("Temperature"); else if (view_type == Slic3r::GUI::gcode::EViewType::VolumetricRate) @@ -1209,6 +1211,7 @@ namespace Slic3r m_p_extrusions->ranges.width.update_from(round_to_bin(curr.width)); }// prevent the start code extrude extreme height/width and make the range deviate from the normal range m_p_extrusions->ranges.fan_speed.update_from(curr.fan_speed); + m_p_extrusions->ranges.additional_fan_speed.update_from(curr.additional_fan_speed); m_p_extrusions->ranges.temperature.update_from(curr.temperature); if (curr.extrusion_role != erCustom || is_extrusion_role_visible(ExtrusionRole::erCustom)) m_p_extrusions->ranges.volumetric_rate.update_from(round_to_bin(curr.volumetric_rate())); @@ -1687,25 +1690,31 @@ namespace Slic3r const_cast(m_gcode_result)->update_imgui_flag = false; } push_combo_style(); + + auto *preset_bundle = wxGetApp().preset_bundle; + const bool is_bbl_vendor_preset = preset_bundle != nullptr && preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(preset_bundle); + const auto *printer_model = wxGetApp().plater()->get_curr_printer_model(); + const bool hide_additional_fan_speed = !is_bbl_vendor_preset || (printer_model != nullptr && printer_model->support_side_panel_fan == "false"); + if (hide_additional_fan_speed && view_type_items[m_view_type_sel] == EViewType::AdditionalFanSpeed) { + for (int i = 0; i < view_type_items.size(); ++i) { + if (view_type_items[i] == EViewType::FeatureType) { + apply_view_type_selection(i, EViewType::FeatureType); + break; + } + } + } ImGuiComboFlags flags = 0; const char* view_type_value = view_type_image_names[m_view_type_sel].option_name.c_str(); if (ImGui::BBLBeginCombo("", view_type_value, flags)) { ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f); for (int i = 0; i < view_type_image_names.size(); i++) { const bool is_selected = (m_view_type_sel == i); + if (hide_additional_fan_speed && view_type_items[i] == EViewType::AdditionalFanSpeed) { + continue; + } if (ImGui::BBLSelectable_LeftImage(view_type_image_names[i].option_name.c_str(), is_selected, view_type_image_names[i].texture_id)) { m_fold = false; - m_view_type_sel = i; - if (!is_helio_option()) { - m_last_non_helio_option_item = i; - record_gcodeviewer_option_item(); - } - set_view_type(view_type_items[m_view_type_sel]); - reset_visible(view_type_items[m_view_type_sel]); - // update buffers' render paths - refresh_render_paths(); - update_moves_slider(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + apply_view_type_selection(i, view_type_items[i]); } if (is_selected) { ImGui::SetItemDefaultFocus(); @@ -1861,6 +1870,7 @@ namespace Slic3r case EViewType::Width: { imgui.title(_u8L("Line Width (mm)")); break; } case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } + case EViewType::AdditionalFanSpeed: { imgui.title(_u8L("AUX Fan Speed (%)")); break; } case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } case EViewType::LayerTime: { imgui.title(_u8L("Layer Time")); break; } @@ -2006,6 +2016,7 @@ namespace Slic3r break; } case EViewType::FanSpeed: { append_range(m_p_extrusions->ranges.fan_speed, 0); break; } + case EViewType::AdditionalFanSpeed: { append_range(m_p_extrusions->ranges.additional_fan_speed, 0); break; } case EViewType::Temperature: { append_range(m_p_extrusions->ranges.temperature, 0); break; } case EViewType::LayerTime: { append_range(m_p_extrusions->ranges.layer_duration, 1); break; } case EViewType::VolumetricRate: { append_range(m_p_extrusions->ranges.volumetric_rate, 2); break; } @@ -2163,8 +2174,8 @@ namespace Slic3r break; } // helio - case EViewType::ThermalIndexMin: - case EViewType::ThermalIndexMax: + case EViewType::ThermalIndexMin: + case EViewType::ThermalIndexMax: case EViewType::ThermalIndexMean: { if (m_view_type == EViewType::ThermalIndexMin) append_range(m_p_extrusions->ranges.thermal_index_min, 0); @@ -2172,13 +2183,13 @@ namespace Slic3r append_range(m_p_extrusions->ranges.thermal_index_max, 0); else append_range(m_p_extrusions->ranges.thermal_index_mean, 0); - + // Add "View Summary" link only if simulation/optimization result is available if (wxGetApp().plater()->has_helio_simulation_result()) { ImGui::Spacing(); ImGui::Dummy({ window_padding, window_padding }); ImGui::SameLine(); - + // Render as hyperlink with green color and underline std::string label = _u8L("View Summary"); ImColor HyperColor = ImColor(0, 174, 66, 255).Value; @@ -2948,6 +2959,20 @@ namespace Slic3r wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); } + void BaseRenderer::apply_view_type_selection(int view_type_sel, EViewType type) + { + m_view_type_sel = view_type_sel; + if (!is_helio_option()) { + m_last_non_helio_option_item = view_type_sel; + record_gcodeviewer_option_item(); + } + set_view_type(type); + reset_visible(type); + refresh_render_paths(); + update_moves_slider(); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + } + void BaseRenderer::do_set_view_type(EViewType type) { m_view_type = type; @@ -3105,6 +3130,7 @@ namespace Slic3r view_type_items.push_back(EViewType::VolumetricRate); view_type_items.push_back(EViewType::LayerTime); view_type_items.push_back(EViewType::FanSpeed); + view_type_items.push_back(EViewType::AdditionalFanSpeed); view_type_items.push_back(EViewType::Temperature); for (int i = 0; i < view_type_items.size(); i++) { if (view_type_items[i] == EViewType::FilamentId) { @@ -3573,6 +3599,7 @@ namespace Slic3r std::string flow = ImGui::ColorMarkerStart + _u8L("Flow: ") + ImGui::ColorMarkerEnd; std::string layer_time = ImGui::ColorMarkerStart + _u8L("Layer Time: ") + ImGui::ColorMarkerEnd; std::string fanspeed = ImGui::ColorMarkerStart + _u8L("Fan Speed: ") + ImGui::ColorMarkerEnd; + std::string additional_fanspeed = ImGui::ColorMarkerStart + _u8L("AUX Fan Speed: ") + ImGui::ColorMarkerEnd; std::string temperature = ImGui::ColorMarkerStart + _u8L("Temperature: ") + ImGui::ColorMarkerEnd; std::string thermal_index = ImGui::ColorMarkerStart + _u8L("Thermal Index") + ImGui::ColorMarkerEnd; // helio @@ -3651,6 +3678,13 @@ namespace Slic3r imgui.text(buf); break; } + case EViewType::AdditionalFanSpeed: { + ImGui::SameLine(window_padding + item_size + item_spacing); + sprintf(buf, "%s%.0f", additional_fanspeed.c_str(), m_curr_move.additional_fan_speed); + ImGui::PushItemWidth(item_size); + imgui.text(buf); + break; + } case EViewType::Temperature: { ImGui::SameLine(window_padding + item_size + item_spacing); sprintf(buf, "%s%.0f", temperature.c_str(), m_curr_move.temperature); diff --git a/src/slic3r/GUI/GCodeRenderer/BaseRenderer.hpp b/src/slic3r/GUI/GCodeRenderer/BaseRenderer.hpp index 6ddc21cfe8..8a45b3372b 100644 --- a/src/slic3r/GUI/GCodeRenderer/BaseRenderer.hpp +++ b/src/slic3r/GUI/GCodeRenderer/BaseRenderer.hpp @@ -39,6 +39,7 @@ namespace Slic3r { ColorPrint, FilamentId, LayerTime, + AdditionalFanSpeed, // helio ThermalIndexMin, ThermalIndexMax, @@ -182,6 +183,7 @@ namespace Slic3r { void render_shells(); void render_slider(int canvas_width, int canvas_height); virtual void render_legend(float& legend_height, int canvas_width, int canvas_height, int right_margin); + void apply_view_type_selection(int view_type_sel, EViewType type); void update_by_mode(ConfigOptionMode mode); void update_thermal_options(bool add); void push_combo_style(); @@ -425,6 +427,8 @@ namespace Slic3r { Range feedrate; // Color mapping by fan speed. Range fan_speed; + // Color mapping by additional fan speed. + Range additional_fan_speed; // Color mapping by volumetric extrusion rate. Range volumetric_rate; // Color mapping by extrusion temperature. @@ -445,6 +449,7 @@ namespace Slic3r { width.reset(); feedrate.reset(); fan_speed.reset(); + additional_fan_speed.reset(); volumetric_rate.reset(); temperature.reset(); layer_duration.reset(true); diff --git a/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.cpp b/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.cpp index 2350291fdf..a4a31e8b04 100644 --- a/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.cpp +++ b/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.cpp @@ -181,6 +181,7 @@ namespace Slic3r { // use rounding to reduce the number of generated paths return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && move.position.z() <= sub_paths.front().first.position.z() && feedrate == move.feedrate && fan_speed == move.fan_speed && + additional_fan_speed == move.additional_fan_speed && height == round_to_bin(move.height) && width == round_to_bin(move.width) && matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f) && layer_time == move.layer_duration && thermal_index_mean == move.thermal_index_mean && thermal_index_min == move.thermal_index_min && thermal_index_max == move.thermal_index_max; @@ -217,6 +218,7 @@ namespace Slic3r { round_to_bin(move.width), move.feedrate, move.fan_speed, + move.additional_fan_speed, move.temperature, move.thermal_index_min, move.thermal_index_max, @@ -1781,6 +1783,7 @@ namespace Slic3r { case EViewType::Width: { color = m_p_extrusions->ranges.width.get_color_at(path.width); break; } case EViewType::Feedrate: { color = m_p_extrusions->ranges.feedrate.get_color_at(path.feedrate); break; } case EViewType::FanSpeed: { color = m_p_extrusions->ranges.fan_speed.get_color_at(path.fan_speed); break; } + case EViewType::AdditionalFanSpeed: { color = m_p_extrusions->ranges.additional_fan_speed.get_color_at(path.additional_fan_speed); break; } case EViewType::Temperature: { color = m_p_extrusions->ranges.temperature.get_color_at(path.temperature); break; } case EViewType::LayerTime: { color = m_p_extrusions->ranges.layer_duration.get_color_at(path.layer_time, Range::EType::Logarithmic); break; } case EViewType::VolumetricRate: { color = m_p_extrusions->ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } diff --git a/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.hpp b/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.hpp index ccd5682492..22961af2ac 100644 --- a/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.hpp +++ b/src/slic3r/GUI/GCodeRenderer/LegacyRenderer.hpp @@ -163,6 +163,7 @@ namespace Slic3r { float width{ 0.0f }; float feedrate{ 0.0f }; float fan_speed{ 0.0f }; + float additional_fan_speed{ 0.0f }; float temperature{ 0.0f }; // helio float thermal_index_min{ 0.0f }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7c26f16bff..5cbc0f77cf 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -278,6 +278,7 @@ void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config) m_slicing_parameters = nullptr; m_layers_texture.valid = false; m_layer_height_profile.clear(); + m_profile_dirty = true; } void GLCanvas3D::LayersEditing::select_object(const Model& model, int object_id) @@ -792,7 +793,13 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const void GLCanvas3D::LayersEditing::adjust_layer_height_profile() { this->update_slicing_parameters(); - PrintObject::update_layer_height_profile(*m_model_object, *m_slicing_parameters, m_layer_height_profile); + bool nozzle_range_reset = false; + PrintObject::update_layer_height_profile(*m_model_object, *m_slicing_parameters, m_layer_height_profile, nozzle_range_reset); + if (nozzle_range_reset) { + wxGetApp().plater()->get_notification_manager()->push_plater_warning_notification( + _u8L("The variable layer height profile has been reset because some layer heights " + "exceed the allowed range of the current nozzle.")); + } Slic3r::adjust_layer_height_profile(*m_slicing_parameters, m_layer_height_profile, this->last_z, this->strength, this->band_width, this->last_action); m_layers_texture.valid = false; m_profile_dirty = true; @@ -835,9 +842,16 @@ void GLCanvas3D::LayersEditing::generate_layer_height_texture() this->update_slicing_parameters(); // Always try to update the layer height profile. bool update = !m_layers_texture.valid; - if (PrintObject::update_layer_height_profile(*m_model_object, *m_slicing_parameters, m_layer_height_profile)) { + bool nozzle_range_reset = false; + if (PrintObject::update_layer_height_profile(*m_model_object, *m_slicing_parameters, m_layer_height_profile, nozzle_range_reset)) { // Initialized to the default value. update = true; + m_profile_dirty = true; + } + if (nozzle_range_reset) { + wxGetApp().plater()->get_notification_manager()->push_plater_warning_notification( + _u8L("The variable layer height profile has been reset because some layer heights " + "exceed the allowed range of the current nozzle.")); } // Update if the layer height profile was changed, or when the texture is not valid. if (!update && !m_layers_texture.data.empty() && m_layers_texture.cells > 0) @@ -4028,6 +4042,13 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } return; } + case 'e': + case 'E': + case WXK_CONTROL_E: { + m_labels.show_object_labels(!m_labels.are_object_labels_shown()); + m_dirty = true; + return; + } } } // CTRL is pressed @@ -4193,17 +4214,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case WXK_BACK: { post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; } #endif case WXK_ESCAPE: { deselect_all(); break; } - // Shift+E to toggle object labels - case 'E': - case 'e': { - if ((evt.GetModifiers() & shiftMask) != 0) { - m_labels.show_object_labels(!m_labels.are_object_labels_shown()); - m_dirty = true; - break; - } - evt.Skip(); - break; - } //case WXK_F5: { // if ((wxGetApp().is_editor() && !wxGetApp().plater()->model().objects.empty()) || // (wxGetApp().is_gcode_viewer() && !wxGetApp().plater()->get_last_loaded_gcode().empty())) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 94ad197779..729d8784d3 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3,6 +3,7 @@ #include "GUI_Init.hpp" #include "GUI_ObjectList.hpp" #include "GUI_Factories.hpp" +#include "slic3r/GUI/DeviceWeb/DeviceWebPage.hpp" #include "slic3r/GUI/UserManager.hpp" #include "slic3r/GUI/TaskManager.hpp" #include "slic3r/GUI/OpenGLManager.hpp" @@ -1142,13 +1143,7 @@ void GUI_App::post_init() download_url = input_str; } #endif - try - { - //filter relative directories - std::regex pattern("\\.\\.[\\/\\\\]|\\.\\.[\\/\\\\][\\/\\\\]|\\.\\/[\\/\\\\]|\\.[\\/\\\\]"); - download_url = std::regex_replace(download_url, pattern, ""); - } - catch (...){} + download_url = sanitize_download_url(download_url); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", download_url %1%") % PathSanitizer::sanitize(download_url); @@ -2755,6 +2750,32 @@ int GUI_App::OnExit() stop_sync_user_preset(); + if (m_fila_manager_cloud_disp) { + delete m_fila_manager_cloud_disp; + m_fila_manager_cloud_disp = nullptr; + } + + if (m_fila_manager_cloud_sync) { + delete m_fila_manager_cloud_sync; + m_fila_manager_cloud_sync = nullptr; + } + + if (m_fila_manager_cloud_client) { + delete m_fila_manager_cloud_client; + m_fila_manager_cloud_client = nullptr; + } + + if (m_fila_manager_sync) { + delete m_fila_manager_sync; + m_fila_manager_sync = nullptr; + } + + if (m_fila_manager_store) { + m_fila_manager_store->save(); + delete m_fila_manager_store; + m_fila_manager_store = nullptr; + } + if (m_device_manager) { delete m_device_manager; m_device_manager = nullptr; @@ -2774,9 +2795,43 @@ int GUI_App::OnExit() m_agent = nullptr; } +#if !BBL_RELEASE_TO_PUBLIC + m_fila_debug_sink = nullptr; +#endif + return wxApp::OnExit(); } +void GUI_App::emit_fila_debug_log(const std::string& category, + const std::string& level, + const std::string& title, + const std::string& summary, + const nlohmann::json& detail) +{ +#if !BBL_RELEASE_TO_PUBLIC + if (!m_fila_debug_sink) + return; + + nlohmann::json payload = { + {"category", category}, + {"level", level}, + {"title", title}, + {"summary", summary}, + {"detail", detail}, + {"ts", static_cast( + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count())} + }; + m_fila_debug_sink(payload); +#else + (void)category; + (void)level; + (void)title; + (void)summary; + (void)detail; +#endif +} + class wxBoostLog : public wxLog { void DoLogText(const wxString &msg) override { @@ -3217,6 +3272,32 @@ bool GUI_App::on_init_inner() // Let the libslic3r know the callback, which will translate messages on demand. Slic3r::I18N::set_translate_callback(libslic3r_translate_callback); + // Initialize Filament Manager store & sync + if (!m_fila_manager_store) { + m_fila_manager_store = new wgtFilaManagerStore(); + m_fila_manager_store->load(); + BOOST_LOG_TRIVIAL(info) << "Filament Manager store initialized"; + } + if (!m_fila_manager_sync) { + m_fila_manager_sync = new wgtFilaManagerSync(m_fila_manager_store); + BOOST_LOG_TRIVIAL(info) << "Filament Manager sync initialized"; + } + // Cloud layer — owns HTTP client, high-level sync and the serialization dispatcher. + if (!m_fila_manager_cloud_client) { + m_fila_manager_cloud_client = new wgtFilaManagerCloudClient(); + BOOST_LOG_TRIVIAL(info) << "Filament Manager cloud client initialized"; + } + if (!m_fila_manager_cloud_sync) { + m_fila_manager_cloud_sync = new wgtFilaManagerCloudSync(m_fila_manager_store, + m_fila_manager_cloud_client); + BOOST_LOG_TRIVIAL(info) << "Filament Manager cloud sync initialized"; + } + if (!m_fila_manager_cloud_disp) { + m_fila_manager_cloud_disp = new wgtFilaManagerCloudDispatcher(m_fila_manager_cloud_sync, + m_fila_manager_cloud_client); + BOOST_LOG_TRIVIAL(info) << "Filament Manager cloud dispatcher initialized"; + } + BOOST_LOG_TRIVIAL(info) << "create the main window"; mainframe = new MainFrame(); // hide settings tabs after first Layout @@ -4444,6 +4525,14 @@ void GUI_App::request_user_logout() mainframe->update_side_preset_ui(); GUI::wxGetApp().stop_sync_user_preset(); + + // Drop queued cloud ops so they don't fire against a stale user. + if (m_fila_manager_cloud_disp) { + m_fila_manager_cloud_disp->clear_pending(); + } + if (mainframe && mainframe->web_device()) { + mainframe->web_device()->NotifyFilamentSessionState(); + } } } @@ -4875,6 +4964,15 @@ void GUI_App::request_model_download(wxString url) } } +std::string GUI_App::sanitize_download_url(const std::string &url) +{ + try { + std::regex pattern("\\.\\.[\\/\\\\]|\\.\\.[\\/\\\\][\\/\\\\]|\\.\\/[\\/\\\\]|\\.[\\/\\\\]"); + return std::regex_replace(url, pattern, ""); + } catch (...) {} + return url; +} + //BBS download project by project id void GUI_App::download_project(std::string project_id) { @@ -5082,6 +5180,15 @@ void GUI_App::on_user_login_handle(wxCommandEvent &evt) mainframe->update_side_preset_ui(); GUI::wxGetApp().mainframe->show_sync_dialog(); + + // Trigger filament-manager cloud pull on the dispatcher queue; no-op if + // already pulling. Runs after login so auth token is available. + if (m_fila_manager_cloud_disp) { + m_fila_manager_cloud_disp->enqueue_pull(); + } + if (mainframe && mainframe->web_device()) { + mainframe->web_device()->NotifyFilamentSessionState(); + } } } @@ -7141,7 +7248,21 @@ void GUI_App::MacOpenURL(const wxString& url) if (!input_str.empty()) download_origin_url = input_str; } - std::string download_file_url = url_decode(download_origin_url); + std::string decoded_url = url_decode(download_origin_url); + std::string download_file_url; +#if BBL_RELEASE_TO_PUBLIC + if (boost::starts_with(decoded_url, "http://makerworld") || boost::starts_with(decoded_url, "https://makerworld") || + boost::starts_with(decoded_url, "http://public-cdn.bblmw.com") || boost::starts_with(decoded_url, "https://public-cdn.bblmw.com") || + boost::algorithm::contains(decoded_url, "amazonaws.com") || boost::algorithm::contains(decoded_url, "aliyuncs.com")) { + download_file_url = decoded_url; + } else { + MessageDialog msg_dlg(nullptr, _L("This file is not from a trusted site, do you want to open it anyway?"), "", wxAPPLY | wxYES_NO); + if (msg_dlg.ShowModal() == wxID_YES) download_file_url = decoded_url; + } +#else + download_file_url = decoded_url; +#endif + download_file_url = sanitize_download_url(download_file_url); #if !BBL_RELEASE_TO_PUBLIC BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << download_file_url; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index f80a20e020..6efe4855a6 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -1,6 +1,7 @@ #ifndef slic3r_GUI_App_hpp_ #define slic3r_GUI_App_hpp_ +#include #include #include #include "ImGuiWrapper.hpp" @@ -15,6 +16,11 @@ #include "slic3r/GUI/WebUserLoginDialog.hpp" #include "slic3r/GUI/BindDialog.hpp" #include "slic3r/GUI/HMS.hpp" +#include "slic3r/GUI/fila_manager/wgtFilaManagerStore.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerSync.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.h" +#include "slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.h" #include "slic3r/GUI/Jobs/UpgradeNetworkJob.hpp" #include "slic3r/GUI/HttpServer.hpp" #include "slic3r/GUI/UnsavedChangesDialog.hpp" @@ -318,6 +324,12 @@ class GUI_App : public wxApp Slic3r::UserManager* m_user_manager { nullptr }; Slic3r::TaskManager* m_task_manager { nullptr }; NetworkAgent* m_agent { nullptr }; + + wgtFilaManagerStore* m_fila_manager_store { nullptr }; + wgtFilaManagerSync* m_fila_manager_sync { nullptr }; + wgtFilaManagerCloudClient* m_fila_manager_cloud_client { nullptr }; + wgtFilaManagerCloudSync* m_fila_manager_cloud_sync { nullptr }; + wgtFilaManagerCloudDispatcher* m_fila_manager_cloud_disp { nullptr }; std::vector need_delete_presets; // store setting ids of preset std::vector m_create_preset_blocked { false, false, false, false, false, false }; // excceed limit bool m_networking_compatible { false }; @@ -343,6 +355,9 @@ class GUI_App : public wxApp wxString m_info_dialog_content; wxString m_install_preset_fail_text; HttpServer m_http_server; +#if !BBL_RELEASE_TO_PUBLIC + std::function m_fila_debug_sink; +#endif boost::thread m_check_cert_thread; TryLoadLastMachine m_load_last_machine; @@ -369,6 +384,24 @@ class GUI_App : public wxApp Slic3r::DeviceManager* getDeviceManager() { return m_device_manager; } bool is_blocking_printing(MachineObject *obj_ = nullptr); Slic3r::TaskManager* getTaskManager() { return m_task_manager; } + wgtFilaManagerStore* fila_manager_store() { return m_fila_manager_store; } + wgtFilaManagerSync* fila_manager_sync() { return m_fila_manager_sync; } + wgtFilaManagerCloudClient* fila_manager_cloud_client() { return m_fila_manager_cloud_client; } + wgtFilaManagerCloudSync* fila_manager_cloud_sync() { return m_fila_manager_cloud_sync; } + wgtFilaManagerCloudDispatcher* fila_manager_cloud_disp() { return m_fila_manager_cloud_disp; } +#if !BBL_RELEASE_TO_PUBLIC + void set_fila_debug_sink(std::function sink) + { + m_fila_debug_sink = std::move(sink); + } +#else + void set_fila_debug_sink(std::function /*sink*/) {} +#endif + void emit_fila_debug_log(const std::string& category, + const std::string& level, + const std::string& title, + const std::string& summary, + const nlohmann::json& detail = nlohmann::json::object()); HMSQuery* get_hms_query() { return hms_query; } NetworkAgent* getAgent() { return m_agent; } FilamentColorCodeQuery* get_filament_color_code_query(); @@ -482,6 +515,7 @@ class GUI_App : public wxApp std::string handle_web_request(std::string cmd); void handle_script_message(std::string msg); void request_model_download(wxString url); + std::string sanitize_download_url(const std::string& url); void download_project(std::string project_id); void request_project_download(std::string project_id); void request_open_project(std::string project_id); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2a0ecc89b2..0e06e3a0bd 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -4023,7 +4023,7 @@ void ObjectList::update_info_items(size_t obj_idx, wxDataViewItemArray *selectio bool should_show = printer_technology() == ptFFF && std::any_of(model_object->volumes.begin(), model_object->volumes.end(), [](const ModelVolume* mv) { - return !mv->supported_facets.empty(); + return mv->is_model_part() && !mv->supported_facets.empty(); }); if (shows && !should_show) { m_objects_model->SetSupportPaintState(false, item_obj); @@ -4038,7 +4038,7 @@ void ObjectList::update_info_items(size_t obj_idx, wxDataViewItemArray *selectio { bool shows = m_objects_model->IsFuzzySkinPainted(item_obj); bool should_show = printer_technology() == ptFFF && - std::any_of(model_object->volumes.begin(), model_object->volumes.end(), [](const ModelVolume *mv) { return !mv->fuzzy_skin_facets.empty(); }); + std::any_of(model_object->volumes.begin(), model_object->volumes.end(), [](const ModelVolume *mv) { return mv->is_model_part() && !mv->fuzzy_skin_facets.empty(); }); if (shows && !should_show) { m_objects_model->SetFuzzySkinPaintState(false, item_obj); } else if (!shows && should_show) { @@ -4053,7 +4053,7 @@ void ObjectList::update_info_items(size_t obj_idx, wxDataViewItemArray *selectio bool should_show = printer_technology() == ptFFF && std::any_of(model_object->volumes.begin(), model_object->volumes.end(), [](const ModelVolume* mv) { - return !mv->mmu_segmentation_facets.empty(); + return mv->is_model_part() && !mv->mmu_segmentation_facets.empty(); }); if (shows && !should_show) { m_objects_model->SetColorPaintState(false, item_obj); diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 9a1c01e918..7cbaf3c4b2 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -8,6 +8,7 @@ #include "slic3r/GUI/GUI_ObjectList.hpp" #include "libnest2d/common.hpp" +#include #include namespace Slic3r { @@ -59,6 +60,14 @@ void FillBedJob::prepare() ap.height = 1; ap.name = mo->name; + // STUDIO (PRD §11.5): "在不在当前盘"用 overlap 而不是 contains 判定。 + // 旧逻辑只把"AABB 完全落在 plate_bb 内"的 instance 当作 m_unselected + // 障碍;只要因为旋转/缩放/姿态导致 AABB 超出盘边界哪怕零点几毫米, + // 也会被划入 m_locked,从而对 NFP 不可见,最终新副本会叠到这种"边 + // 角对象"上。改成"AABB 与 plate_bb 有任何重叠 → m_unselected", + // 只有"完全在盘外"才进 m_locked。 + const bool on_current_plate = plate_bb.overlap(ap_bb); + if (selected) { if (mo->instances[inst_idx]->printable) @@ -69,7 +78,7 @@ void FillBedJob::prepare() } else { - if (plate_bb.contains(ap_bb)) + if (on_current_plate) { ap.bed_idx = 0; ap.itemid = m_unselected.size(); @@ -89,7 +98,7 @@ void FillBedJob::prepare() } else { - if (plate_bb.contains(ap_bb)) + if (on_current_plate) { ap.bed_idx = 0; ap.itemid = m_unselected.size(); @@ -150,12 +159,15 @@ void FillBedJob::prepare() auto polys = offset_ex(m_selected.front().poly, params.min_obj_distance / 2); ExPolygon poly = polys.empty() ? m_selected.front().poly : polys.front(); double poly_area = poly.area() / sc; + // STUDIO (PRD §11.6): m_unselected 中所有 instance 的 bed_idx 在 prepare 阶段都被 + // 显式置为 0(见 §11.5 上方两处赋值),所以"是否在当前盘"的判定应该用 0 而不是 + // cur_plate_index。旧代码用 cur_plate_index 在非 0 号盘上 fill bed 时此项恒为 0, + // 导致 needed_items 被过估,多生成的副本被 finalize 静默丢弃——只是浪费 CPU, + // 不影响功能正确性,但属于明确的实现 bug。 double unsel_area = std::accumulate(m_unselected.begin(), m_unselected.end(), 0., - [cur_plate_index](double s, const auto &ap) { - //BBS: m_unselected instance is in the same partplate - return s + (ap.bed_idx == cur_plate_index) * ap.poly.area(); - //return s + (ap.bed_idx == 0) * ap.poly.area(); + [](double s, const auto &ap) { + return s + (ap.bed_idx == 0) * ap.poly.area(); }) / sc; double fixed_area = unsel_area + m_selected.size() * poly_area; @@ -170,17 +182,31 @@ void FillBedJob::prepare() ModelInstance *mi = model_object->instances[sel_id]; ArrangePolygon template_ap = get_instance_arrange_poly(mi, global_config); + // STUDIO-15820 修复(FillBed + 旋转/对齐 Y 轴时新副本越界): + // 抓快照模板实例的 *原始 transformation*。不能直接靠 setter 里的 + // m_plater->model().objects[m_object_idx]:finalize() 是按 m_selected 顺序逐项 + // ap.apply(),priority>0 模板会先于新副本 apply,把模板 ModelInstance 旋转了 + // rot_template;接着新副本 setter 里 add_object(*mo) 深拷贝出来的 instance 已经 + // 多了 rot_template 的旋转,再 apply_arrange_result(t, rot_new) 的 + // rotate() 是 prepend 操作 ⇒ 最终旋转 = R_z(rot_new) * R_z(rot_template) * R_3d(θ_0), + // 而 arrange 算 transformed_poly 时只考虑 R_2D(rot_new),二者不一致,bbox 偏移。 + // 解决:在 setter 里把克隆出来的 instance 强制重置到模板的原始 transformation, + // 再 apply_arrange_result,这样组合结果就是 R_z(rot_new) * R_3d(θ_0),与 arrange 一致。 + Geometry::Transformation mi_orig_trafo = mi->get_transformation(); for (int i = 0; i < needed_items; ++i) { ArrangePolygon ap = template_ap; ap.poly = m_selected.front().poly; ap.bed_idx = PartPlateList::MAX_PLATES_COUNT; ap.height = 1; ap.itemid = -1; - ap.setter = [this, mi](const ArrangePolygon &p) { + ap.setter = [this, mi_orig_trafo](const ArrangePolygon &p) { ModelObject *mo = m_plater->model().objects[m_object_idx]; ModelObject* newObj = m_plater->model().add_object(*mo); newObj->name = mo->name +" "+ std::to_string(p.itemid); - for (ModelInstance *newInst : newObj->instances) { newInst->apply_arrange_result(p.translation.cast(), p.rotation); } + for (ModelInstance *newInst : newObj->instances) { + newInst->set_transformation(mi_orig_trafo); + newInst->apply_arrange_result(p.translation.cast(), p.rotation); + } //m_plater->sidebar().obj_list()->paste_objects_into_list({m_plater->model().objects.size()-1}); }; m_selected.emplace_back(ap); @@ -210,6 +236,12 @@ void FillBedJob::process() if (params.avoid_extrusion_cali_region && global_config.opt_bool("scan_first_layer")) partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); + // STUDIO: 当用户没有显式设置对象间距(min_obj_distance==0)时,给铺满整盘 + // 路径加一个 0.5mm 的 inflation 下限,保证副本之间至少有 1mm 的可见间隙; + // 该下限通过 ArrangeParams 注入,不影响 ArrangeJob/CLI 等其他 arrange 调用方。 + if (params.min_obj_distance == 0) + params.min_inflation_floor = scaled(0.5); + update_selected_items_inflation(m_selected, global_config, params); update_unselected_items_inflation(m_unselected, global_config, params); @@ -231,21 +263,135 @@ void FillBedJob::process() if (m_selected.size() > 100){ // too many items, just find grid empty cells to put them - Vec2f step = unscaled(get_extents(m_selected.front().poly).size()) + 2 * Vec2f(m_selected.front().brim_width, m_selected.front().brim_width); + // + // STUDIO: grid 路径的 step 之前只算了 brim_width,完全没考虑 + // min_obj_distance,导致用户把对象间距设为 0 / 默认时副本之间是边对 + // 边贴在一起(A1→H2D 后铺满整盘,立方体之间无间隔)。这里改为复用 + // update_selected_items_inflation 计算出来的 ap.inflation,使 grid 与 + // NFP 路径在间距/膨胀上的行为一致:副本中心间距 = 物体边长 + 2*inflation。 + if (m_bedpts.empty()) { + BOOST_LOG_TRIVIAL(warning) << "FillBedJob::process[grid]: empty m_bedpts, abort grid fill"; + update_status(m_status_range, _L("Bed filling done.")); + return; + } + + const ArrangePolygon &tmpl = m_selected.front(); + const float inflation_mm = unscaled(tmpl.inflation); + const Vec2f step = unscaled(get_extents(tmpl.poly).size()) + + 2.f * Vec2f(inflation_mm, inflation_mm); // calc the polygon position offset based on origin, in order to normalize the initial position of the arrange polygon - auto offset_on_origin = m_selected.front().poly.contour.bounding_box().center(); - - std::vector empty_cells = Plater::get_empty_cells(step); - size_t n=std::min(m_selected.size(), empty_cells.size()); - for (size_t i = 0; i < n; i++) { - m_selected[i].translation = scaled(empty_cells[i]); - m_selected[i].translation -= offset_on_origin; - m_selected[i].bed_idx= 0; + auto offset_on_origin = tmpl.poly.contour.bounding_box().center(); + + // STUDIO: 与 NFP 路径保持一致,把已经按 bed_shrink + brim_skirt_distance/2 + // 收缩的 m_bedpts 作为安全可放置区域传给 get_empty_cells,避免边缘副本的 + // brim/skirt 越出床边界(之前直接用 build_volume(true),仅含 SceneEpsilon, + // 无安全裕量)。 + BoundingBox shrunk_bb = Polygon{m_bedpts}.bounding_box(); + BoundingBoxf safe_area_2d( + Vec2d(unscale(shrunk_bb.min.x()), unscale(shrunk_bb.min.y())), + Vec2d(unscale(shrunk_bb.max.x()), unscale(shrunk_bb.max.y())) + ); + std::vector empty_cells = Plater::get_empty_cells(step, safe_area_2d); + + // STUDIO (重新落地 STUDIO-16564 的修复): + // 1) 剔除被"已有真实物体"占据的格点。m_unselected 是当前盘上其它非模板对象, + // NFP 路径会把它们当作障碍;以前 grid 路径完全忽略,导致新副本会叠在 + // 它们身上(用户 case:盘上已有 4 个对象,铺满后产生重叠)。 + // 2) 把模板对象自身已有的实例(priority>0)也视为已占据,并在分配阶段跳过 + // 它们,这样多模板实例不会被 grid 循环改写到其它格点;与 NFP 行为对齐。 + // 注:屏蔽区已经在 get_empty_cells 内按 cell.overlap(exclude) 过滤过; + // m_unselected 在 prepare() 中已 stride-corrected 到 plate-0 局部坐标, + // priority>0 模板实例则仍是世界坐标,需要在这里同步 stride 修正后再入列。 + PartPlateList &plist = m_plater->get_partplate_list(); + const int plate_cols = plist.get_plate_cols(); + const int cur_plate_index = plist.get_curr_plate_index(); + const int cur_col = cur_plate_index % plate_cols; + const int cur_row = cur_plate_index / plate_cols; + const coord_t stride_dx = bed_stride_x(m_plater) * cur_col; + const coord_t stride_dy = bed_stride_y(m_plater) * cur_row; + + std::vector occupied; + auto add_occupied_local = [&](const ArrangePolygon &ap, bool needs_stride_correction) { + ArrangePolygon local = ap; + if (needs_stride_correction) { + local.translation(X) -= stride_dx; + local.translation(Y) += stride_dy; + } + BoundingBox sbb = local.transformed_poly().contour.bounding_box(); + occupied.emplace_back( + Vec2d(unscale(sbb.min.x()), unscale(sbb.min.y())), + Vec2d(unscale(sbb.max.x()), unscale(sbb.max.y())) + ); + }; + size_t unsel_blocked = 0, tmpl_blocked = 0; + for (const auto &ap : m_unselected) { + if (ap.is_virt_object || ap.bed_idx != 0) continue; + add_occupied_local(ap, /*needs_stride_correction=*/false); + ++unsel_blocked; + } + for (const auto &ap : m_selected) { + if (ap.priority > 0) { + add_occupied_local(ap, /*needs_stride_correction=*/true); + ++tmpl_blocked; + } + } + + const size_t cells_before = empty_cells.size(); + if (!occupied.empty()) { + const double half_x = step(0) / 2.0; + const double half_y = step(1) / 2.0; + // STUDIO: 用"严格相交(带 ε 容差)"判定 cell 是否被已有对象占据, + // 替代 BoundingBox::overlap 的"贴边即重叠"行为。背景:step、cell 中心 + // 与模板 AABB 相加以后会落在浮点不可精确表示的尾数上,正负 ε 方向不 + // 一致会导致左右贴边的对称破缺,整版网格出现不规则缺口。这里要求 cell + // 与障碍 AABB 至少有 EPSILON 的正面积交集才剔除,纯贴边视为可放置。 + auto strict_overlap = [](const BoundingBoxf &a, const BoundingBoxf &b) { + const double ix = std::min(a.max.x(), b.max.x()) - std::max(a.min.x(), b.min.x()); + const double iy = std::min(a.max.y(), b.max.y()) - std::max(a.min.y(), b.min.y()); + return ix > EPSILON && iy > EPSILON; + }; + empty_cells.erase( + std::remove_if(empty_cells.begin(), empty_cells.end(), + [&](const Vec2f &c) { + BoundingBoxf cell( + Vec2d(c.x() - half_x, c.y() - half_y), + Vec2d(c.x() + half_x, c.y() + half_y) + ); + for (const auto &bb : occupied) + if (strict_overlap(bb, cell)) return true; + return false; + }), + empty_cells.end() + ); } - for (size_t i = n; i < m_selected.size(); i++) { - m_selected[i].bed_idx = -1; + + // 分配剩余格点:模板实例(priority>0)保持原位置不动;只把"新副本" + // (priority==0) 顺序填进 empty_cells,超出格点数则置为未排上 (-1)。 + size_t cell_idx = 0, placed = 0, skipped = 0; + for (size_t i = 0; i < m_selected.size(); ++i) { + if (m_selected[i].priority > 0) { + m_selected[i].bed_idx = 0; + continue; + } + if (cell_idx < empty_cells.size()) { + m_selected[i].translation = scaled(empty_cells[cell_idx]); + m_selected[i].translation -= offset_on_origin; + m_selected[i].bed_idx = 0; + ++cell_idx; + ++placed; + } else { + m_selected[i].bed_idx = -1; + ++skipped; + } } + + BOOST_LOG_TRIVIAL(debug) << "FillBedJob::process[grid]: selected=" << m_selected.size() + << ", unselected=" << m_unselected.size() + << ", inflation_mm=" << inflation_mm + << ", cells " << cells_before << "->" << empty_cells.size() + << " (blocked unsel=" << unsel_blocked << ", tmpl=" << tmpl_blocked << ")" + << ", placed=" << placed << ", skipped=" << skipped; } else arrangement::arrange(m_selected, m_unselected, m_bedpts, params); @@ -291,12 +437,15 @@ void FillBedJob::finalize() else ap.bed_idx = cur_plate; - if (m_selected.size() <= 100) { - ap.row = ap.bed_idx / plate_cols; - ap.col = ap.bed_idx % plate_cols; - ap.translation(X) += bed_stride_x(m_plater) * ap.col; - ap.translation(Y) -= bed_stride_y(m_plater) * ap.row; - } + // STUDIO: 把 plate-0 局部坐标平移回 cur_plate 的世界坐标。 + // grid 路径(m_selected.size()>100)下 priority>0 的模板实例没有 setter, + // apply() 是空操作,因此对它们的 translation 多加一份 stride 不会有副作用; + // priority==0 的新副本则需要这一步才能落在正确的盘上(修复 STUDIO-15820 在 + // 非 0 号盘铺满整盘时副本被错放到 0 号盘的问题)。 + ap.row = ap.bed_idx / plate_cols; + ap.col = ap.bed_idx % plate_cols; + ap.translation(X) += bed_stride_x(m_plater) * ap.col; + ap.translation(Y) -= bed_stride_y(m_plater) * ap.row; ap.apply(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b2a3260d33..1a37b30945 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -65,6 +65,7 @@ #include "FilamentMapDialog.hpp" #include "DeviceCore/DevManager.h" +#include "slic3r/GUI/DeviceWeb/DeviceWebPage.hpp" #ifdef _WIN32 #include @@ -1100,13 +1101,31 @@ void MainFrame::show_calibration_button(bool show, bool is_BBL) topbar()->ShowCalibrationButton(show); #endif show = is_BBL; - auto shown2 = m_tabpanel->FindPage(m_calibration) != wxNOT_FOUND; + // STUDIO-18116: locate the Calibration tab by its page pointer instead of relying on + // the hardcoded `tpCalibration` enum index. The enum value (6) is calibrated for the + // multi_machine-enabled layout (8 pages); when multi_machine is disabled the actual + // notebook only has 7 pages and Calibration sits at index 5 while the Filament Manager + // tab sits at index 6. Calling RemovePage(tpCalibration=6) in that situation removes + // the Filament Manager tab instead, which is exactly the "no Filament Manager tab on + // first launch" symptom users hit when no BBL preset is selected yet. + int cal_page_id = m_tabpanel->FindPage(m_calibration); + auto shown2 = cal_page_id != wxNOT_FOUND; if (shown2 == show) ; - else if (show) - m_tabpanel->InsertPage(tpCalibration, m_calibration, _L("Calibration"), std::string("tab_monitor_active"), std::string("tab_monitor_active"), false); - else - m_tabpanel->RemovePage(tpCalibration); + else if (show) { + // Insert right before the Filament Manager tab (or append if it isn't there) so + // the visual order stays Project / Calibration / Filament Manager regardless of + // how many leading plater pages update_layout() has inserted. + int fm_page_id = m_web_device ? m_tabpanel->FindPage(m_web_device) : wxNOT_FOUND; + size_t insert_at = (fm_page_id != wxNOT_FOUND) + ? static_cast(fm_page_id) + : m_tabpanel->GetPageCount(); + m_tabpanel->InsertPage(insert_at, m_calibration, _L("Calibration"), + std::string("tab_monitor_active"), + std::string("tab_monitor_active"), false); + } else { + m_tabpanel->RemovePage(static_cast(cal_page_id)); + } } void MainFrame::update_title_colour_after_set_title() @@ -1158,6 +1177,9 @@ void MainFrame::init_tabpanel() m_settings_dialog.set_tabpanel(m_tabpanel); m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGING, [this](wxBookCtrlEvent& e) { + int old_sel = e.GetOldSelection(); + int new_sel = e.GetSelection(); + //if (bool test = false) { // SupportRecommendDialog* dialog = new SupportRecommendDialog(nullptr, _L("Notice"));; @@ -1188,8 +1210,6 @@ void MainFrame::init_tabpanel() // dialog->ShowModal(); //} - int old_sel = e.GetOldSelection(); - int new_sel = e.GetSelection(); if (old_sel != wxNOT_FOUND && new_sel != old_sel && m_project != nullptr && @@ -1288,6 +1308,17 @@ void MainFrame::init_tabpanel() if (agent) agent->track_update_property("select_device_page", std::to_string(++select_device_page_count)); } + else if (panel == m_web_device) { +#if defined(__WXOSX__) + // Defer hash navigation until after the notebook paints (macOS + WKWebView). + CallAfter([this]() { + if (m_web_device && m_tabpanel && m_tabpanel->GetCurrentPage() == m_web_device) + m_web_device->NavigateTo("/filament"); + }); +#else + m_web_device->NavigateTo("/filament"); +#endif + } #ifndef __APPLE__ if (sel == tp3DEditor) { m_topbar->EnableUndoRedoItems(); @@ -1297,7 +1328,12 @@ void MainFrame::init_tabpanel() } #endif #ifndef __WXGTK__ - if (panel) + // macOS: avoid moving first responder into WKWebView on Filament Manager (STUDIO-18111). + if (panel +#if defined(__WXOSX__) + && panel != m_web_device +#endif + ) panel->SetFocus(); #endif /*switch (sel) { @@ -1366,6 +1402,9 @@ void MainFrame::init_tabpanel() m_calibration->SetBackgroundColour(*wxWHITE); m_tabpanel->AddPage(m_calibration, _L("Calibration"), std::string("tab_calibration_active"), std::string("tab_calibration_active"), false); + m_web_device = new DeviceWebPage(m_tabpanel); + m_tabpanel->AddPage(m_web_device, _L("Filament Manager"), std::string("tab_filament_active"), std::string("tab_filament_active"), false); + if (m_plater) { // load initial config auto full_config = wxGetApp().preset_bundle->full_config(); @@ -2469,6 +2508,8 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect) if (m_multi_machine) m_multi_machine->msw_rescale(); m_calibration->msw_rescale(); + if (m_web_device) + m_web_device->msw_rescale(); // BBS #if 0 @@ -2528,6 +2569,7 @@ void MainFrame::on_sys_color_changed() wxGetApp().plater()->sys_color_changed(); m_monitor->on_sys_color_changed(); m_calibration->on_sys_color_changed(); + if (m_web_device) m_web_device->on_sys_color_changed(); // update Tabs for (auto tab : wxGetApp().tabs_list) tab->sys_color_changed(); @@ -2751,11 +2793,11 @@ void MainFrame::init_menubar_as_editor() #ifndef __APPLE__ - append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + _L("Shift+") + "S", _L("Save current project as"), + append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + "Shift+" + "S", _L("Save current project as"), [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, "menu_save", nullptr, [this](){return m_plater != nullptr && can_save_as(); }, this); #else - append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + _L("Shift+") + "S", _L("Save current project as"), + append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + "Shift+" + "S", _L("Save current project as"), [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, "", nullptr, [this](){return m_plater != nullptr && can_save_as(); }, this); #endif @@ -2899,7 +2941,7 @@ void MainFrame::init_menubar_as_editor() _L("Deletes the current selection"),[this](wxCommandEvent&) { m_plater->remove_selected(); }, "menu_remove", nullptr, [this](){return can_delete(); }, this); //BBS: delete all - append_menu_item(editMenu, wxID_ANY, _L("Delete all") + "\t" + ctrl + _L("Shift+") + "D", + append_menu_item(editMenu, wxID_ANY, _L("Delete all") + "\t" + ctrl + "Shift+" + "D", _L("Deletes all objects"),[this](wxCommandEvent&) { m_plater->delete_all_objects_from_model(); }, "menu_remove", nullptr, [this](){return can_delete_all(); }, this); editMenu->AppendSeparator(); @@ -2981,7 +3023,7 @@ void MainFrame::init_menubar_as_editor() "", nullptr, [this](){return can_delete(); }, this); #endif //BBS: delete all - append_menu_item(editMenu, wxID_ANY, _L("Delete all") + "\t" + ctrl + _L("Shift+") + "D", + append_menu_item(editMenu, wxID_ANY, _L("Delete all") + "\t" + ctrl + "Shift+" + "D", _L("Deletes all objects"),[this, handle_key_event](wxCommandEvent&) { wxKeyEvent e; e.SetEventType(wxEVT_KEY_DOWN); @@ -3101,7 +3143,7 @@ void MainFrame::init_menubar_as_editor() append_menu_check_item(viewMenu, wxID_ANY, _L("Show Labels by Layer") + "\t" + ctrl + "E", _L("Show Labels of printing by layer in 3D scene"), [this](wxCommandEvent&) { m_plater->show_view3D_layer_labels(!m_plater->are_view3D_layer_labels_shown()); m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, this, [this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_layer_labels_shown(); }, this); - append_menu_check_item(viewMenu, wxID_ANY, _L("Show Labels by Object") + "\t" + _L("Shift+") + "E", _L("Show Labels of printing by object in 3D scene"), + append_menu_check_item(viewMenu, wxID_ANY, _L("Show Labels by Object") + "\t" + ctrl + "Shift+" + "E", _L("Show Labels of printing by object in 3D scene"), [this](wxCommandEvent&) { m_plater->show_view3D_object_labels(!m_plater->are_view3D_object_labels_shown()); m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, this, [this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_object_labels_shown(); }, this); diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 4b36d5307e..bb91a740ae 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -51,6 +51,7 @@ class Plater; class MainFrame; class ParamsDialog; class FilamentGroupPopup; +class DeviceWebPage; enum QuickSlice { @@ -209,6 +210,7 @@ class MainFrame : public DPIFrame #ifdef __APPLE__ bool get_mac_full_screen() { return m_mac_fullscreen; } #endif + DeviceWebPage* web_device() const { return m_web_device; } //BBS GUI refactor enum TabPosition { @@ -218,9 +220,11 @@ class MainFrame : public DPIFrame tpMonitor = 3, tpMultiDevice = 4, tpProject = 5, - tpCalibration = 6, - tpAuxiliary = 7, - toDebugTool = 8, + tpCalibration = 6, + tpAuxiliary = 7, + toDebugTool = 8, + tpFilamentManager = 9, + tpWebDevice = 10, }; //BBS: add slice&&print status update logic @@ -378,6 +382,7 @@ class MainFrame : public DPIFrame ProjectPanel* m_project{ nullptr }; CalibrationPanel* m_calibration{ nullptr }; + DeviceWebPage* m_web_device{ nullptr }; WebViewPanel* m_webview { nullptr }; PrinterWebView* m_printer_view{nullptr}; wxLogWindow* m_log_window { nullptr }; diff --git a/src/slic3r/GUI/MixedFilamentDialog.cpp b/src/slic3r/GUI/MixedFilamentDialog.cpp index 64f603e0b6..61dcf92798 100644 --- a/src/slic3r/GUI/MixedFilamentDialog.cpp +++ b/src/slic3r/GUI/MixedFilamentDialog.cpp @@ -2,23 +2,27 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include "libslic3r/Utils.hpp" +#include "libslic3r/FilamentMixer.hpp" #include "I18N.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "Tab.hpp" #include "libslic3r/Preset.hpp" #include "Widgets/Button.hpp" +#include "Widgets/CheckBox.hpp" #include "Widgets/ComboBox.hpp" #include "Widgets/DropDown.hpp" #include "Widgets/Label.hpp" @@ -30,24 +34,26 @@ static constexpr int MAX_COMPONENTS = 3; static wxColour blend_colors(const wxColour& a, const wxColour& b, double ratio_a) { - double rb = 1.0 - ratio_a; - return wxColour( - (unsigned char)(a.Red() * ratio_a + b.Red() * rb), - (unsigned char)(a.Green() * ratio_a + b.Green() * rb), - (unsigned char)(a.Blue() * ratio_a + b.Blue() * rb)); + unsigned char r, g, bl; + Slic3r::filament_mixer_lerp(a.Red(), a.Green(), a.Blue(), + b.Red(), b.Green(), b.Blue(), + static_cast(1.0 - ratio_a), + &r, &g, &bl); + return wxColour(r, g, bl); } static wxColour blend_n_colors(const std::vector& cols, const std::vector& weights) { - double r = 0, g = 0, b = 0; + std::vector hex_colors; + std::vector int_weights; for (size_t i = 0; i < cols.size() && i < weights.size(); ++i) { - r += cols[i].Red() * weights[i]; - g += cols[i].Green() * weights[i]; - b += cols[i].Blue() * weights[i]; + hex_colors.push_back(cols[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString()); + // Scale double weights (e.g. 0.5) to int (5000) for blend_color_multi; + // only relative magnitude matters. + int_weights.push_back(static_cast(std::lround(weights[i] * 10000))); } - return wxColour((unsigned char)std::clamp(r, 0.0, 255.0), - (unsigned char)std::clamp(g, 0.0, 255.0), - (unsigned char)std::clamp(b, 0.0, 255.0)); + std::string hex = Slic3r::blend_color_multi(hex_colors, int_weights); + return wxColour(hex); } // ---- Constructors ---- @@ -126,6 +132,35 @@ wxColour MixedFilamentDialog::comp_colour(size_t i) const return wxColour("#D9D9D9"); } +static wxBitmap make_alpha_bitmap(int w, int h, + const std::function& draw_fn) +{ + wxBitmap bmp(w, h); + wxMemoryDC memdc; +#ifdef __WXOSX__ + bmp.UseAlpha(); + memdc.SelectObject(bmp); +#else + { + wxImage img(w, h); + img.InitAlpha(); + memset(img.GetAlpha(), 0, w * h); + bmp = wxBitmap(std::move(img)); + } + memdc.SelectObject(bmp); +#endif + { +#ifdef __WXMSW__ + wxGCDC dc(memdc); +#else + wxDC& dc = memdc; +#endif + draw_fn(dc); + } + memdc.SelectObject(wxNullBitmap); + return bmp; +} + wxBitmap MixedFilamentDialog::make_swatch_bitmap(size_t idx) { int swatch_sz = FromDIP(16); @@ -134,42 +169,33 @@ wxBitmap MixedFilamentDialog::make_swatch_bitmap(size_t idx) int bmp_w = pad_left + swatch_sz + pad_right; int bmp_h = swatch_sz; - wxBitmap bmp(bmp_w, bmp_h); - wxMemoryDC dc(bmp); - wxColour col("#D9D9D9"); if (idx < m_physical_colors.size()) col = wxColour(m_physical_colors[idx]); - wxColour swatch_bg = StateColor::darkModeColorFor(*wxWHITE); - dc.SetBrush(wxBrush(swatch_bg)); - dc.SetPen(wxPen(swatch_bg)); - dc.DrawRectangle(0, 0, bmp_w, bmp_h); - - dc.SetBrush(wxBrush(col)); - dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRoundedRectangle(pad_left, 0, swatch_sz, swatch_sz, FromDIP(2)); - - if (!wxGetApp().dark_mode() && col.Red() > 224 && col.Green() > 224 && col.Blue() > 224) { - dc.SetPen(wxPen(wxColour(130, 130, 128), 1)); - dc.SetBrush(*wxTRANSPARENT_BRUSH); - dc.DrawRoundedRectangle(pad_left, 0, swatch_sz, swatch_sz, FromDIP(2)); - } - if (wxGetApp().dark_mode() && col.Red() < 45 && col.Green() < 45 && col.Blue() < 45) { - dc.SetPen(wxPen(wxColour(207, 207, 207), 1)); - dc.SetBrush(*wxTRANSPARENT_BRUSH); + return make_alpha_bitmap(bmp_w, bmp_h, [&](wxDC& dc) { + dc.SetBrush(wxBrush(col)); + dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRoundedRectangle(pad_left, 0, swatch_sz, swatch_sz, FromDIP(2)); - } - wxString num = wxString::Format(wxT("%zu"), idx + 1); - dc.SetFont(::Label::Body_13); - wxSize txt_sz = dc.GetTextExtent(num); - dc.SetTextForeground(col.GetLuminance() > 0.5 ? wxColour(50, 58, 61) : *wxWHITE); - dc.DrawText(num, pad_left + (swatch_sz - txt_sz.GetWidth()) / 2, - (swatch_sz - txt_sz.GetHeight()) / 2); + if (!wxGetApp().dark_mode() && col.Red() > 224 && col.Green() > 224 && col.Blue() > 224) { + dc.SetPen(wxPen(wxColour(130, 130, 128), 1)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(pad_left, 0, swatch_sz, swatch_sz, FromDIP(2)); + } + if (wxGetApp().dark_mode() && col.Red() < 45 && col.Green() < 45 && col.Blue() < 45) { + dc.SetPen(wxPen(wxColour(207, 207, 207), 1)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(pad_left, 0, swatch_sz, swatch_sz, FromDIP(2)); + } - dc.SelectObject(wxNullBitmap); - return bmp; + wxString num = wxString::Format(wxT("%zu"), idx + 1); + dc.SetFont(::Label::Body_13); + wxSize txt_sz = dc.GetTextExtent(num); + dc.SetTextForeground(col.GetLuminance() > 0.5 ? wxColour(50, 58, 61) : *wxWHITE); + dc.DrawText(num, pad_left + (swatch_sz - txt_sz.GetWidth()) / 2, + (swatch_sz - txt_sz.GetHeight()) / 2); + }); } // ---- UI Construction ---- @@ -239,17 +265,12 @@ wxBoxSizer* MixedFilamentDialog::create_preview_panel() wxBufferedPaintDC dc(m_preview_canvas); wxSize sz = m_preview_canvas->GetClientSize(); size_t n = num_components(); - if (n == 0) return; - const wxBitmap& src = (n >= 3) ? m_preview_bmp_three : m_preview_bmp_two; - if (src.IsOk()) { - wxImage scaled = src.ConvertToImage().Scale(sz.GetWidth(), sz.GetHeight(), wxIMAGE_QUALITY_BILINEAR); - dc.DrawBitmap(wxBitmap(scaled), 0, 0, true); - } else { - dc.SetBrush(wxBrush(StateColor::darkModeColorFor(*wxWHITE))); - dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight()); - } + dc.SetBrush(wxBrush(StateColor::darkModeColorFor(*wxWHITE))); + dc.SetPen(*wxTRANSPARENT_PEN); + dc.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight()); + + if (n == 0) return; std::vector cols; std::vector weights; @@ -259,10 +280,11 @@ wxBoxSizer* MixedFilamentDialog::create_preview_panel() } wxColour mixed = blend_n_colors(cols, weights); - int swatch_sz = FromDIP(16); + int swatch_sz = FromDIP(80); dc.SetBrush(wxBrush(mixed)); dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRoundedRectangle(FromDIP(4), FromDIP(4), swatch_sz, swatch_sz, FromDIP(2)); + dc.DrawRoundedRectangle((sz.GetWidth() - swatch_sz) / 2, (sz.GetHeight() - swatch_sz) / 2, + swatch_sz, swatch_sz, FromDIP(6)); }); sizer->Add(m_preview_canvas, 0, wxALIGN_CENTER); @@ -360,7 +382,7 @@ wxBoxSizer* MixedFilamentDialog::create_material_selection() m_btn_add_material->SetBackgroundColor(wxColour("#F8F8F8")); m_btn_add_material->SetBorderColor(wxColour("#EEEEEE")); m_btn_add_material->SetTextColor(wxColour("#262E30")); - m_btn_add_material->SetMinSize(wxSize(-1, FromDIP(23))); + m_btn_add_material->SetMinSize(wxSize(-1, FromDIP(24))); m_btn_add_material->SetCursor(wxCursor(wxCURSOR_HAND)); m_btn_add_material->EnableTooltipEvenDisabled(); m_btn_add_material->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_add_material(); }); @@ -370,7 +392,7 @@ wxBoxSizer* MixedFilamentDialog::create_material_selection() m_btn_remove_material->SetBackgroundColor(wxColour("#F8F8F8")); m_btn_remove_material->SetBorderColor(wxColour("#EEEEEE")); m_btn_remove_material->SetTextColor(wxColour("#262E30")); - m_btn_remove_material->SetMinSize(wxSize(-1, FromDIP(23))); + m_btn_remove_material->SetMinSize(wxSize(-1, FromDIP(24))); m_btn_remove_material->SetCursor(wxCursor(wxCURSOR_HAND)); m_btn_remove_material->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_remove_material(); }); m_btn_remove_material->Hide(); @@ -408,6 +430,8 @@ wxBoxSizer* MixedFilamentDialog::create_ratio_slider() } int div_x = (int)(ratio(1) / 100.0 * sz.GetWidth()); + dc.SetPen(wxPen(StateColor::darkModeColorFor(wxColour(80, 80, 80)), FromDIP(4))); + dc.DrawLine(div_x, 0, div_x, sz.GetHeight()); dc.SetPen(wxPen(*wxWHITE, FromDIP(2))); dc.DrawLine(div_x, 0, div_x, sz.GetHeight()); }); @@ -534,46 +558,65 @@ wxBoxSizer* MixedFilamentDialog::create_triangle_picker() wxColour c0 = comp_colour(0), c1 = comp_colour(1), c2 = comp_colour(2); - int min_y = (int)std::min({v0.y, v1.y, v2.y}); - int max_y = (int)std::max({v0.y, v1.y, v2.y}); - int min_x = (int)std::min({v0.x, v1.x, v2.x}); - int max_x = (int)std::max({v0.x, v1.x, v2.x}); - - wxBitmap bmp(sz.GetWidth(), sz.GetHeight(), 24); - wxMemoryDC mdc(bmp); - mdc.SetBrush(wxBrush(tri_bg)); - mdc.SetPen(*wxTRANSPARENT_PEN); - mdc.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight()); - - for (int py = min_y; py <= max_y; ++py) { - for (int px = min_x; px <= max_x; ++px) { - TriPoint p = {(double)px, (double)py}; - if (!tri_contains(p, v0, v1, v2)) continue; - double w0, w1, w2; - tri_barycentric(p, v0, v1, v2, w0, w1, w2); - int r = (int)(c0.Red() * w0 + c1.Red() * w1 + c2.Red() * w2); - int g = (int)(c0.Green() * w0 + c1.Green() * w1 + c2.Green() * w2); - int b = (int)(c0.Blue() * w0 + c1.Blue() * w1 + c2.Blue() * w2); - mdc.SetPen(wxPen(wxColour(std::clamp(r, 0, 255), std::clamp(g, 0, 255), std::clamp(b, 0, 255)))); - mdc.DrawPoint(px, py); + const bool cache_valid = m_tri_cache_bmp.IsOk() && + m_tri_cache_size == sz && + m_tri_cache_c0 == c0 && m_tri_cache_c1 == c1 && m_tri_cache_c2 == c2; + + if (!cache_valid) { + int min_y = (int)std::min({v0.y, v1.y, v2.y}); + int max_y = (int)std::max({v0.y, v1.y, v2.y}); + int min_x = (int)std::min({v0.x, v1.x, v2.x}); + int max_x = (int)std::max({v0.x, v1.x, v2.x}); + + m_tri_cache_bmp = wxBitmap(sz.GetWidth(), sz.GetHeight(), 24); + wxMemoryDC mdc(m_tri_cache_bmp); + mdc.SetBrush(wxBrush(tri_bg)); + mdc.SetPen(*wxTRANSPARENT_PEN); + mdc.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight()); + + for (int py = min_y; py <= max_y; ++py) { + for (int px = min_x; px <= max_x; ++px) { + TriPoint p = {(double)px, (double)py}; + if (!tri_contains(p, v0, v1, v2)) continue; + double w0, w1, w2; + tri_barycentric(p, v0, v1, v2, w0, w1, w2); + unsigned char mr, mg, mb; + if (w0 + w1 > 1e-6) { + float t01 = static_cast(w1 / (w0 + w1)); + Slic3r::filament_mixer_lerp(c0.Red(), c0.Green(), c0.Blue(), + c1.Red(), c1.Green(), c1.Blue(), + t01, &mr, &mg, &mb); + float t2 = static_cast(w2); + Slic3r::filament_mixer_lerp(mr, mg, mb, + c2.Red(), c2.Green(), c2.Blue(), + t2, &mr, &mg, &mb); + } else { + mr = c2.Red(); mg = c2.Green(); mb = c2.Blue(); + } + mdc.SetPen(wxPen(wxColour(mr, mg, mb))); + mdc.DrawPoint(px, py); + } } + + mdc.SetPen(wxPen(StateColor::darkModeColorFor(wxColour("#CECECE")), 1)); + mdc.SetBrush(*wxTRANSPARENT_BRUSH); + wxPoint pts[3] = {{(int)v0.x, (int)v0.y}, {(int)v1.x, (int)v1.y}, {(int)v2.x, (int)v2.y}}; + mdc.DrawPolygon(3, pts); + + mdc.SelectObject(wxNullBitmap); + m_tri_cache_c0 = c0; m_tri_cache_c1 = c1; m_tri_cache_c2 = c2; + m_tri_cache_size = sz; } - mdc.SetPen(wxPen(StateColor::darkModeColorFor(wxColour("#CECECE")), 1)); - mdc.SetBrush(*wxTRANSPARENT_BRUSH); - wxPoint pts[3] = {{(int)v0.x, (int)v0.y}, {(int)v1.x, (int)v1.y}, {(int)v2.x, (int)v2.y}}; - mdc.DrawPolygon(3, pts); + dc.DrawBitmap(m_tri_cache_bmp, 0, 0); - // Drag handle + // Drag handle (always redrawn on top of cached bitmap) double hx = m_tri_wx * v0.x + m_tri_wy * v1.x + m_tri_wz * v2.x; double hy = m_tri_wx * v0.y + m_tri_wy * v1.y + m_tri_wz * v2.y; int handle_r = FromDIP(5); - mdc.SetBrush(*wxWHITE_BRUSH); - mdc.SetPen(wxPen(wxColour("#262E30"), FromDIP(2))); - mdc.DrawCircle((int)hx, (int)hy, handle_r); - - mdc.SelectObject(wxNullBitmap); - dc.DrawBitmap(bmp, 0, 0); + dc.SetBrush(*wxWHITE_BRUSH); + dc.SetPen(wxPen(wxColour("#262E30"), FromDIP(2))); + dc.DrawCircle((int)hx, (int)hy, handle_r); dc.SetFont(::Label::Body_10); dc.SetTextForeground(StateColor::darkModeColorFor(wxColour("#262E30"))); @@ -650,13 +693,15 @@ wxBoxSizer* MixedFilamentDialog::create_gradient_section() { m_gradient_sizer = new wxBoxSizer(wxHORIZONTAL); - m_chk_gradient = new wxCheckBox(this, wxID_ANY, _L("Gradient Effect")); + m_chk_gradient = new ::CheckBox(this); m_chk_gradient->SetValue(m_result.gradient_enabled); - m_chk_gradient->SetFont(::Label::Body_13); - m_chk_gradient->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { on_gradient_toggled(); }); - + m_chk_gradient->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) { e.Skip(); on_gradient_toggled(); }); m_gradient_sizer->Add(m_chk_gradient, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, FromDIP(4)); + m_label_gradient = new wxStaticText(this, wxID_ANY, _L("Gradient Effect")); + m_label_gradient->SetFont(::Label::Body_13); + m_gradient_sizer->Add(m_label_gradient, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(8)); + m_combo_gradient_dir = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(152), FromDIP(24)), 0, nullptr, wxCB_READONLY); m_combo_gradient_dir->SetKeepDropArrow(true); @@ -682,7 +727,7 @@ wxBoxSizer* MixedFilamentDialog::create_recommendation_grid() auto* rec_line = new wxPanel(this, wxID_ANY); rec_line->SetMinSize(wxSize(-1, 1)); - rec_line->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#ACACAC"))); + rec_line->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#DFDFDF"))); title_sizer->Add(rec_line, 1, wxALIGN_CENTER_VERTICAL); outer->Add(title_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(4)); @@ -692,7 +737,9 @@ wxBoxSizer* MixedFilamentDialog::create_recommendation_grid() m_recommendation_scroll->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#F8F8F8"))); m_recommendation_grid = new wxWrapSizer(wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS); - m_recommendation_scroll->SetSizer(m_recommendation_grid); + auto* scroll_inner_sizer = new wxBoxSizer(wxVERTICAL); + scroll_inner_sizer->Add(m_recommendation_grid, 1, wxEXPAND | wxLEFT | wxTOP, FromDIP(8)); + m_recommendation_scroll->SetSizer(scroll_inner_sizer); rebuild_recommendation_items(); @@ -1270,45 +1317,38 @@ void MixedFilamentDialog::update_gradient_direction_items() int bmp_w = swatch_sz + gap + arrow_w + gap + swatch_sz; int bmp_h = swatch_sz; - wxBitmap bmp(bmp_w, bmp_h); - wxMemoryDC dc(bmp); - - wxColour dir_bg = StateColor::darkModeColorFor(*wxWHITE); wxColour dir_text = StateColor::darkModeColorFor(wxColour("#262E30")); - dc.SetBrush(wxBrush(dir_bg)); - dc.SetPen(wxPen(dir_bg)); - dc.DrawRectangle(0, 0, bmp_w, bmp_h); - dc.SetFont(::Label::Body_13); - auto draw_swatch = [&](int x, size_t idx) { - wxColour col("#D9D9D9"); - if (idx < m_physical_colors.size()) - col = wxColour(m_physical_colors[idx]); - dc.SetBrush(wxBrush(col)); - dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRoundedRectangle(x, 0, swatch_sz, swatch_sz, FromDIP(2)); - wxString num = wxString::Format(wxT("%zu"), idx + 1); - wxSize txt_sz = dc.GetTextExtent(num); - dc.SetTextForeground(col.GetLuminance() > 0.5 ? dir_text : *wxWHITE); - dc.DrawText(num, x + (swatch_sz - txt_sz.GetWidth()) / 2, - (swatch_sz - txt_sz.GetHeight()) / 2); - }; - - int x = 0; - draw_swatch(x, idx_from); - x += swatch_sz + gap; - - dc.SetTextForeground(dir_text); - wxString arrow = wxT("\u2192"); - wxSize arrow_sz = dc.GetTextExtent(arrow); - dc.DrawText(arrow, x + (arrow_w - arrow_sz.GetWidth()) / 2, - (bmp_h - arrow_sz.GetHeight()) / 2); - x += arrow_w + gap; - - draw_swatch(x, idx_to); - - dc.SelectObject(wxNullBitmap); - return bmp; + return make_alpha_bitmap(bmp_w, bmp_h, [&](wxDC& dc) { + dc.SetFont(::Label::Body_13); + + auto draw_swatch = [&](int x, size_t idx) { + wxColour col("#D9D9D9"); + if (idx < m_physical_colors.size()) + col = wxColour(m_physical_colors[idx]); + dc.SetBrush(wxBrush(col)); + dc.SetPen(*wxTRANSPARENT_PEN); + dc.DrawRoundedRectangle(x, 0, swatch_sz, swatch_sz, FromDIP(2)); + wxString num = wxString::Format(wxT("%zu"), idx + 1); + wxSize txt_sz = dc.GetTextExtent(num); + dc.SetTextForeground(col.GetLuminance() > 0.5 ? dir_text : *wxWHITE); + dc.DrawText(num, x + (swatch_sz - txt_sz.GetWidth()) / 2, + (swatch_sz - txt_sz.GetHeight()) / 2); + }; + + int x = 0; + draw_swatch(x, idx_from); + x += swatch_sz + gap; + + dc.SetTextForeground(dir_text); + wxString arrow = wxT("\u2192"); + wxSize arrow_sz = dc.GetTextExtent(arrow); + dc.DrawText(arrow, x + (arrow_w - arrow_sz.GetWidth()) / 2, + (bmp_h - arrow_sz.GetHeight()) / 2); + x += arrow_w + gap; + + draw_swatch(x, idx_to); + }); }; size_t idx_a = (comp(0) >= 1) ? comp(0) - 1 : 0; @@ -1338,6 +1378,7 @@ void MixedFilamentDialog::update_component_count_ui() if (m_gradient_sizer) { bool show_gradient = is_two; m_chk_gradient->Show(show_gradient); + if (m_label_gradient) m_label_gradient->Show(show_gradient); m_combo_gradient_dir->Show(show_gradient && m_result.gradient_enabled); } if (is_three) { diff --git a/src/slic3r/GUI/MixedFilamentDialog.hpp b/src/slic3r/GUI/MixedFilamentDialog.hpp index 2633c9bab1..e1b6193405 100644 --- a/src/slic3r/GUI/MixedFilamentDialog.hpp +++ b/src/slic3r/GUI/MixedFilamentDialog.hpp @@ -5,12 +5,13 @@ #include #include #include -#include +#include #include #include "GUI_Utils.hpp" class Button; +class CheckBox; class ComboBox; class wxScrolledWindow; class wxWrapSizer; @@ -97,7 +98,8 @@ class MixedFilamentDialog : public DPIDialog wxPanel* m_triangle_panel{nullptr}; wxStaticText* m_label_ratio_a{nullptr}; wxStaticText* m_label_ratio_b{nullptr}; - wxCheckBox* m_chk_gradient{nullptr}; + CheckBox* m_chk_gradient{nullptr}; + wxStaticText* m_label_gradient{nullptr}; ComboBox* m_combo_gradient_dir{nullptr}; wxBoxSizer* m_gradient_sizer{nullptr}; Button* m_btn_add_material{nullptr}; @@ -122,6 +124,11 @@ class MixedFilamentDialog : public DPIDialog bool m_dragging{false}; // Triangle picker drag point (barycentric weights) double m_tri_wx{0.333}, m_tri_wy{0.333}, m_tri_wz{0.334}; + + // Cached triangle color bitmap (invalidated when colors or size change) + wxBitmap m_tri_cache_bmp; + wxColour m_tri_cache_c0, m_tri_cache_c1, m_tri_cache_c2; + wxSize m_tri_cache_size; }; } // namespace GUI diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index a16cc9edc9..0876a0a806 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -9,9 +9,11 @@ #include #include #include +#include #include +#include "Widgets/Label.hpp" #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" #include "GUI.hpp" @@ -396,6 +398,73 @@ WarningDialog::WarningDialog(wxWindow *parent, finalize(); } +PostProcessScriptDialog::PostProcessScriptDialog(wxWindow* parent, const wxString& message, const wxString& script_content) + : MsgDialog(parent, + wxString::Format(_L("%s warning"), SLIC3R_APP_FULL_NAME), + wxString::Format(_L("%s has a warning") + ":", SLIC3R_APP_FULL_NAME), + wxICON_WARNING) +{ + const int content_width = FromDIP(500); + wxFont msg_font = wxGetApp().normal_font(); + msg_font.SetPointSize(wxGetApp().code_font().GetPointSize()); + auto* msg = new Label(this, msg_font, message, LB_AUTO_WRAP, wxSize(content_width, -1)); + msg->SetMinSize(wxSize(content_width, -1)); + msg->SetForegroundColour(wxGetApp().get_label_clr_default()); + msg->Wrap(content_width); + content_sizer->Add(msg, 0, wxEXPAND | wxBOTTOM, FromDIP(8)); + + m_script_text = new wxTextCtrl(this, wxID_ANY, script_content, wxDefaultPosition, + wxSize(content_width, FromDIP(140)), wxTE_MULTILINE | wxTE_READONLY | wxTE_WORDWRAP); + m_script_text->SetFont(wxGetApp().code_font()); + m_details_expanded = true; + content_sizer->Add(m_script_text, 0, wxEXPAND | wxBOTTOM, FromDIP(8)); + + m_toggle_details = new Button(this, _L("Collapse") + " \u2227", "", 0, 0, wxID_ANY); + m_toggle_details->SetMinSize(wxSize(FromDIP(120), FromDIP(24))); + m_toggle_details->SetCornerRadius(FromDIP(12)); + m_toggle_details->SetFont(Label::Body_12); + StateColor btn_bg_white( + std::pair(wxColour(255, 255, 255), StateColor::Pressed), + std::pair(wxColour(255, 255, 255), StateColor::Hovered), + std::pair(wxColour(255, 255, 255), StateColor::Normal) + ); + StateColor btn_bd_white( + std::pair(WXCOLOUR_GREY500, StateColor::Pressed), + std::pair(WXCOLOUR_GREY500, StateColor::Hovered), + std::pair(WXCOLOUR_GREY500, StateColor::Normal) + ); + StateColor btn_text_white( + std::pair(WXCOLOUR_GREY700, StateColor::Pressed), + std::pair(WXCOLOUR_GREY700, StateColor::Hovered), + std::pair(WXCOLOUR_GREY700, StateColor::Normal) + ); + m_toggle_details->SetBackgroundColor(btn_bg_white); + m_toggle_details->SetBorderColor(btn_bd_white); + m_toggle_details->SetTextColor(btn_text_white); + m_toggle_details->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + m_details_expanded = !m_details_expanded; + m_script_text->Show(m_details_expanded); + m_toggle_details->SetLabel(m_details_expanded ? (_L("Collapse") + " \u2227") : (_L("View details") + " \u2228")); + Layout(); + Fit(); + }); + content_sizer->Add(m_toggle_details, 0, wxBOTTOM, FromDIP(4)); + + add_button(wxID_YES, false, _L("Execute")); + add_button(wxID_NO, true, _L("Do not execute")); + if (Button* execute_btn = get_button(wxID_YES)) { + execute_btn->SetBorderColor(WXCOLOUR_GREY500); + execute_btn->SetTextColor(WXCOLOUR_GREY700); + } + SetMaxSize(MSG_DLG_MAX_SIZE); + finalize(); + CallAfter([this]() { + Layout(); + Fit(); + CenterOnParent(); + }); +} + #if 1 // MessageDialog diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index 9b848e2c60..dc6fd3f363 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -131,6 +131,22 @@ class WarningDialog : public MsgDialog virtual ~WarningDialog() = default; }; +// Post-processing script confirmation before slicing (3MF with post_process scripts) +class PostProcessScriptDialog : public MsgDialog +{ + ::wxTextCtrl* m_script_text{ nullptr }; + Button* m_toggle_details{ nullptr }; + bool m_details_expanded{ false }; + +public: + PostProcessScriptDialog(wxWindow* parent, const wxString& message, const wxString& script_content); + PostProcessScriptDialog(PostProcessScriptDialog&&) = delete; + PostProcessScriptDialog(const PostProcessScriptDialog&) = delete; + PostProcessScriptDialog& operator=(PostProcessScriptDialog&&) = delete; + PostProcessScriptDialog& operator=(const PostProcessScriptDialog&) = delete; + ~PostProcessScriptDialog() override = default; +}; + #if 1 // Generic static line, used intead of wxStaticLine //class StaticLine: public wxTextCtrl diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 6030f4e527..ea3094bd2e 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1136,8 +1136,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config else if (opt->gui_flags == "serialized") { std::vector values = config.option(opt_key2)->values; if (!values.empty() && !values[0].empty()) - for (auto el : values) - text_value += el + ";"; + for (const auto& el : values) + text_value += from_u8(el) + ";"; ret = text_value; } else diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c9f7ee461f..6c29a29d38 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -66,6 +66,7 @@ #include "libslic3r/Print.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/FilamentMixer.hpp" +#include "libslic3r/LocalesUtils.hpp" #include "libslic3r/SLAPrint.hpp" #include "MixedFilamentDialog.hpp" #include "libslic3r/Utils.hpp" @@ -2154,30 +2155,6 @@ void Sidebar::priv::update_sync_status(const MachineObject *obj) fila_switch_warning_shown = false; } - std::map, int> ams_cnt_map{ - {{MAIN_EXTRUDER_ID, 1}, 0}, - {{DEPUTY_EXTRUDER_ID, 1}, 0}, - {{MAIN_EXTRUDER_ID, 4}, 0}, - {{DEPUTY_EXTRUDER_ID, 4}, 0}, - }; - for (const auto &ams : obj->GetFilaSystem()->GetAmsList()) { - for (auto extruder_id : ams.second->GetBindedExtruderSet()) { - if (is_fila_switch_ready()) { - auto switcher_pos = ams.second->GetSwitcherPos(); - if (!switcher_pos) { continue; } - auto switcher_id = obj->is_main_extruder_on_left() ? (1 - static_cast(switcher_pos.value())) : static_cast(switcher_pos.value()); - if (extruder_id != switcher_id) { continue; } - } - std::pair key = {extruder_id, ams.second->GetAmsType() == DevAmsType::N3S ? 1 : 4}; - ams_cnt_map[key]++; - } - } - int main_index = obj->is_main_extruder_on_left() ? 0 : 1; - int deputy_index = obj->is_main_extruder_on_left() ? 1 : 0; - AMSCountPopupWindow::SetAMSCount(deputy_index, ams_cnt_map[{DEPUTY_EXTRUDER_ID, 4}], ams_cnt_map[{DEPUTY_EXTRUDER_ID, 1}], false); - AMSCountPopupWindow::SetAMSCount(main_index, ams_cnt_map[{MAIN_EXTRUDER_ID, 4}], ams_cnt_map[{MAIN_EXTRUDER_ID, 1}], false); - AMSCountPopupWindow::UpdateAMSCount(0, left_extruder); - AMSCountPopupWindow::UpdateAMSCount(1, right_extruder); } //std::vector extruder_infos(extruder_nums); @@ -3027,7 +3004,8 @@ Sidebar::Sidebar(Plater *parent) if (!indices.empty()) delete_mixed_filament_at(indices.size() - 1); }); - title_sizer->Add(p->m_btn_mixed_del, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(16)); + title_sizer->Add(p->m_btn_mixed_del, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(12)); + title_sizer->Add(FromDIP(16), 0, 0, 0, 0); p->m_panel_mixed_title->SetSizer(title_sizer); wrapper_sizer->Add(p->m_panel_mixed_title, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(8)); @@ -4984,6 +4962,17 @@ void Sidebar::recalc_filament_scroll_sizes() recalc(p->m_mixed_scroll_area); } +static std::string blend_mixed_color(const std::vector &comp_ids, + const std::vector &ratios, + const std::vector &color_strs) +{ + std::vector hex_colors; + hex_colors.reserve(comp_ids.size()); + for (unsigned int id : comp_ids) + hex_colors.push_back((id >= 1 && id <= color_strs.size()) ? color_strs[id - 1] : "#808080"); + return Slic3r::blend_color_multi(hex_colors, ratios); +} + void Sidebar::update_mixed_filament_list() { auto* plater = dynamic_cast(GetParent()); @@ -5122,6 +5111,7 @@ void Sidebar::update_mixed_filament_list() } } if (ratios_opt && cfg_idx < ratios_opt->values.size()) { + CNumericLocalesSetter c_locale_setter; std::istringstream iss(ratios_opt->values[cfg_idx]); std::string tok; while (std::getline(iss, tok, ',')) { @@ -5130,24 +5120,21 @@ void Sidebar::update_mixed_filament_list() comp_ratios.push_back((int)(v * 100 + 0.5f)); } } + if (!comp_ids.empty() && comp_ratios.size() != comp_ids.size()) { + BOOST_LOG_TRIVIAL(warning) << "Mixed filament slot " << cfg_idx + << ": ratio count (" << comp_ratios.size() + << ") != component count (" << comp_ids.size() + << "), resetting to even distribution"; + int n = (int)comp_ids.size(); + comp_ratios.assign(n, 100 / n); + comp_ratios[0] += 100 - (100 / n) * n; + } bool is_broken = broken_set.count(cfg_idx) > 0; // Recalculate mixed color based on current physical colors if (!is_broken && !comp_ids.empty() && comp_ids.size() == comp_ratios.size()) { - int ratio_sum = 0; - for (int r : comp_ratios) ratio_sum += r; - if (ratio_sum <= 0) ratio_sum = 100; - - double mr = 0, mg = 0, mb = 0; - for (size_t j = 0; j < comp_ids.size(); ++j) { - double w = (double)comp_ratios[j] / ratio_sum; - std::string cs = (comp_ids[j] >= 1 && comp_ids[j] <= physical_colors.size()) - ? physical_colors[comp_ids[j] - 1] : "#808080"; - wxColour c(cs); - mr += c.Red() * w; mg += c.Green() * w; mb += c.Blue() * w; - } - std::string new_mixed_color = wxColour((unsigned char)mr, (unsigned char)mg, (unsigned char)mb).GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); + std::string new_mixed_color = blend_mixed_color(comp_ids, comp_ratios, physical_colors); if (colours_opt && cfg_idx < colours_opt->values.size() && colours_opt->values[cfg_idx] != new_mixed_color) { colours_opt->values[cfg_idx] = new_mixed_color; @@ -5164,6 +5151,7 @@ void Sidebar::update_mixed_filament_list() if (grad_opt && cfg_idx < grad_opt->values.size()) is_gradient = grad_opt->values[cfg_idx]; if (is_gradient && grad_range_opt && cfg_idx < grad_range_opt->values.size()) { + CNumericLocalesSetter c_locale_setter; float v0 = 0, v1 = 0; if (std::sscanf(grad_range_opt->values[cfg_idx].c_str(), "%f,%f", &v0, &v1) == 2) gradient_direction = (v0 > v1) ? 0 : 1; @@ -5654,22 +5642,7 @@ void Sidebar::add_mixed_filament() size_t new_idx = total; // Compute blended color from all components - int ratio_sum = 0; - for (int r : result.ratios) ratio_sum += r; - if (ratio_sum <= 0) ratio_sum = 100; - - std::string mixed_color = "#808080"; - { - double mr = 0, mg = 0, mb = 0; - for (size_t i = 0; i < result.components.size(); ++i) { - double w = (double)result.ratios[i] / ratio_sum; - std::string cs = (result.components[i] >= 1 && result.components[i] <= color_strs.size()) - ? color_strs[result.components[i] - 1] : "#808080"; - wxColour c(cs); - mr += c.Red() * w; mg += c.Green() * w; mb += c.Blue() * w; - } - mixed_color = wxColour((unsigned char)mr, (unsigned char)mg, (unsigned char)mb).GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); - } + std::string mixed_color = blend_mixed_color(result.components, result.ratios, color_strs); wxGetApp().preset_bundle->set_num_filaments(total + 1, mixed_color); @@ -5691,12 +5664,19 @@ void Sidebar::add_mixed_filament() project_config.option("filament_mixed_components")->values[new_idx] = comp_str; // Serialize ratios as normalized floats: "0.5000,0.5000" or "0.3000,0.3000,0.4000" + int ratio_sum = 0; + for (int r : result.ratios) ratio_sum += r; + if (ratio_sum <= 0) ratio_sum = 100; + std::string ratio_str; - for (size_t i = 0; i < result.ratios.size(); ++i) { - if (i > 0) ratio_str += ","; - char buf[32]; - std::snprintf(buf, sizeof(buf), "%.4f", (float)result.ratios[i] / ratio_sum); - ratio_str += buf; + { + CNumericLocalesSetter c_locale_setter; + for (size_t i = 0; i < result.ratios.size(); ++i) { + if (i > 0) ratio_str += ","; + char buf[32]; + std::snprintf(buf, sizeof(buf), "%.4f", (float)result.ratios[i] / ratio_sum); + ratio_str += buf; + } } project_config.option("filament_mixed_sublayer_ratios")->values[new_idx] = ratio_str; @@ -5766,6 +5746,7 @@ void Sidebar::edit_mixed_filament(size_t panel_idx) } // Parse existing ratios if (ratios_opt && cfg_idx < ratios_opt->values.size()) { + CNumericLocalesSetter c_locale_setter; const std::string& rs = ratios_opt->values[cfg_idx]; std::istringstream iss(rs); std::string tok; @@ -5778,6 +5759,14 @@ void Sidebar::edit_mixed_filament(size_t panel_idx) if (existing.components.size() < 2) { existing.components = {1, 2}; existing.ratios = {50, 50}; + } else if (existing.ratios.size() != existing.components.size()) { + BOOST_LOG_TRIVIAL(warning) << "Mixed filament edit: ratio count (" + << existing.ratios.size() << ") != component count (" + << existing.components.size() + << "), resetting to even distribution"; + int n = (int)existing.components.size(); + existing.ratios.assign(n, 100 / n); + existing.ratios[0] += 100 - (100 / n) * n; } // Read gradient settings @@ -5786,6 +5775,7 @@ void Sidebar::edit_mixed_filament(size_t panel_idx) existing.gradient_enabled = grad_opt->values[cfg_idx]; auto* grad_range_opt = project_config.option("filament_mixed_gradient_range"); if (existing.gradient_enabled && grad_range_opt && cfg_idx < grad_range_opt->values.size()) { + CNumericLocalesSetter c_locale_setter; float v0 = 0, v1 = 0; if (std::sscanf(grad_range_opt->values[cfg_idx].c_str(), "%f,%f", &v0, &v1) == 2) existing.gradient_direction = (v0 > v1) ? 0 : 1; @@ -5810,11 +5800,14 @@ void Sidebar::edit_mixed_filament(size_t panel_idx) if (ratio_sum <= 0) ratio_sum = 100; std::string ratio_str; - for (size_t i = 0; i < result.ratios.size(); ++i) { - if (i > 0) ratio_str += ","; - char buf[32]; - std::snprintf(buf, sizeof(buf), "%.4f", (float)result.ratios[i] / ratio_sum); - ratio_str += buf; + { + CNumericLocalesSetter c_locale_setter; + for (size_t i = 0; i < result.ratios.size(); ++i) { + if (i > 0) ratio_str += ","; + char buf[32]; + std::snprintf(buf, sizeof(buf), "%.4f", (float)result.ratios[i] / ratio_sum); + ratio_str += buf; + } } ratios_opt->values[cfg_idx] = ratio_str; @@ -5841,16 +5834,7 @@ void Sidebar::edit_mixed_filament(size_t panel_idx) } // Compute blended color - double mr = 0, mg = 0, mb = 0; - for (size_t i = 0; i < result.components.size(); ++i) { - double w = (double)result.ratios[i] / ratio_sum; - std::string cs = (result.components[i] >= 1 && result.components[i] <= color_strs.size()) - ? color_strs[result.components[i] - 1] : "#808080"; - wxColour c(cs); - mr += c.Red() * w; mg += c.Green() * w; mb += c.Blue() * w; - } - std::string blended = wxColour((unsigned char)mr, (unsigned char)mg, (unsigned char)mb) - .GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); + std::string blended = blend_mixed_color(result.components, result.ratios, color_strs); auto* colours_opt = project_config.option("filament_colour"); if (colours_opt && cfg_idx < colours_opt->values.size()) colours_opt->values[cfg_idx] = blended; @@ -6202,6 +6186,10 @@ struct Plater::priv int m_cur_slice_plate; //BBS: m_slice_all in .gcode.3mf file case, set true when slice all bool m_slice_all_only_has_gcode{ false }; + // Whcih means "In this slicing session, the popup has already asked the user once". + bool m_post_process_script_prompt_consumed{ false }; + // Which means "This moment is during the popup display period". + bool m_inside_post_process_script_modal{ false }; bool m_need_update{false}; //BBS: add popup object table logic @@ -7416,28 +7404,6 @@ void Plater::priv::select_view(const std::string& direction) } } -bool Plater::check_include_gcode() -{ - PresetBundle& preset_bundle = *wxGetApp().preset_bundle; - const DynamicPrintConfig& config = preset_bundle.prints.get_edited_preset().config; - - if (config.has("post_process")) { - auto* opt = config.opt("post_process"); - if (opt && !opt->values.empty()) { - std::string first_script = opt->values.front(); - std::string all_scripts = boost::algorithm::join(opt->values, "; "); - if (!first_script.empty()) { - MessageDialog msg(wxGetApp().mainframe, _L("There is a G-code script present in the current 3mf file, please verify the content of the script."), _L("Warning"), wxOK | wxICON_WARNING); - if (msg.ShowModal() == wxID_OK) { - wxGetApp().sidebar().jump_to_option("post_process", Preset::TYPE_PRINT, L""); - } - return true; - } - } - } - return false; -} - const VendorProfile::PrinterModel *Plater::get_curr_printer_model() { auto bundle = wxGetApp().preset_bundle; @@ -8575,7 +8541,14 @@ std::vector Plater::priv::load_files(const std::vector& input_ } is_user_cancel = true; return -1; - }, linear, angle, split_compound); + }, linear, angle, split_compound, + [](const std::vector& names) { + wxString msg = _L("The following shells are not closed and may cause issues:") + "\n\n"; + for (const auto& name : names) { + msg += wxString::FromUTF8(name) + "\n"; + } + Slic3r::GUI::show_info(nullptr, msg, _L("Unclosed Shell Warning")); + }); }else { if (boost::algorithm::iends_with(path.string(), ".obj")) { is_xxx = GUI::wxGetApp().app_config->get_bool("gamma_correct_in_import_obj"); @@ -10234,7 +10207,14 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const return 1; } return -1; - }, linear, angle, split_compound); + }, linear, angle, split_compound, + [](const std::vector& names) { + wxString msg = _L("The following shells are not closed and may cause issues:") + "\n\n"; + for (const auto& name : names) { + msg += wxString::FromUTF8(name) + "\n"; + } + Slic3r::GUI::show_info(nullptr, msg, _L("Unclosed Shell Warning")); + }); }else { new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel); } @@ -11524,6 +11504,13 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": ignore this event %1%") % evt.status(); return; } + // Allow the post-process script prompt to appear again on the next slicing session. + // Guard: never reset while a PostProcessScriptDialog is open (a nested event loop could + // dispatch a stale EVT_PROCESS_COMPLETED here and break the "prompt once per session" guarantee). + // m_inside_post_process_script_modal is intentionally NOT touched here; it is owned exclusively + // by reslice() around its ShowModal() call. + if (!m_inside_post_process_script_modal) + m_post_process_script_prompt_consumed = false; //BBS: add project slice logic bool is_finished = !m_slice_all || (m_cur_slice_plate == (partplate_list.get_plate_count() - 1)); @@ -16438,6 +16425,9 @@ void Plater::reset_flags_when_new_or_close_project() m_only_gcode = false; m_exported_file = false; m_loading_project = false; + p->background_process.set_skip_post_process_once(false); + p->m_post_process_script_prompt_consumed = false; + p->m_inside_post_process_script_modal = false; } int Plater::new_project(bool skip_confirm, bool silent, const wxString &project_name) @@ -16668,8 +16658,6 @@ int Plater::load_project(wxString const &filename2, std::vector res = load_files(input_paths, strategy); - check_include_gcode(); - reset_project_dirty_initial_presets(); update_project_dirty_from_presets(); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); @@ -16804,7 +16792,7 @@ void Plater::import_model_id(wxString download_info) size_t namePos = download_info.Find(separator); if (namePos != wxString::npos) { download_url = download_info.Mid(0, namePos); - filename = download_info.Mid(namePos + separator.Length()); + filename = fs::path(download_info.Mid(namePos + separator.Length()).wc_str()).filename().wstring(); } else { @@ -17037,7 +17025,7 @@ void Plater::import_model_id(wxString download_info) // Atomic rename operation BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Renaming temp file to target: " << PathSanitizer::sanitize(tmp_path) << " -> " << PathSanitizer::sanitize(target_path); fs::rename(tmp_path, target_path); - + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " File renamed successfully: " << PathSanitizer::sanitize(target_path); cont = false; download_ok = true; @@ -17046,7 +17034,7 @@ void Plater::import_model_id(wxString download_info) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Exception during file operations: " << e.what(); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Temp path: " << PathSanitizer::sanitize(tmp_path); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Target path: " << PathSanitizer::sanitize(target_path); - + // Clean up temp file try { if (fs::exists(tmp_path)) { @@ -17057,7 +17045,7 @@ void Plater::import_model_id(wxString download_info) catch (const std::exception& cleanup_error) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Failed to clean up temp file: " << cleanup_error.what(); } - + cont = false; download_ok = false; } @@ -20307,10 +20295,49 @@ bool Plater::is_multi_extruder_ams_empty() return true; } +namespace { +bool plater_has_nonempty_post_process_scripts(const PresetBundle& preset_bundle) +{ + const DynamicPrintConfig& config = preset_bundle.prints.get_edited_preset().config; + if (!config.has("post_process")) + return false; + const auto* opt = config.opt("post_process"); + if (!opt || opt->values.empty()) + return false; + for (const std::string& v : opt->values) { + std::string t = v; + boost::trim(t); + if (!t.empty()) + return true; + } + return false; +} + +wxString plater_post_process_scripts_field_text(const PresetBundle& preset_bundle) +{ + const DynamicPrintConfig& config = preset_bundle.prints.get_edited_preset().config; + if (!config.has("post_process")) + return wxEmptyString; + const auto* opt = config.opt("post_process"); + if (!opt) + return wxEmptyString; + std::string joined; + for (const std::string& v : opt->values) { + if (!joined.empty()) + joined += '\n'; + joined += v; + } + return from_u8(joined); +} +} // namespace + //BBS: add multiple plate reslice logic void Plater::reslice() { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: enter, process_completed_with_error=%2%")%__LINE__ %p->process_completed_with_error; + // Nested wx event dispatch during PostProcessScriptDialog::ShowModal() can re-enter reslice(); ignore the inner call. + if (p->m_inside_post_process_script_modal) + return; // There is "invalid data" button instead "slice now" if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) { @@ -20329,21 +20356,63 @@ void Plater::reslice() if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) return; + if (printer_technology() == ptFFF && !only_gcode_mode() && !is_gcode_3mf() && + plater_has_nonempty_post_process_scripts(*wxGetApp().preset_bundle) && + !p->m_post_process_script_prompt_consumed) { + // Set before ShowModal: nested event loop may dispatch another reslice() before we return. + p->m_post_process_script_prompt_consumed = true; + p->m_inside_post_process_script_modal = true; + PostProcessScriptDialog dlg(wxGetApp().mainframe, + _L("Security Warning: This 3MF file contains post-processing script commands that will run automatically during slicing and may pose security risks!\nPlease verify the file source and script contents before continuing."), + plater_post_process_scripts_field_text(*wxGetApp().preset_bundle)); + const int result = dlg.ShowModal(); + p->m_inside_post_process_script_modal = false; + // ESC / close [X] / any non-explicit choice: cancel this slice entirely and allow re-prompting on next reslice(). + if (result != wxID_YES && result != wxID_NO) { + p->m_post_process_script_prompt_consumed = false; + p->background_process.set_skip_post_process_once(false); + return; + } + p->background_process.set_skip_post_process_once(result == wxID_NO); + } + // Stop arrange and (or) optimize rotation tasks. this->stop_jobs(); // softfever: regenerate CalibPressureAdvancePattern custom G-code to apply changes if (model().calib_pa_pattern) { PresetBundle* preset_bundle = wxGetApp().preset_bundle; - DynamicPrintConfig calib_config = preset_bundle->full_config(); + std::optional> override_filament_maps; auto *fff_print_ptr = p->background_process.fff_print(); if (fff_print_ptr) { const auto &calib = fff_print_ptr->calib_params(); if (calib.has_bowden_extruder) { - auto *opt = calib_config.option("filament_map"); - if (opt && !opt->values.empty()) - opt->values[0] = calib.extruder_id + 1; + std::vector fmap; + if (auto *opt = preset_bundle->project_config.option("filament_map")) + fmap = opt->values; + if (fmap.empty()) + fmap.resize(1, 1); + std::fill(fmap.begin(), fmap.end(), calib.extruder_id + 1); + override_filament_maps = std::move(fmap); + } + } + + DynamicPrintConfig calib_config = preset_bundle->full_config(true, override_filament_maps); + + { + auto *filament_map_opt = calib_config.option("filament_map"); + if (filament_map_opt && !filament_map_opt->values.empty()) { + std::vector filament_map_indices(filament_map_opt->values.size(), 0); + for (size_t i = 0; i < filament_map_opt->values.size(); ++i) + filament_map_indices[i] = filament_map_opt->values[i] - 1; + const std::string filament_prefix = "filament_"; + for (const auto &key : print_config_def.extruder_retract_keys()) { + ConfigOption *machine_opt = calib_config.option(key); + ConfigOption *filament_opt = calib_config.option(filament_prefix + key); + if (machine_opt && filament_opt && machine_opt->is_vector() && filament_opt->is_vector()) + machine_opt->apply_override(filament_opt, filament_map_indices); + } } } @@ -20421,6 +20490,9 @@ void Plater::reslice() { //BBS: add logs BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": state %1% is UPDATE_BACKGROUND_PROCESS_INVALID, can not slice") % state; + // Slicing never started: roll back the skip flag and allow the prompt to reappear on the next reslice(). + p->background_process.set_skip_post_process_once(false); + p->m_post_process_script_prompt_consumed = false; p->update_fff_scene_only_shells(); return; } @@ -20795,7 +20867,7 @@ int Plater::export_config_3mf(int plate_idx, Export3mfProgressFn proFn) //BBS void Plater::send_calibration_job_finished(wxCommandEvent & evt) { - p->main_frame->request_select_tab(MainFrame::TabPosition::tpCalibration); + p->main_frame->select_tab(p->main_frame->m_calibration); auto calibration_panel = p->main_frame->m_calibration; if (calibration_panel) { auto curr_wizard = static_cast(calibration_panel->get_tabpanel()->GetPage(evt.GetInt())); @@ -21431,6 +21503,7 @@ std::vector parse_mixed_gradient_slots(const Slic3r::DynamicP int direction = 0; if (grad_range && i < grad_range->values.size()) { + CNumericLocalesSetter c_locale_setter; float v0 = 0, v1 = 0; if (std::sscanf(grad_range->values[i].c_str(), "%f,%f", &v0, &v1) == 2) direction = (v0 > v1) ? 0 : 1; @@ -22061,35 +22134,70 @@ void Plater::clone_selection() selection.clone(res); } -std::vector Plater::get_empty_cells(const Vec2f step) +std::vector Plater::get_empty_cells(const Vec2f step, const BoundingBoxf& safe_area_2d) { PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); - BoundingBoxf3 build_volume = plate->get_build_volume(true); - Vec2d vmin(build_volume.min.x(), build_volume.min.y()), vmax(build_volume.max.x(), build_volume.max.y()); - BoundingBoxf bbox(vmin, vmax); + + // 优先使用调用方传入的"安全可放置区域"(已按 bed_shrink + brim_skirt_distance/2 收缩), + // 与 NFP 路径行为对齐;未提供时回落到原 build_volume(true)(仅含微小 SceneEpsilon)。 + BoundingBoxf bbox; + if (safe_area_2d.defined) { + bbox = safe_area_2d; + } else { + BoundingBoxf3 build_volume = plate->get_build_volume(true); + bbox = BoundingBoxf(Vec2d(build_volume.min.x(), build_volume.min.y()), + Vec2d(build_volume.max.x(), build_volume.max.y())); + } + std::vector cells; - auto min_x = step(0)/2;// start_point.x() - step(0) * int((start_point.x() - bbox.min.x()) / step(0)); - auto min_y = step(1)/2;// start_point.y() - step(1) * int((start_point.y() - bbox.min.y()) / step(1)); + if (step(0) <= 0.f || step(1) <= 0.f) + return cells; + + const double width = bbox.max.x() - bbox.min.x(); + const double height = bbox.max.y() - bbox.min.y(); + if (width < step(0) || height < step(1)) + return cells; + + // STUDIO: 把整除剩余的"边缘余量"对称分摊到两侧,避免最左/最下那一列死贴床边、 + // 而最右/最上却空一大条的现象。floor 使每行/列至少容下一个完整 cell;上面已经 + // 提前 return 保证 width >= step(0) && height >= step(1),所以 cols/rows >= 1。 + // NOTE: 网格起点改为居中,调用方(如 FillBedJob)的可视化布局会与旧版本不同, + // 但仍然完整落在 bbox 内,且左右/上下对称。 + const int cols = int(std::floor(width / step(0))); + const int rows = int(std::floor(height / step(1))); + const double half_x = step(0) / 2.0; + const double half_y = step(1) / 2.0; + const double pad_x = (width - cols * step(0)) / 2.0; + const double pad_y = (height - rows * step(1)) / 2.0; + const double start_x = bbox.min.x() + pad_x + half_x; + const double start_y = bbox.min.y() + pad_y + half_y; + auto& exclude_box3s = plate->get_exclude_areas(); std::vector exclude_boxs; + exclude_boxs.reserve(exclude_box3s.size()); for (auto& box : exclude_box3s) { - Vec2d vmin(box.min.x(), box.min.y()), vmax(box.max.x(), box.max.y()); - exclude_boxs.emplace_back(vmin, vmax); + exclude_boxs.emplace_back(Vec2d(box.min.x(), box.min.y()), Vec2d(box.max.x(), box.max.y())); } - for (float x = min_x + bbox.min.x(); x < bbox.max.x() - step(0) / 2; x += step(0)) - for (float y = min_y + bbox.min.y(); y < bbox.max.y() - step(1) / 2; y += step(1)) { + + cells.reserve(size_t(cols) * size_t(rows)); + for (int i = 0; i < cols; ++i) { + const double x = start_x + i * step(0); + for (int j = 0; j < rows; ++j) { + const double y = start_y + j * step(1); + BoundingBoxf cell(Vec2d(x - half_x, y - half_y), + Vec2d(x + half_x, y + half_y)); bool in_exclude = false; - BoundingBoxf cell(Vec2d(x - step(0) / 2, y - step(1) / 2), Vec2d(x + step(0) / 2, y + step(1) / 2)); for (auto& box : exclude_boxs) { if (box.overlap(cell)) { in_exclude = true; break; } } - if(in_exclude) + if (in_exclude) continue; - cells.emplace_back(x, y); + cells.emplace_back(float(x), float(y)); } + } return cells; } @@ -22549,6 +22657,17 @@ void Plater::open_platesettings_dialog(wxCommandEvent& evt) { else curr_plate->set_print_seq(PrintSequence::ByDefault); + PrintSequence actual_seq = curr_plate->get_real_print_seq(); + if (actual_seq == PrintSequence::ByObject) { + const DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + if (print_config.opt_int("skirt_height") > 1 && print_config.opt_int("skirt_loops") > 0) { + MessageDialog warn_dlg(this, + _(L("While printing by Object, the extruder may collide skirt.\nThus, it is recommended to reset the skirt layer to 1 to avoid that.")), + "", wxICON_WARNING | wxOK); + warn_dlg.ShowModal(); + } + } + int spiral_sel = dlg.get_spiral_mode_choice(); if (spiral_sel == 1) { curr_plate->set_spiral_vase_mode(true, false); @@ -22635,11 +22754,11 @@ void Plater::open_filament_map_setting_dialog(wxCommandEvent &evt) old_filament_volume_maps != new_filament_volume_maps); if (need_invalidate) { - if (need_slice) { + wxString filament_printable_error_msg; + if (need_slice && curr_plate->check_filament_printable(wxGetApp().preset_bundle->full_config(), filament_printable_error_msg)) { update(false, true); wxPostEvent(this, SimpleEvent(EVT_GLTOOLBAR_SLICE_PLATE)); - } - else { + } else { curr_plate->update_slice_result_valid_state(false); set_plater_dirty(true); update(false, true); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 3faa9ac606..72537b9b5f 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -356,7 +356,6 @@ class Plater: public wxPanel void request_download_project(std::string project_id); // BBS: check snapshot bool up_to_date(bool saved, bool backup); - bool check_include_gcode(); bool open_3mf_file(const fs::path &file_path); int get_3mf_file_count(std::vector paths); @@ -696,7 +695,13 @@ class Plater: public wxPanel void split_volume(); void optimize_rotation(); // find all empty cells on the plate and won't overlap with exclusion areas - static std::vector get_empty_cells(const Vec2f step); + // safe_area_2d: 可选的可放置区域包围盒(毫米,世界坐标)。defined() 时优先使用, + // 典型由 `get_shrink_bedpts` 收缩后的 m_bedpts 传入,使网格路径与 + // NFP 路径在 bed_shrink/brim_skirt_distance 上保持一致;未提供时 + // 回落到 plate->get_build_volume(true)(旧行为)。 + // 网格无论使用哪个区域,都会按 step 在区域内居中,把整除剩余的空间均匀分到两端, + // 避免边缘对象贴床边导致 brim/skirt 越出。 + static std::vector get_empty_cells(const Vec2f step, const BoundingBoxf& safe_area_2d = BoundingBoxf()); //BBS: void fill_color(int extruder_id); diff --git a/src/slic3r/GUI/PrePrintChecker.cpp b/src/slic3r/GUI/PrePrintChecker.cpp index 57b4035161..441dd93a98 100644 --- a/src/slic3r/GUI/PrePrintChecker.cpp +++ b/src/slic3r/GUI/PrePrintChecker.cpp @@ -116,8 +116,8 @@ wxString PrePrintChecker::get_pre_state_msg(PrintDialogStatus status) "If 'Dynamic Flow Calibration' is set to auto/on, the system will use the previous calibration value and skip the flow calibration process."); case PrintStatusWarningKvalueNotUsed: return _L("Set dynamic flow calibration to 'OFF' to enable custom dynamic flow value."); case PrintStatusNotSupportedPrintAll: return _L("This printer does not support printing all plates"); - case PrintStatusColorQuantityExceed: return _L("The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support."); case PrintStatusHasUnreliableNozzleWarning: return _L("Please check if the required nozzle diameter and flow rate match the current display."); + case PrintStatusColorQuantityExceed: return _L("The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support."); } return wxEmptyString; } diff --git a/src/slic3r/GUI/PrinterWebView.cpp b/src/slic3r/GUI/PrinterWebView.cpp index 8065015453..91b4a056e3 100644 --- a/src/slic3r/GUI/PrinterWebView.cpp +++ b/src/slic3r/GUI/PrinterWebView.cpp @@ -63,7 +63,7 @@ PrinterWebView::~PrinterWebView() } -void PrinterWebView::load_url(wxString& url) +void PrinterWebView::load_url(const wxString& url) { // this->Show(); // this->Raise(); diff --git a/src/slic3r/GUI/PrinterWebView.hpp b/src/slic3r/GUI/PrinterWebView.hpp index bdf5f4c68f..da0c4666f7 100644 --- a/src/slic3r/GUI/PrinterWebView.hpp +++ b/src/slic3r/GUI/PrinterWebView.hpp @@ -35,7 +35,8 @@ class PrinterWebView : public wxPanel { PrinterWebView(wxWindow *parent); virtual ~PrinterWebView(); - void load_url(wxString& url); + void load_url(const wxString& url); + wxWebView* GetWebView() const { return m_browser; } void UpdateState(); void OnClose(wxCloseEvent& evt); void OnError(wxWebViewEvent& evt); diff --git a/src/slic3r/GUI/Project.cpp b/src/slic3r/GUI/Project.cpp index c743c94768..04a7600b32 100644 --- a/src/slic3r/GUI/Project.cpp +++ b/src/slic3r/GUI/Project.cpp @@ -302,11 +302,81 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt) wxString accessory_path = j["accessory_path"]; if (!accessory_path.empty()) { + // Restrict open requests to files under the current auxiliary root. + auto is_sub_path = [](const fs::path& child, const fs::path& root) { + auto child_it = child.begin(); + auto root_it = root.begin(); + for (; root_it != root.end(); ++root_it, ++child_it) { + if (child_it == child.end() || *child_it != *root_it) + return false; + } + return true; + }; + auto json_array_or_empty = [](const json& parent, const char* key) -> json { + if (parent.is_object() && parent.contains(key) && parent[key].is_array()) + return parent[key]; + return json::array(); + }; + + // Keep runtime-openable types aligned with current accessory UI support. + static const std::set s_allowed_extensions = { + ".txt", ".pdf", ".fdf", ".xfdf", ".xdp", ".ppdf", ".ofd", + ".xls", ".xlsx", ".xlsm", ".xlsb", ".csv", ".xltx", ".xltm", + ".xlt", ".xlam", ".xla", + ".jpg", ".jpeg", ".pjpeg", ".png", ".jfif", ".pjp", + ".webp", ".bmp" + }; + std::string decode_path = wxGetApp().url_decode(accessory_path.ToStdString()); - fs::path path(decode_path); + fs::path requested_path(decode_path); + + // Only consider real files while we still have the current project context. + if (fs::exists(requested_path) && fs::is_regular_file(requested_path) && !m_last_payload.empty() && !m_root_dir.empty()) { + fs::path canonical_path = fs::canonical(requested_path); + fs::path canonical_root = fs::canonical(fs::path(m_root_dir.ToStdWstring())); + + std::string extension = canonical_path.extension().string(); + boost::algorithm::to_lower(extension); + + bool is_known_accessory = false; + // Reject paths outside the project root or outside the allowed attachment types. + if (is_sub_path(canonical_path, canonical_root) && s_allowed_extensions.count(extension) > 0) { + const json& model_section = m_last_payload.contains("model") ? m_last_payload["model"] : json::object(); + const json& file_section = (model_section.is_object() && model_section.contains("file")) ? model_section["file"] : json::object(); + + // Only files already published to the current page payload may be opened. + for (const char* key : {"BOM", "Assembly", "Other"}) { + for (const auto& entry : json_array_or_empty(file_section, key)) { + if (!entry.is_object() || !entry.contains("filepath") || !entry["filepath"].is_string()) + continue; + + std::string stored_path = entry["filepath"].get(); + if (stored_path.empty() || boost::starts_with(stored_path, "data:")) + continue; + + fs::path allowed_path(wxGetApp().url_decode(stored_path)); + if (!fs::exists(allowed_path) || !fs::is_regular_file(allowed_path)) + continue; + + fs::path canonical_allowed_path = fs::canonical(allowed_path); + if (!is_sub_path(canonical_allowed_path, canonical_root)) + continue; + + if (canonical_allowed_path == canonical_path) { + is_known_accessory = true; + break; + } + } - if (fs::exists(path)) { - wxLaunchDefaultApplication(path.wstring(), 0); + if (is_known_accessory) + break; + } + } + + // Hand the file to the OS only after all project-scoped checks pass. + if (is_known_accessory) { + wxLaunchDefaultApplication(canonical_path.wstring(), 0); + } } } } @@ -776,7 +846,6 @@ std::map> ProjectPanel::Reload(wxString aux_path) { std::vector dir_cache; fs::directory_iterator iter_end; - wxString m_root_dir; std::map> m_paths_list; const static std::array s_default_folders = { @@ -793,12 +862,16 @@ std::map> ProjectPanel::Reload(wxString aux_path) fs::path new_aux_path(aux_path.ToStdWstring()); + fs::path old_aux_path(m_root_dir.ToStdWstring()); - try { - fs::remove_all(fs::path(m_root_dir.ToStdWstring())); - } - catch (...) { - BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory" << m_root_dir.c_str(); + // Only clear the previous auxiliary root when switching to a different project path. + if (!m_root_dir.empty() && old_aux_path.lexically_normal() != new_aux_path.lexically_normal()) { + try { + fs::remove_all(old_aux_path); + } + catch (...) { + BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory" << m_root_dir.c_str(); + } } m_root_dir = aux_path; diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 783987aeff..f9fa984d51 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -1752,6 +1752,10 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector 0) { + msg = wxString::Format(_L("The current firmware supports a maximum of %s materials. You can either reduce the number of materials to %s or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support."), + params[0], params[0]); + } Enable_Refresh_Button(true); Enable_Send_Button(false); } @@ -2803,6 +2807,15 @@ void SelectMachineDialog::load_option_vals(MachineObject *obj) } } + if (obj->is_multi_extruders()) { + auto used_nozzle_idxes = _get_used_nozzle_idxes(); + if (used_nozzle_idxes.size() == 1) { + m_checkbox_list["nozzle_offset_cali"]->setValue("off"); + } else if (used_nozzle_idxes.size() >= 2) { + m_checkbox_list["nozzle_offset_cali"]->setValue("auto"); + } + } + update_option_dynamic_state(obj); } @@ -3965,10 +3978,11 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) show_status(PrintDialogStatus::PrintStatusNoSdcard); return; } - if (wxGetApp().preset_bundle->filament_presets.size() > 16 && m_print_type != PrintFromType::FROM_SDCARD_VIEW) { - if (!obj_->is_enable_ams_np && !obj_->is_enable_np) - { - show_status(PrintDialogStatus::PrintStatusColorQuantityExceed); + if (m_print_type != PrintFromType::FROM_SDCARD_VIEW) { + const int max_color = obj_->get_max_filament_color_count(); + const size_t fila_cnt = wxGetApp().preset_bundle->filament_presets.size(); + if (max_color > 0 && fila_cnt > (size_t) max_color) { + show_status(PrintDialogStatus::PrintStatusColorQuantityExceed, {wxString::Format("%d", max_color)}); return; } } @@ -4487,6 +4501,13 @@ void SelectMachineDialog::reset_and_sync_ams_list() int left_sizer_count = 0, right_sizer_count = 0, sizer_count = 0; BitmapCache bmcache; + + auto dev = wxGetApp().getDeviceManager()->get_selected_machine(); + bool has_switcher = dev && dev->GetFilaSwitch()->IsInstalled(); + + auto filament_color_render_info = wxGetApp().plater()->get_filament_colors_render_info(); + auto filament_color_type_info = wxGetApp().plater()->get_filament_color_render_type(); + for (auto i = 0; i < used_filaments.size(); i++) { auto used_filament = used_filaments[i] - 1; if (used_filament >= preset_filament_vec.size()) { @@ -4507,8 +4528,6 @@ void SelectMachineDialog::reset_and_sync_ams_list() // create material item MaterialItem* item = nullptr; - auto dev = wxGetApp().getDeviceManager()->get_selected_machine(); - bool has_switcher = dev && dev->GetFilaSwitch()->IsInstalled(); if (extruder_nums == 2 && !has_switcher) { if (m_filaments_map[used_filament] == 1) { item = new MaterialItem(m_filament_left_panel, colour_rgb, preset_filament.filament_display_type, preset_filament.filament_id); @@ -4526,6 +4545,20 @@ void SelectMachineDialog::reset_and_sync_ams_list() } if (!item) { continue; } + + if (used_filament < filament_color_render_info.size() && used_filament < filament_color_type_info.size()) { + auto color_strs = Slic3r::split_string(filament_color_render_info[used_filament], ' '); + if (color_strs.size() > 1) { + int ctype = (filament_color_type_info[used_filament] == "0") ? 0 : 1; + std::vector cols; + for (const auto& cs : color_strs) { + wxColour c(cs); + if (c.IsOk()) cols.push_back(c); + } + if (cols.size() > 1) item->set_material_cols(ctype, cols); + } + } + item->SetToolTip(_L("Upper half area: Original\nLower half area: Filament in AMS\nAnd you can click it to modify")); if (!selected_any && used_filament == m_current_filament_id && item->m_enable) { @@ -5007,6 +5040,9 @@ void SelectMachineDialog::set_default_from_sdcard() MaterialItem *first_enabled = nullptr; int first_enabled_id = -1; + auto filament_color_render_info2 = wxGetApp().plater()->get_filament_colors_render_info(); + auto filament_color_type_info2 = wxGetApp().plater()->get_filament_color_render_type(); + for (auto i = 0; i < m_required_data_plate_data_list[m_print_plate_idx]->slice_filaments_info.size(); i++) { FilamentInfo fo = m_required_data_plate_data_list[m_print_plate_idx]->slice_filaments_info[i]; @@ -5030,6 +5066,19 @@ void SelectMachineDialog::set_default_from_sdcard() if (!item) continue; + if (fo.id < (int)filament_color_render_info2.size() && fo.id < (int)filament_color_type_info2.size()) { + auto color_strs = Slic3r::split_string(filament_color_render_info2[fo.id], ' '); + if (color_strs.size() > 1) { + int ctype = (filament_color_type_info2[fo.id] == "0") ? 0 : 1; + std::vector cols; + for (const auto& cs : color_strs) { + wxColour c(cs); + if (c.IsOk()) cols.push_back(c); + } + if (cols.size() > 1) item->set_material_cols(ctype, cols); + } + } + if (!selected_any && fo.id == m_current_filament_id && item->m_enable) { item->on_selected(); selected_any = true; @@ -6455,13 +6504,17 @@ std::optional SelectMachineDialog::get_filament_change_gap_time(MachineOb params.selector_load_time = params.standard_load_time * 0.5; params.selector_unload_time = params.standard_unload_time * 0.5; + int group_count = group_of_filaments.empty() ? 0 : *std::max_element(group_of_filaments.begin(), group_of_filaments.end()) + 1; + std::vector ams_preload_enabled(group_count, obj_->ams_preload_version >= 1); + try { return MultiNozzleUtils::calc_filament_change_gap_for_assignment(logic_filaments, nozzle_list, fila_change_seq, nozzle_change_seq, group_of_filaments, - params); + params, + ams_preload_enabled); } catch (const std::exception& e) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": exception: " << e.what(); return std::nullopt; diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index b425d688aa..4b78b288ed 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -3275,6 +3275,8 @@ void StatusPanel::update_ams(MachineObject *obj) cali_info.use_extruder_id = false; cali_info.use_nozzle_volume_type = false; CalibUtils::emit_get_PA_calib_infos(cali_info); + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " calibration: sync calib version for device " << BBLCrossTalk::Crosstalk_DevName(obj->get_dev_name()); } if (obj && obj->is_security_control_ready()) { obj->check_ams_filament_valid(); } @@ -3334,7 +3336,7 @@ void StatusPanel::update_ams(MachineObject *obj) } // must select a current can - m_ams_control->UpdateAms(obj->get_printer_series_str(), obj->printer_type, ams_info, ext_info, *obj->GetExtderSystem(), obj->get_dev_id(), false); + m_ams_control->UpdateAms(obj->get_printer_series_str(), obj->printer_type, ams_info, ext_info, *obj->GetExtderSystem(), obj->get_dev_id(), obj, false); m_ams_control->UpdateAmsDryControl(obj); last_tray_exist_bits = obj->tray_exist_bits; @@ -4245,7 +4247,7 @@ void StatusPanel::on_ams_load_curr() } } - FeedDirectionDialog dialog(nullptr, 2); + FeedDirectionDialog dialog(nullptr, 2, obj->printer_type); dialog.SetExtruderMapping(obj, curr_ams_id, curr_can_id, extruderSlots); auto rtn = dialog.ShowModal(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index cd27ab5154..3e1f3ae506 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -61,6 +61,19 @@ namespace Slic3r { t_config_option_keys deep_diff(const ConfigBase &config_this, const ConfigBase &config_other, bool strict = true); +// Check if `opt` is a variant key like "opt_abc#0" (per-extruder/nozzle-volume option). +// When it is, return index of '#' +// When it is not, return 0 +size_t variant_option_hash_pos(const std::string &opt, Preset::Type type) +{ + auto n = opt.find('#'); + if (n == std::string::npos) return 0; + + if (type == Preset::TYPE_FILAMENT && filament_options_with_variant.count(opt.substr(0, n)) == 0) return 0; + + return n; +} + namespace GUI { #define DISABLE_UNDO_SYS @@ -2572,42 +2585,102 @@ void Tab::cache_config_diff(const std::vector& selected_options) m_cache_config.apply_only(m_presets->get_edited_preset().config, selected_options); } +// Variants related options need special handling when transfering to another printer +// If m_cache_options ends with the variant trailer (title, variants_key) pushed by +// handle_transfer_action, we'll do our work here, otherwise we dont touch it +// +// variant names encodes extruder type (such as direct drive and Bowden) and volume (such as Standard and High Flow) +// we should try our best to transfer as much options as possible +// the genral rule is: if variant matches, transfer, when ambugious encounted, dont transfer +void Tab::remap_variant_cache() +{ + const auto &variants_key = extruder_variant_keys[m_type].second; + if (m_cache_options.empty() || m_cache_options.back() != variants_key) return; + + m_cache_options.pop_back(); // variants_key + auto title = m_cache_options.back(); + m_cache_options.pop_back(); + + auto *old_variants = dynamic_cast(m_cache_config.option(variants_key)); + auto *new_variants = dynamic_cast(m_config->option(variants_key)); + assert(old_variants && new_variants); + if (*old_variants == *new_variants) return; + + const auto &old_vars = old_variants->values; + const auto &new_vars = new_variants->values; + bool any_variant_dropped = false; + + // pop the master_extruder_id we pushed in handle_transfer_action + const int master_extruder_id = dynamic_cast(m_cache_config.option("master_extruder_id"))->value; + m_cache_config.erase("master_extruder_id"); + + std::vector remapped; + remapped.reserve(m_cache_options.size()); + + // If two slots share a variant name but hold different values + // (e.g. H2C dual-direct-drive's two "Direct Drive Standard" slots), + // choose the one on the master extruder + auto best_source_idx = [&old_vars, master_extruder_id](size_t si, ConfigOptionVectorBase *cached) { + auto cached_values = cached->vserialize(); + for (size_t i = 0; i < cached_values.size(); ++i) { + if (old_vars[i] == old_vars[si] && cached_values[i] != cached_values[si]) { + // ambiguous, choose the one on the master_extruder_id, 1 based + return master_extruder_id > 1 ? std::max(si, i) : std::min(si, i); + } + } + + // no ambiguous + return si; + }; + + // copy to all dest slots where variant matches + auto copy_options = [&old_vars, &new_vars, &remapped](size_t si, ConfigOptionVectorBase *cached, const std::string &opt) { + bool succeed = false; + for (size_t di = 0; di < new_vars.size(); ++di) { + if (new_vars[di] != old_vars[si]) continue; + + succeed = true; + if (di != si) cached->set_at(cached, di, si); + remapped.push_back(opt + "#" + std::to_string(di)); + } + return succeed; + }; + + for (auto &entry : m_cache_options) { + auto hash_pos = variant_option_hash_pos(entry, m_type); + if (!hash_pos) { + remapped.push_back(std::move(entry)); + continue; + } + + size_t si = size_t(std::stoul(entry.substr(hash_pos + 1))); + auto opt = entry.substr(0, hash_pos); + auto *cached = dynamic_cast(m_cache_config.option(opt)); + + si = best_source_idx(si, cached); + + if (!copy_options(si, cached, opt)) { + any_variant_dropped |= true; + BOOST_LOG_TRIVIAL(info) << "option variant not matched will not be transfered: " << entry << ", " << old_vars[si]; + } + } + m_cache_options = std::move(remapped); + + if (any_variant_dropped) { + auto msg = _L("Switching to a printer with different extruder types or numbers will discard or reset changes to extruder or multi-nozzle-related parameters."); + MessageDialog(wxGetApp().plater(), msg, from_u8(title), wxOK | wxICON_WARNING).ShowModal(); + } +} + void Tab::apply_config_from_cache() { bool was_applied = false; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<(this)->apply_extruder_cnt_from_cache(); + if (m_type == Preset::TYPE_PRINTER) was_applied = static_cast(this)->apply_extruder_cnt_from_cache(); if (!m_cache_config.empty()) { - auto variants_key = extruder_variant_keys[m_type].second; - if (m_cache_options.back() == variants_key) { - m_cache_options.pop_back(); - ConfigOptionStrings *old_variants = dynamic_cast(m_cache_config.option(variants_key)); - ConfigOptionStrings *new_variants = dynamic_cast(m_config->option(variants_key)); - std::vector variant_options; - boost::split(variant_options, m_cache_options.back(), boost::is_any_of(";")); - m_cache_options.pop_back(); - auto title = m_cache_options.back(); - m_cache_options.pop_back(); - if (!(*old_variants == *new_variants) && old_variants->size() == 1) { - for (auto &opt : variant_options) { - auto copy = dynamic_cast(m_cache_config.option(opt)->clone()); - copy->resize(new_variants->size()); - m_cache_config.set_key_value(opt, copy); - } - old_variants = new_variants; - } - auto *printer_tab = static_cast(wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)); - assert(printer_tab); - if ((*old_variants == *new_variants) || (printer_tab && printer_tab->should_keep_config())) { - m_cache_options.insert(m_cache_options.end(), variant_options.begin(), variant_options.end()); - } else { - auto msg = _L("Switching to a printer with different extruder types or numbers will discard or reset changes to extruder or multi-nozzle-related parameters."); - MessageDialog(wxGetApp().plater(), msg, from_u8(title), wxOK | wxICON_WARNING).ShowModal(); - } - } + remap_variant_cache(); m_presets->get_edited_preset().config.apply_only(m_cache_config, m_cache_options); m_cache_config.clear(); m_cache_options.clear(); @@ -5431,7 +5504,6 @@ void TabPrinter::on_preset_loaded() if (base_name != m_base_preset_name) { bool use_default_nozzle_volume_type = true; - m_last_base_preset_name = m_base_preset_name; m_base_preset_name = base_name; auto plater_for_nvt = wxGetApp().plater(); if (plater_for_nvt && plater_for_nvt->is_loading_project()) { @@ -6405,22 +6477,26 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr auto &cache_options = tab->m_cache_options; auto &cache_config = tab->m_cache_config; auto &edited_config = presets->get_edited_preset().config; - std::vector variant_options; - for (auto &opt : cache_options) { - if (auto n = opt.find('#'); n != std::string::npos) { - if (type == Preset::TYPE_FILAMENT && filament_options_with_variant.count(opt.substr(0, n)) == 0) - continue; - variant_options.push_back(opt.substr(0, n)); - opt.clear(); - } + // variant options like "opt#idx" need special processing + // append title in case of warning users we have to discard some mofified options + // append extruder_variant_keys[type].second so we know we have some variant options modified + bool has_variant_edits = false; + for (const auto &opt : cache_options) { + auto hash_pos = variant_option_hash_pos(opt, m_type); + if (!hash_pos) continue; + has_variant_edits = true; + // copy all slots/variant + cache_config.apply_only(edited_config, {opt.substr(0, hash_pos)}); } - if (!variant_options.empty()) { - cache_options.erase(std::remove(cache_options.begin(), cache_options.end(), std::string{}), cache_options.end()); + + if (has_variant_edits) { cache_options.push_back(into_u8(dlg.GetTitle())); - cache_options.push_back(boost::join(variant_options, ";")); cache_options.push_back(extruder_variant_keys[type].second); - variant_options.push_back(extruder_variant_keys[type].second); - cache_config.apply_only(edited_config, variant_options); + cache_config.apply_only(edited_config, {extruder_variant_keys[type].second}); + // Stash the source printer's master_extruder_id so remap_variant_cache can + // tiebreak ambiguous duplicate variants (e.g. H2C dual-direct-drive) using + // the extruder the user had designated as master on the source printer. + cache_config.apply_only(m_preset_bundle->printers.get_edited_preset().config, {"master_extruder_id"}); } } }; @@ -7278,20 +7354,6 @@ bool TabPrinter::apply_extruder_cnt_from_cache() return false; } -bool TabPrinter::should_keep_config() const { - // disable this temporarily for a hot fix due to a bug - return false; - - const auto *old_printer = m_preset_bundle->printers.find_preset(m_last_base_preset_name); - const auto &cur_printer = m_preset_bundle->printers.get_selected_preset(); - - if (extruders_count(old_printer) != extruders_count(&cur_printer)) return false; - - auto old_nozzle = default_nozzle_volume_types(m_preset_bundle, old_printer); - auto new_nozzle = default_nozzle_volume_types(m_preset_bundle, &cur_printer); - return old_nozzle == new_nozzle; -} - bool Tab::validate_custom_gcodes() { if (m_type != Preset::TYPE_FILAMENT && diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 098d6d024b..912304a1a4 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -420,6 +420,12 @@ class Tab: public wxPanel void apply_searcher(); void cache_config_diff(const std::vector& selected_options); void apply_config_from_cache(); + +private: + // when transfer modified options to a new printer, we may need do some work here + void remap_variant_cache(); + +public: void show_timelapse_warning_dialog(); const std::map& get_category_icon_map() { return m_category_icon; } @@ -628,8 +634,7 @@ class TabPrinter : public Tab std::vector m_pages_sla; std::vector m_extruder_type; std::string m_base_preset_name; - std::string m_base_preset_model; - std::string m_last_base_preset_name; + std::string m_base_preset_model; public: ScalableButton* m_reset_to_filament_color = nullptr; @@ -671,14 +676,7 @@ class TabPrinter : public Tab wxSizer* create_bed_shape_widget(wxWindow* parent); void cache_extruder_cnt(); - bool apply_extruder_cnt_from_cache(); - - // when switching printers, should we keep/transfer or discard user modified parameters? - // the old logic is a bit complex and it is too risky to touch it - // just add a patch here to handle some discarded case: - // for printers with the same number of extuders and used the same nozzle configurations, keep it - // Maybe we can simplify this logic and move them into one place - bool should_keep_config() const; + bool apply_extruder_cnt_from_cache(); }; class TabSLAMaterial : public Tab diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index e169de95f1..1e2ccb7dce 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -381,6 +381,19 @@ std::tuple AMSControl::isFilaSwitchReady() return {false, false}; } +bool AMSControl::isFilaSwitchInstalled() const +{ + DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) return false; + MachineObject* obj = dev->get_selected_machine(); + if (!obj) return false; + std::shared_ptr filaSwitch = obj->GetFilaSwitch(); + if (filaSwitch) { + return filaSwitch->IsInstalled(); + } + return false; +} + void AMSControl::AmsSelectedSwitch(wxCommandEvent& event) { std::string ams_id_selected = std::to_string(event.GetInt()); if (m_current_ams != ams_id_selected){ @@ -903,6 +916,7 @@ void AMSControl::UpdateAms(const std::string &series_name, std::vector ext_info, DevExtderSystem data, std::string dev_id, + MachineObject* obj, bool is_reset, bool test) { @@ -1018,6 +1032,28 @@ void AMSControl::UpdateAms(const std::string &series_name, this->Refresh(true); this->Update(); } + + /*update ext road visibility when fila switch installed*/ + bool road_visibility_changed = false; + for (auto& [ams_id, ams_item] : m_ams_item_list) { + if (!ams_item) continue; + const bool should_show_road = !(install && ams_item->get_ams_model() == DevAmsType::EXT_SPOOL); + if (ams_item->ShowRoad(should_show_road)) { + road_visibility_changed = true; + } + } + if (road_visibility_changed) { + m_amswin->Layout(); + } + + /*distribute device info to road components*/ + std::weak_ptr fila_sys_weak; + if (obj) fila_sys_weak = obj->GetFilaSystem(); + for (auto& [id, item] : m_ams_item_list) { + if (item) item->UpdateDeviceInfo(fila_sys_weak); + } + if (m_vams_road) m_vams_road->UpdateDeviceInfo(fila_sys_weak); + if (m_down_road) m_down_road->UpdateDeviceInfo(fila_sys_weak); } void AMSControl::AddAmsPreview(AMSinfo info, AMSPanelPos pos) @@ -1055,29 +1091,32 @@ void AMSControl::createAms(wxSimplebook* parent, int& idx, AMSinfo info, AMSPane AMSRoadShowMode AMSControl::findFirstMode(AMSPanelPos pos) { auto init_mode = AMSRoadShowMode::AMS_ROAD_MODE_NONE; + const bool fila_switch_installed = isFilaSwitchInstalled(); - std::string ams_id = ""; for (const auto& [idx, ams_item] : m_ams_item_list) { - if(ams_item->get_panel_pos() == pos){ - ams_id = idx; - break; - } - } - - auto item = m_ams_item_list.find(ams_id); - if (ams_id.empty() || item == m_ams_item_list.end()) return init_mode; + if (ams_item->get_panel_pos() != pos) continue; + if (fila_switch_installed && ams_item->get_ams_model() == DevAmsType::EXT_SPOOL) continue; - if (item->second->get_can_count() == GENERIC_AMS_SLOT_NUM) { - if (item->second->get_ams_model() == DevAmsType::AMS_LITE) return AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; - if (item->second->get_ams_model() == DevAmsType::EXT_SPOOL && item->second->get_ext_type() == AMSModelOriginType::LITE_EXT) return AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; - return AMSRoadShowMode::AMS_ROAD_MODE_FOUR; - } - else{ - if (IsInSlotPair(ams_id)) return AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE; - if (item->second->get_ams_model() == DevAmsType::EXT_SPOOL && item->second->get_ext_type() == AMSModelOriginType::LITE_EXT) return AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; - if (item->second->get_ams_model() == DevAmsType::N3S) return AMSRoadShowMode::AMS_ROAD_MODE_SINGLE_N3S; - return AMSRoadShowMode::AMS_ROAD_MODE_SINGLE; + const std::string& ams_id = idx; + if (ams_item->get_can_count() == GENERIC_AMS_SLOT_NUM) { + if (ams_item->get_ams_model() == DevAmsType::AMS_LITE) return AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; + if (ams_item->get_ams_model() == DevAmsType::EXT_SPOOL && ams_item->get_ext_type() == AMSModelOriginType::LITE_EXT) return AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; + return AMSRoadShowMode::AMS_ROAD_MODE_FOUR; + } + else { + if (IsInSlotPair(ams_id)) { + AMSRoadShowMode replaced = AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE; + if (GetExtPairedDoubleMode(ams_id, pos, replaced)) { + return replaced; + } + return AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE; + } + if (ams_item->get_ams_model() == DevAmsType::EXT_SPOOL && ams_item->get_ext_type() == AMSModelOriginType::LITE_EXT) return AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; + if (ams_item->get_ams_model() == DevAmsType::N3S) return AMSRoadShowMode::AMS_ROAD_MODE_SINGLE_N3S; + return AMSRoadShowMode::AMS_ROAD_MODE_SINGLE; + } } + return init_mode; } void AMSControl::createAmsPanel(wxSimplebook *parent, int &idx, std::vector infos, const std::string &series_name, const std::string &printer_type, AMSPanelPos pos, int total_ext_num) @@ -1302,27 +1341,57 @@ void AMSControl::SwitchAms(std::string ams_id) } const auto& panel_pos = ams_item->get_panel_pos(); - if (ams_item->get_can_count() == GENERIC_AMS_SLOT_NUM) { - if (ams_item->get_ams_model() == DevAmsType::AMS_LITE) { - if (panel_pos == AMSPanelPos::LEFT_PANEL) { - m_down_road->UpdateLeft(m_total_ext_count, AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE); - } else { - m_down_road->UpdateRight(m_total_ext_count, AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE); - } + const bool fila_switch_installed = isFilaSwitchInstalled(); + + // When fila switch is installed and the clicked preview is an EXT_SPOOL paired + // with an AMS in the same book page, both previews share the same down-road view. + // Drive the mode computation from the paired AMS item so switching between + // the two previews renders identical lines. + std::string effective_ams_id = ams_id; + AmsItem* effective_item = ams_item; + if (fila_switch_installed && ams_item->get_ams_model() == DevAmsType::EXT_SPOOL) { + for (const auto& p : pair_id) { + const std::string* other = nullptr; + if (p.first == ams_id) other = &p.second; + else if (p.second == ams_id) other = &p.first; + else continue; + const auto other_it = m_ams_item_list.find(*other); + if (other_it == m_ams_item_list.end() || !other_it->second) continue; + if (other_it->second->get_ams_model() == DevAmsType::EXT_SPOOL) continue; + effective_ams_id = *other; + effective_item = other_it->second; + break; + } + } + + const bool hide_ext_road = fila_switch_installed && effective_item->get_ams_model() == DevAmsType::EXT_SPOOL; + + if (effective_item->get_can_count() == GENERIC_AMS_SLOT_NUM) { + AMSRoadShowMode mode; + if (effective_item->get_ams_model() == DevAmsType::AMS_LITE) { + mode = AMSRoadShowMode::AMS_ROAD_MODE_AMS_LITE; } else { - if (panel_pos == AMSPanelPos::LEFT_PANEL) { - m_down_road->UpdateLeft(m_total_ext_count, AMSRoadShowMode::AMS_ROAD_MODE_FOUR); - } else { - m_down_road->UpdateRight(m_total_ext_count, AMSRoadShowMode::AMS_ROAD_MODE_FOUR); - } + mode = AMSRoadShowMode::AMS_ROAD_MODE_FOUR; + } + if (hide_ext_road) mode = AMSRoadShowMode::AMS_ROAD_MODE_NONE; + + if (panel_pos == AMSPanelPos::LEFT_PANEL) { + m_down_road->UpdateLeft(m_total_ext_count, mode); + } else { + m_down_road->UpdateRight(m_total_ext_count, mode); } } else { AMSRoadShowMode mode = AMSRoadShowMode::AMS_ROAD_MODE_SINGLE; - if (IsInSlotPair(ams_id)) { + if (IsInSlotPair(effective_ams_id)) { mode = AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE; - } else if(ams_item->get_ams_model() == DevAmsType::N3S){ + AMSRoadShowMode replaced = AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE; + if (GetExtPairedDoubleMode(effective_ams_id, panel_pos, replaced)) { + mode = replaced; + } + } else if(effective_item->get_ams_model() == DevAmsType::N3S){ mode = AMSRoadShowMode::AMS_ROAD_MODE_SINGLE_N3S; - } + } + if (hide_ext_road) mode = AMSRoadShowMode::AMS_ROAD_MODE_NONE; if (panel_pos == AMSPanelPos::LEFT_PANEL) { m_down_road->UpdateLeft(m_total_ext_count, mode); @@ -1632,6 +1701,38 @@ bool AMSControl::IsInSlotPair(const std::string& ams_id) const return false; } +bool AMSControl::GetExtPairedDoubleMode(const std::string& ams_id, AMSPanelPos panel_pos, AMSRoadShowMode& out_mode) const +{ + if (!isFilaSwitchInstalled()) return false; + + for (const auto& p : pair_id) { + const std::string* other_id = nullptr; + bool ams_is_first = false; + if (p.first == ams_id) { + other_id = &p.second; + ams_is_first = true; + } else if (p.second == ams_id) { + other_id = &p.first; + ams_is_first = false; + } else { + continue; + } + + const auto it = m_ams_item_list.find(*other_id); + if (it == m_ams_item_list.end() || !it->second) continue; + if (it->second->get_ams_model() != DevAmsType::EXT_SPOOL) continue; + + // Position mapping (see AmsItem length in UpdateAms/OnAmsLoading): + // LEFT_PANEL : pair.first => FAR (-218), pair.second => NEAR (-110) + // RIGHT_PANEL: pair.first => NEAR (+110), pair.second => FAR (+218) + const bool ams_at_far = (panel_pos == AMSPanelPos::LEFT_PANEL) ? ams_is_first : !ams_is_first; + out_mode = ams_at_far ? AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE_FAR_ONLY + : AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE_NEAR_ONLY; + return true; + } + return false; +} + void AMSControl::UpdateAmsPreviewSelection() { // Switch ams preview selection display diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index 927698c1ec..32dcd7d3f7 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -167,6 +167,7 @@ class AMSControl : public wxSimplebook std::vector ext_info, DevExtderSystem data, std::string dev_id, + MachineObject* obj = nullptr, bool is_reset = true, bool test = false); @@ -186,6 +187,7 @@ class AMSControl : public wxSimplebook void Reset(); std::tuple isFilaSwitchReady(); + bool isFilaSwitchInstalled() const; void show_switcher_status(bool show); void show_noams_mode(); void show_auto_refill(bool show); @@ -208,6 +210,11 @@ class AMSControl : public wxSimplebook void UpdateAmsPreviewSelection(); bool IsInSlotPair(const std::string& ams_id) const; + + // When fila switch is installed and the given AMS item is paired with an EXT_SPOOL + // in the same panel, return the DOUBLE variant that only draws the AMS side. + // Returns false if no replacement is needed (caller should keep using DOUBLE). + bool GetExtPairedDoubleMode(const std::string& ams_id, AMSPanelPos panel_pos, AMSRoadShowMode& out_mode) const; }; }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Widgets/AMSItem.cpp b/src/slic3r/GUI/Widgets/AMSItem.cpp index 1022b067a0..50ca1608db 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.cpp +++ b/src/slic3r/GUI/Widgets/AMSItem.cpp @@ -1997,8 +1997,10 @@ void AMSRoad::doRender(wxDC &dc) //virtual road if (m_rode_mode == AMSRoadMode::AMS_ROAD_MODE_VIRTUAL_TRAY) { - dc.SetBrush(wxBrush(m_road_def_color)); - dc.DrawLine(size.x / 2, -1, size.x / 2, size.y - 1); + if (!shouldHideExtRoad()) { + dc.SetBrush(wxBrush(m_road_def_color)); + dc.DrawLine(size.x / 2, -1, size.x / 2, size.y - 1); + } } // mode none @@ -2061,6 +2063,22 @@ void AMSRoad::doRender(wxDC &dc) void AMSRoad::UpdatePassRoad(int tag_index, AMSPassRoadType type, AMSPassRoadSTEP step) {} +void AMSRoad::UpdateDeviceInfo(std::weak_ptr fila_system) +{ + m_fila_system = fila_system; + Refresh(); +} + +bool AMSRoad::shouldHideExtRoad() const +{ + auto fila_sys = m_fila_system.lock(); + if (!fila_sys) return false; + auto* obj = fila_sys->GetOwner(); + if (!obj) return false; + auto fila_switch = obj->GetFilaSwitch(); + return fila_switch && fila_switch->IsInstalled() && fila_switch->IsReady(); +} + void AMSRoad::OnPassRoad(std::vector prord_list) { // AMS_ROAD_MODE_NONE, AMS_ROAD_MODE_LEFT, AMS_ROAD_MODE_LEFT_RIGHT, AMS_ROAD_MODE_END_TOP, AMS_ROAD_MODE_END_BOTTOM, AMS_ROAD_MODE_END_RIGHT, @@ -2241,10 +2259,13 @@ void AMSRoadUpPart::doRender(wxDC& dc) dc.SetBrush(wxBrush(*wxTRANSPARENT_BRUSH)); if ((m_ams_model == DevAmsType::N3S || m_ams_model == DevAmsType::EXT_SPOOL) && m_amsinfo.cans.size() != 4){ - dc.DrawLine(((float)size.x / 2), (0), ((float)size.x / 2), (size.y)); - if (m_load_step == AMSPassRoadSTEP::AMS_ROAD_STEP_2 || m_load_step == AMSPassRoadSTEP::AMS_ROAD_STEP_3){ - dc.SetPen(wxPen(_get_diff_clr(this, m_amsinfo.cans[m_load_slot_index].material_colour), 4, wxPENSTYLE_SOLID)); - dc.DrawLine((size.x / 2), (0), (size.x / 2), (size.y)); + bool hide_ext = (m_ams_model == DevAmsType::EXT_SPOOL) && shouldHideExtRoad(); + if (!hide_ext) { + dc.DrawLine(((float)size.x / 2), (0), ((float)size.x / 2), (size.y)); + if (m_load_step == AMSPassRoadSTEP::AMS_ROAD_STEP_2 || m_load_step == AMSPassRoadSTEP::AMS_ROAD_STEP_3){ + dc.SetPen(wxPen(_get_diff_clr(this, m_amsinfo.cans[m_load_slot_index].material_colour), 4, wxPENSTYLE_SOLID)); + dc.DrawLine((size.x / 2), (0), (size.x / 2), (size.y)); + } } } else{ @@ -2318,7 +2339,21 @@ void AMSRoadUpPart::msw_rescale() { Refresh(); } +void AMSRoadUpPart::UpdateDeviceInfo(std::weak_ptr fila_system) +{ + m_fila_system = fila_system; + Refresh(); +} +bool AMSRoadUpPart::shouldHideExtRoad() const +{ + auto fila_sys = m_fila_system.lock(); + if (!fila_sys) return false; + auto* obj = fila_sys->GetOwner(); + if (!obj) return false; + auto fila_switch = obj->GetFilaSwitch(); + return fila_switch && fila_switch->IsInstalled() && fila_switch->IsReady(); +} /************************************************* Description:AMSRoadDownPart @@ -2446,7 +2481,7 @@ void AMSRoadDownPart::doRender(wxDC& dc) wxPoint left_nozzle_pos = wxPoint(std::ceil((float)size.x / 2 - FromDIP(8)), FromDIP(258)); wxPoint right_nozzle_pos = wxPoint(std::ceil((float)size.x / 2 + FromDIP(6)), FromDIP(258)); dc.SetPen(empty_pen); - if (m_left_rode_mode == AMSRoadShowMode::AMS_ROAD_MODE_NONE || m_right_rode_mode == AMSRoadShowMode::AMS_ROAD_MODE_NONE){ + if (m_nozzle_num < 2 && (m_left_rode_mode == AMSRoadShowMode::AMS_ROAD_MODE_NONE || m_right_rode_mode == AMSRoadShowMode::AMS_ROAD_MODE_NONE)){ //switch (m_left_rode_mode) { // default: break; //}; @@ -2488,6 +2523,14 @@ void AMSRoadDownPart::doRender(wxDC& dc) dc.DrawLine(left_nozzle_pos.x - FromDIP(110), 0, left_nozzle_pos.x - FromDIP(110), (size.y / 2)); dc.DrawLine(left_nozzle_pos.x - FromDIP(218), 0, left_nozzle_pos.x - FromDIP(218), (size.y / 2)); break; + case AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE_FAR_ONLY: + dc.DrawLine(left_nozzle_pos.x - FromDIP(218), (size.y / 2), left_nozzle_pos.x, (size.y / 2)); + dc.DrawLine(left_nozzle_pos.x - FromDIP(218), 0, left_nozzle_pos.x - FromDIP(218), (size.y / 2)); + break; + case AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE_NEAR_ONLY: + dc.DrawLine(left_nozzle_pos.x - FromDIP(110), (size.y / 2), left_nozzle_pos.x, (size.y / 2)); + dc.DrawLine(left_nozzle_pos.x - FromDIP(110), 0, left_nozzle_pos.x - FromDIP(110), (size.y / 2)); + break; case AMSRoadShowMode::AMS_ROAD_MODE_SINGLE: dc.DrawLine(left_nozzle_pos.x - FromDIP(129), (size.y / 2), left_nozzle_pos.x, (size.y / 2)); dc.DrawLine(left_nozzle_pos.x - FromDIP(129), 0, left_nozzle_pos.x - FromDIP(129), (size.y / 2)); @@ -2514,6 +2557,14 @@ void AMSRoadDownPart::doRender(wxDC& dc) dc.DrawLine(right_nozzle_pos.x + FromDIP(110), 0, right_nozzle_pos.x + FromDIP(110), (size.y / 2)); dc.DrawLine(right_nozzle_pos.x + FromDIP(218), 0, right_nozzle_pos.x + FromDIP(218), (size.y / 2)); break; + case AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE_FAR_ONLY: + dc.DrawLine(right_nozzle_pos.x, (size.y / 2), right_nozzle_pos.x + FromDIP(218), (size.y / 2)); + dc.DrawLine(right_nozzle_pos.x + FromDIP(218), 0, right_nozzle_pos.x + FromDIP(218), (size.y / 2)); + break; + case AMSRoadShowMode::AMS_ROAD_MODE_DOUBLE_NEAR_ONLY: + dc.DrawLine(right_nozzle_pos.x, (size.y / 2), right_nozzle_pos.x + FromDIP(110), (size.y / 2)); + dc.DrawLine(right_nozzle_pos.x + FromDIP(110), 0, right_nozzle_pos.x + FromDIP(110), (size.y / 2)); + break; case AMSRoadShowMode::AMS_ROAD_MODE_SINGLE: dc.DrawLine(right_nozzle_pos.x, (size.y / 2), right_nozzle_pos.x + FromDIP(131), (size.y / 2)); dc.DrawLine(right_nozzle_pos.x + FromDIP(131), 0, right_nozzle_pos.x + FromDIP(131), (size.y / 2)); @@ -2536,8 +2587,12 @@ void AMSRoadDownPart::doRender(wxDC& dc) if (m_nozzle_num == 2) { /*dc.DrawLine(FromDIP(left_nozzle_pos.x), FromDIP(size.y / 2), FromDIP(left_nozzle_pos.x), FromDIP(size.y)); dc.DrawLine(FromDIP(right_nozzle_pos.x), FromDIP(size.y / 2), FromDIP(right_nozzle_pos.x), FromDIP(size.y));*/ - dc.DrawLine((left_nozzle_pos.x), (size.y / 2), (left_nozzle_pos.x), (size.y)); - dc.DrawLine((right_nozzle_pos.x), (size.y / 2), (right_nozzle_pos.x), (size.y)); + if (m_left_rode_mode != AMSRoadShowMode::AMS_ROAD_MODE_NONE) { + dc.DrawLine((left_nozzle_pos.x), (size.y / 2), (left_nozzle_pos.x), (size.y)); + } + if (m_right_rode_mode != AMSRoadShowMode::AMS_ROAD_MODE_NONE) { + dc.DrawLine((right_nozzle_pos.x), (size.y / 2), (right_nozzle_pos.x), (size.y)); + } } else { if (m_right_rode_mode != AMSRoadShowMode::AMS_ROAD_MODE_NONE && m_left_rode_mode != AMSRoadShowMode::AMS_ROAD_MODE_NONE) { @@ -2629,6 +2684,22 @@ void AMSRoadDownPart::msw_rescale() { Refresh(); } +void AMSRoadDownPart::UpdateDeviceInfo(std::weak_ptr fila_system) +{ + m_fila_system = fila_system; + Refresh(); +} + +bool AMSRoadDownPart::shouldHideExtRoad() const +{ + auto fila_sys = m_fila_system.lock(); + if (!fila_sys) return false; + auto* obj = fila_sys->GetOwner(); + if (!obj) return false; + auto fila_switch = obj->GetFilaSwitch(); + return fila_switch && fila_switch->IsInstalled() && fila_switch->IsReady(); +} + /************************************************* Description:AMSPreview **************************************************/ @@ -3286,6 +3357,16 @@ void AmsItem::create(wxWindow *parent) //Refresh(); } +bool AmsItem::ShowRoad(bool show) +{ + if (!m_panel_road) return false; + if (m_panel_road->IsShown() == show) return false; + m_panel_road->Show(show); + Layout(); + Refresh(); + return true; +} + void AmsItem::AddCan(Caninfo caninfo, int canindex, int maxcan, wxBoxSizer* sizer) { auto amscan = new wxWindow(this, wxID_ANY); @@ -3451,6 +3532,12 @@ void AmsItem::AddLiteCan(Caninfo caninfo, int canindex, wxGridSizer* sizer) //m_can_road_list[caninfo.can_id] = m_panel_road; } +void AmsItem::UpdateDeviceInfo(std::weak_ptr fila_system) +{ + if (m_panel_road) + m_panel_road->UpdateDeviceInfo(fila_system); +} + void AmsItem::Update(AMSinfo info) { if (m_info == info) @@ -4016,9 +4103,11 @@ void DevExtruderImage::doRender(wxDC &dc) FeedDirectionDialog::FeedDirectionDialog(wxWindow* parent, - const int extruderNum) + const int extruderNum, + const std::string& printer_type) : wxDialog(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize), - m_extruder_num(extruderNum) + m_extruder_num(extruderNum), + m_printer_type(printer_type) { SetBackgroundColour(wxColour("#FFFFFF")); SetMaxSize(wxSize(FromDIP(360), FromDIP(207))); @@ -4030,11 +4119,10 @@ FeedDirectionDialog::FeedDirectionDialog(wxWindow* parent, wxGridSizer* topSizer = new wxGridSizer (1, 3, FromDIP(5), 0); m_radioHelper = new wxRadioButton(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); - std::string ai_pt = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); m_leftRadio = new wxRadioButton(this, wxID_ANY, - _L(DevPrinterConfigUtil::get_toolhead_display_name(ai_pt, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); m_rightRadio = new wxRadioButton(this, wxID_ANY, - _L(DevPrinterConfigUtil::get_toolhead_display_name(ai_pt, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); m_radioHelper->Show(false); m_radioHelper->SetCanFocus(false); @@ -4099,8 +4187,7 @@ void FeedDirectionDialog::OnRadioClicked(wxCommandEvent& evt) m_extruderImage->setExtruderUsed("left"); m_load_extruder_id = 1; { - std::string ai_pt = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); - SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(ai_pt, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id)); + SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id)); } } else if (clicked == m_rightRadio) @@ -4109,8 +4196,7 @@ void FeedDirectionDialog::OnRadioClicked(wxCommandEvent& evt) m_extruderImage->setExtruderUsed("right"); m_load_extruder_id = 0; { - std::string ai_pt2 = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); - SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(ai_pt2, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id)); + SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id)); } } } diff --git a/src/slic3r/GUI/Widgets/AMSItem.hpp b/src/slic3r/GUI/Widgets/AMSItem.hpp index d9fbfb9594..ee695bd297 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.hpp +++ b/src/slic3r/GUI/Widgets/AMSItem.hpp @@ -67,7 +67,12 @@ enum class AMSRoadShowMode : int { AMS_ROAD_MODE_SINGLE, AMS_ROAD_MODE_SINGLE_N3S, AMS_ROAD_MODE_AMS_LITE, - AMS_ROAD_MODE_NONE + AMS_ROAD_MODE_ARROW, + AMS_ROAD_MODE_NONE, + // Variants of DOUBLE that only draw the AMS side when paired with an EXT_SPOOL + // (used when fila switch is installed and EXT's down-road should be hidden) + AMS_ROAD_MODE_DOUBLE_FAR_ONLY, + AMS_ROAD_MODE_DOUBLE_NEAR_ONLY, }; enum class AMSPassRoadMode : int { @@ -551,6 +556,7 @@ class AMSRoad : public wxWindow wxColour m_road_def_color; wxColour m_road_color; void Update(AMSinfo amsinfo, Caninfo info, int canindex, int maxcan); + void UpdateDeviceInfo(std::weak_ptr fila_system); std::vector ams_humidity_img; @@ -569,6 +575,10 @@ class AMSRoad : public wxWindow void paintEvent(wxPaintEvent &evt); void render(wxDC &dc); void doRender(wxDC &dc); + +private: + std::weak_ptr m_fila_system; + bool shouldHideExtRoad() const; }; @@ -584,6 +594,7 @@ class AMSRoadUpPart : public wxWindow public: void Update(AMSinfo amsinfo); + void UpdateDeviceInfo(std::weak_ptr fila_system); void OnVamsLoading(bool load, wxColour col = AMS_CONTROL_GRAY500); void SetPassRoadColour(wxColour col); @@ -622,6 +633,9 @@ class AMSRoadUpPart : public wxWindow bool m_show_humidity = {false}; bool m_vams_loading{false}; DevAmsType m_ams_model; + + std::weak_ptr m_fila_system; + bool shouldHideExtRoad() const; }; @@ -639,6 +653,7 @@ class AMSRoadDownPart : public wxWindow // void Update(AMSRoadDownPartMode nozzle, AMSRoadShowMode left_mode, AMSRoadShowMode right_mode, int left_len, int right_len); void UpdateLeft(int nozzle_num, AMSRoadShowMode mode); void UpdateRight(int nozzle_num, AMSRoadShowMode mode); + void UpdateDeviceInfo(std::weak_ptr fila_system); void OnVamsLoading(bool load, wxColour col = AMS_CONTROL_GRAY500); void SetPassRoadColour(bool left, wxColour col); @@ -669,6 +684,9 @@ class AMSRoadDownPart : public wxWindow std::map m_road_color; bool m_vams_loading{false}; DevAmsType m_ams_model; + + std::weak_ptr m_fila_system; + bool shouldHideExtRoad() const; }; /************************************************* @@ -770,6 +788,7 @@ class AmsItem : public wxWindow ~AmsItem(); void Update(AMSinfo info); + void UpdateDeviceInfo(std::weak_ptr fila_system); void create(wxWindow *parent); void AddCan(Caninfo caninfo, int canindex, int maxcan, wxBoxSizer* sizer); void AddLiteCan(Caninfo caninfo, int canindex, wxGridSizer* sizer); @@ -778,6 +797,7 @@ class AmsItem : public wxWindow void PlayRridLoading(wxString canid); void StopRridLoading(wxString canid); void msw_rescale(); + bool ShowRoad(bool show); void show_sn_value(bool show); void SetAmsStepExtra(wxString canid, AMSPassRoadType type, AMSPassRoadSTEP step); void SetAmsStep(std::string amsid, std::string canid, AMSPassRoadType type, AMSPassRoadSTEP step); @@ -914,7 +934,7 @@ class DevExtruderImage : public wxWindow class FeedDirectionDialog : public wxDialog { public: - FeedDirectionDialog(wxWindow* parent, const int extruderNum); + FeedDirectionDialog(wxWindow* parent, const int extruderNum, const std::string& printer_type = ""); std::optional GetExtruderID(); @@ -927,6 +947,7 @@ class FeedDirectionDialog : public wxDialog static wxString calcTrayName(MachineObject* obj, const std::string& amsID, const std::string& slotID); int m_extruder_num{}; + std::string m_printer_type; wxString m_filament_id{}; wxRadioButton* m_radioHelper{nullptr}; wxRadioButton* m_leftRadio{nullptr}; diff --git a/src/slic3r/GUI/Widgets/Label.cpp b/src/slic3r/GUI/Widgets/Label.cpp index be48956f28..f8a4fe9463 100644 --- a/src/slic3r/GUI/Widgets/Label.cpp +++ b/src/slic3r/GUI/Widgets/Label.cpp @@ -319,6 +319,17 @@ void Label::SetWindowStyleFlag(long style) Refresh(); } +wxSize Label::DoGetBestClientSize() const +{ + wxSize size = wxStaticText::DoGetBestClientSize(); +#ifdef WIN32 + // GetTextExtentPoint32 can underestimate the width needed by the native + // STATIC control to render text. Add a small margin to prevent clipping. + if (size.x > 0) size.x += FromDIP(4); +#endif + return size; +} + void Label::Wrap(int width) { wxLabelWrapper2 wrapper; diff --git a/src/slic3r/GUI/Widgets/Label.hpp b/src/slic3r/GUI/Widgets/Label.hpp index c887c1b44d..ab5fb8d624 100644 --- a/src/slic3r/GUI/Widgets/Label.hpp +++ b/src/slic3r/GUI/Widgets/Label.hpp @@ -21,6 +21,9 @@ class Label : public wxStaticText void Wrap(int width); +protected: + wxSize DoGetBestClientSize() const override; + private: void OnSize(wxSizeEvent & evt); diff --git a/src/slic3r/GUI/Widgets/StateColor.cpp b/src/slic3r/GUI/Widgets/StateColor.cpp index 184c79f726..c54bb9214f 100644 --- a/src/slic3r/GUI/Widgets/StateColor.cpp +++ b/src/slic3r/GUI/Widgets/StateColor.cpp @@ -41,7 +41,8 @@ static std::map gDarkColors{ {"#2B3436", "#808080"}, {"#ABABAB", "#ABABAB"}, {"#D9D9D9", "#2D2D32"}, - {"#EBF9F0", "#293F34"} + {"#EBF9F0", "#293F34"}, + {"#DBFDE7", "#1F3529"} //{"#F0F0F0", "#4C4C54"}, }; diff --git a/src/slic3r/GUI/fila_manager/CMakeLists.txt b/src/slic3r/GUI/fila_manager/CMakeLists.txt new file mode 100644 index 0000000000..36e9c921b8 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/CMakeLists.txt @@ -0,0 +1,18 @@ +# GUI/fila_manager +# Filament Manager — inventory, WebView UI, AMS sync + +list(APPEND SLIC3R_GUI_SOURCES + GUI/fila_manager/wgtFilaManagerStore.h + GUI/fila_manager/wgtFilaManagerStore.cpp + GUI/fila_manager/wgtFilaManagerPanel.h + GUI/fila_manager/wgtFilaManagerPanel.cpp + GUI/fila_manager/wgtFilaManagerSync.h + GUI/fila_manager/wgtFilaManagerSync.cpp + GUI/fila_manager/wgtFilaManagerCloudClient.h + GUI/fila_manager/wgtFilaManagerCloudClient.cpp + GUI/fila_manager/wgtFilaManagerCloudSync.h + GUI/fila_manager/wgtFilaManagerCloudSync.cpp + GUI/fila_manager/wgtFilaManagerCloudDispatcher.h + GUI/fila_manager/wgtFilaManagerCloudDispatcher.cpp +) +set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE) diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.cpp b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.cpp new file mode 100644 index 0000000000..e14d8069bb --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.cpp @@ -0,0 +1,248 @@ +#include "wgtFilaManagerCloudClient.h" + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/Utils/NetworkAgent.hpp" + +#include +#include + +namespace Slic3r { namespace GUI { + +namespace { + +using SuccessFn = wgtFilaManagerCloudClient::SuccessFn; +using ErrorFn = wgtFilaManagerCloudClient::ErrorFn; +using RequestFn = std::function; + +void emit_http_debug(const std::string& level, + const std::string& title, + const std::string& summary, + const nlohmann::json& detail = nlohmann::json::object()) +{ + wxGetApp().emit_fila_debug_log("http", level, title, summary, detail); +} + +nlohmann::json parse_json_response(const std::string& resp_body) +{ + try { + return nlohmann::json::parse(resp_body); + } catch (const std::exception&) { + return nlohmann::json{{"raw", resp_body}}; + } +} + +int parse_int(const std::map& query, const std::string& key, int default_value) +{ + auto it = query.find(key); + if (it == query.end() || it->second.empty()) + return default_value; + + try { + return std::stoi(it->second); + } catch (const std::exception&) { + return default_value; + } +} + +NetworkAgent* get_agent() +{ + return wxGetApp().getAgent(); +} + +void dispatch_agent_request(const std::string& action, + const nlohmann::json& request_detail, + RequestFn request, + SuccessFn on_ok, + ErrorFn on_err) +{ + emit_http_debug("info", + "NetworkAgent " + action, + "Dispatching filament cloud request through NetworkAgent", + request_detail); + + std::thread([action, request_detail, request = std::move(request), on_ok = std::move(on_ok), on_err = std::move(on_err)]() mutable { + NetworkAgent* agent = get_agent(); + if (!agent) { + wxGetApp().CallAfter([on_err, action]() { + emit_http_debug("error", + "NetworkAgent " + action + " failed", + "NetworkAgent is unavailable", + {{"action", action}, {"ret_code", BAMBU_NETWORK_ERR_INVALID_HANDLE}}); + if (on_err) + on_err(BAMBU_NETWORK_ERR_INVALID_HANDLE, "network agent unavailable"); + }); + return; + } + + std::string response_body; + int ret = request(agent, response_body); + + if (ret == BAMBU_NETWORK_SUCCESS) { + auto parsed = parse_json_response(response_body); + wxGetApp().CallAfter([on_ok, action, parsed = std::move(parsed), response_body]() mutable { + emit_http_debug("info", + "NetworkAgent " + action + " success", + "Filament cloud request completed via NetworkAgent", + {{"action", action}, {"response", parsed}, {"raw_response", response_body}}); + if (on_ok) + on_ok(parsed); + }); + return; + } + + wxGetApp().CallAfter([on_err, action, ret, response_body]() { + emit_http_debug("error", + "NetworkAgent " + action + " failed", + "Filament cloud request failed in NetworkAgent", + {{"action", action}, {"ret_code", ret}, {"body", response_body}}); + if (on_err) + on_err(ret, response_body.empty() ? "network request failed" : response_body); + }); + }).detach(); +} + +} // namespace + +bool wgtFilaManagerCloudClient::check_login(ErrorFn& on_err) const +{ + NetworkAgent* agent = get_agent(); + if (!agent || !agent->is_user_login()) { + if (on_err) + on_err(0, "user not logged in"); + return false; + } + return true; +} + +void wgtFilaManagerCloudClient::create_spool( + const nlohmann::json& body, SuccessFn on_ok, ErrorFn on_err) +{ + if (!check_login(on_err)) + return; + + dispatch_agent_request("create_spool", + {{"method", "POST"}, {"body", body}}, + [payload = body.dump()](NetworkAgent* agent, std::string& response_body) { + return agent->create_filament_spool(payload, &response_body); + }, + std::move(on_ok), + std::move(on_err)); +} + +void wgtFilaManagerCloudClient::update_spool( + const std::string& id, const nlohmann::json& body, SuccessFn on_ok, ErrorFn on_err) +{ + if (!check_login(on_err)) + return; + + // Swagger UpdateFilamentV2Req:`id` 为 int64 且 required,路由是 + // `PUT /my/filament/v2`(id 在 body,不在 path)。这里把字符串形式的本地 + // spool_id 转成 int64 写回 body;其余字段由 `spool_to_cloud_update_patch` + // 过滤过 swagger 白名单,调用方直接传入即可。 + nlohmann::json request_body = body.is_object() ? body : nlohmann::json::object(); + try { + request_body["id"] = std::stoll(id); + } catch (const std::exception&) { + // spool_id 不可解析为 int64 时保持字符串形式交给 server,让服务端回 + // 具体的 400 校验错误(而不是本地吞掉),便于排查。 + request_body["id"] = id; + } + + dispatch_agent_request("update_spool", + {{"method", "PUT"}, {"spool_id", id}, {"body", request_body}}, + [id, payload = request_body.dump()](NetworkAgent* agent, std::string& response_body) { + return agent->update_filament_spool(id, payload, &response_body); + }, + std::move(on_ok), + std::move(on_err)); +} + +void wgtFilaManagerCloudClient::batch_delete( + const nlohmann::json& body, SuccessFn on_ok, ErrorFn on_err) +{ + if (!check_login(on_err)) + return; + + // Tolerate both int / string arrays for "ids" (cloud schema uses int64), + // and both "RFIDs" (cloud key) / "rfids" (legacy local key). + auto collect_as_strings = [](const nlohmann::json& arr, std::vector& out) { + if (!arr.is_array()) return; + out.reserve(out.size() + arr.size()); + for (const auto& item : arr) { + if (item.is_string()) out.push_back(item.get()); + else if (item.is_number_integer()) out.push_back(std::to_string(item.get())); + else if (item.is_number_unsigned()) out.push_back(std::to_string(item.get())); + } + }; + + FilamentDeleteParams params; + if (body.contains("ids")) + collect_as_strings(body["ids"], params.ids); + if (body.contains("RFIDs")) + collect_as_strings(body["RFIDs"], params.rfids); + else if (body.contains("rfids")) + collect_as_strings(body["rfids"], params.rfids); + + if (params.ids.empty() && params.rfids.empty()) { + if (on_err) + on_err(0, "batch_delete requires 'ids' or 'rfids'"); + return; + } + + dispatch_agent_request("batch_delete", + {{"method", "DELETE"}, {"body", body}}, + [params](NetworkAgent* agent, std::string& response_body) mutable { + return agent->delete_filament_spools(params, &response_body); + }, + std::move(on_ok), + std::move(on_err)); +} + +void wgtFilaManagerCloudClient::list_spools( + const std::map& query, SuccessFn on_ok, ErrorFn on_err) +{ + if (!check_login(on_err)) + return; + + FilamentQueryParams params; + if (auto it = query.find("category"); it != query.end()) + params.category = it->second; + if (auto it = query.find("status"); it != query.end()) + params.status = it->second; + if (auto it = query.find("ids"); it != query.end()) + params.spool_id = it->second; + else if (auto it = query.find("spoolId"); it != query.end()) + params.spool_id = it->second; + else if (auto it2 = query.find("spool_id"); it2 != query.end()) + params.spool_id = it2->second; + if (auto it = query.find("RFIDs"); it != query.end()) + params.rfid = it->second; + else if (auto it = query.find("rfid"); it != query.end()) + params.rfid = it->second; + params.offset = parse_int(query, "offset", 0); + params.limit = parse_int(query, "limit", 20); + + dispatch_agent_request("list_spools", + {{"method", "GET"}, {"query", query}}, + [params](NetworkAgent* agent, std::string& response_body) mutable { + return agent->get_filament_spools(params, &response_body); + }, + std::move(on_ok), + std::move(on_err)); +} + +void wgtFilaManagerCloudClient::get_filament_config(SuccessFn on_ok, ErrorFn on_err) +{ + if (!check_login(on_err)) + return; + + dispatch_agent_request("get_filament_config", + {{"method", "GET"}}, + [](NetworkAgent* agent, std::string& response_body) { + return agent->get_filament_config(&response_body); + }, + std::move(on_ok), + std::move(on_err)); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.h b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.h new file mode 100644 index 0000000000..c33dcb7444 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudClient.h @@ -0,0 +1,40 @@ +#ifndef slic3r_wgtFilaManagerCloudClient_h_ +#define slic3r_wgtFilaManagerCloudClient_h_ + +#include +#include +#include +#include "nlohmann/json.hpp" + +namespace Slic3r { namespace GUI { + +class wgtFilaManagerCloudClient { +public: + using SuccessFn = std::function; + using ErrorFn = std::function; + + wgtFilaManagerCloudClient() = default; + ~wgtFilaManagerCloudClient() = default; + + // POST /my/filament/v2 + void create_spool(const nlohmann::json& body, SuccessFn on_ok, ErrorFn on_err); + + // PUT /my/filament/v2/:id + void update_spool(const std::string& id, const nlohmann::json& body, SuccessFn on_ok, ErrorFn on_err); + + // DELETE /my/filament/v2/batch + void batch_delete(const nlohmann::json& body, SuccessFn on_ok, ErrorFn on_err); + + // GET /my/filament/v2 + void list_spools(const std::map& query, SuccessFn on_ok, ErrorFn on_err); + + // GET /filament/config (no auth required) + void get_filament_config(SuccessFn on_ok, ErrorFn on_err); + +private: + bool check_login(ErrorFn& on_err) const; +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_wgtFilaManagerCloudClient_h_ diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.cpp b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.cpp new file mode 100644 index 0000000000..e1d549f530 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.cpp @@ -0,0 +1,480 @@ +#include "wgtFilaManagerCloudDispatcher.h" + +#include "wgtFilaManagerCloudClient.h" +#include "wgtFilaManagerCloudSync.h" +#include "wgtFilaManagerStore.h" + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/Utils/NetworkAgent.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +namespace Slic3r { namespace GUI { + +namespace { + +// ISO-8601 UTC timestamp: "2026-04-17T10:23:45Z". +std::string now_iso_utc() +{ + using namespace std::chrono; + auto t = system_clock::to_time_t(system_clock::now()); + std::tm tm{}; +#ifdef _WIN32 + gmtime_s(&tm, &t); +#else + gmtime_r(&t, &tm); +#endif + std::ostringstream os; + os << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ"); + return os.str(); +} + +bool is_user_logged_in() +{ + NetworkAgent* agent = wxGetApp().getAgent(); + return agent && agent->is_user_login(); +} + +std::string cloud_spool_id_from_response(const nlohmann::json& resp) +{ + auto read_id = [](const nlohmann::json& obj) -> std::string { + if (!obj.is_object()) return {}; + if (!obj.contains("id")) return {}; + const auto& id = obj["id"]; + if (id.is_string()) return id.get(); + if (id.is_number_integer()) return std::to_string(id.get()); + if (id.is_number_unsigned()) return std::to_string(id.get()); + return {}; + }; + + if (auto id = read_id(resp); !id.empty()) return id; + if (resp.contains("data")) { + if (auto id = read_id(resp["data"]); !id.empty()) return id; + } + return {}; +} + +} // namespace + +// --------------------------------------------------------------------------- +// ctor +// --------------------------------------------------------------------------- + +wgtFilaManagerCloudDispatcher::wgtFilaManagerCloudDispatcher( + wgtFilaManagerCloudSync* sync, + wgtFilaManagerCloudClient* client) + : m_sync(sync) + , m_client(client) +{} + +// --------------------------------------------------------------------------- +// Public entry points (UI thread) +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudDispatcher::enqueue_pull() +{ + if (m_pulling) { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] enqueue_pull skipped: already pulling"; + return; + } + // STUDIO-17956: a batch add of N spools fires N push_done callbacks, + // each of which enqueues a reconciliation pull. Without this check the + // dispatcher would run `list_spools` N times in a row (the first pull + // already gets all the fresh data, the rest are wasted HTTP calls and + // produce duplicate "+0 added, M up-to-date" toasts). Skip when a pull + // is already waiting in the queue; run_pull_op() clears the flag when + // the pending pull starts. + if (m_pending_pull_queued) { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] enqueue_pull skipped: pull already queued"; + return; + } + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher enqueue pull", + "A cloud pull operation was queued", + nlohmann::json::object()); + m_pending_pull_queued = true; + m_queue.push_back([this]() { run_pull_op(); }); + schedule_next(); +} + +void wgtFilaManagerCloudDispatcher::enqueue_push_create(const FilamentSpool& spool) +{ + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher enqueue push_create", + "A create push operation was queued", + {{"setting_id", spool.setting_id}}); + m_queue.push_back([this, spool]() { run_push_create_op(spool); }); + schedule_next(); +} + +void wgtFilaManagerCloudDispatcher::enqueue_push_update(const std::string& spool_id, + const nlohmann::json& local_patch) +{ + if (spool_id.empty()) return; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher enqueue push_update", + "An update push operation was queued", + {{"spool_id", spool_id}, + {"patch_keys", local_patch.is_object() ? + static_cast(local_patch.size()) : 0}}); + nlohmann::json patch_copy = local_patch.is_object() ? local_patch : nlohmann::json::object(); + m_queue.push_back([this, spool_id, patch_copy]() { + run_push_update_op(spool_id, patch_copy); + }); + schedule_next(); +} + +void wgtFilaManagerCloudDispatcher::enqueue_push_delete(const std::vector& spool_ids) +{ + if (spool_ids.empty()) return; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher enqueue push_delete", + "A delete push operation was queued", + {{"spool_ids", spool_ids}, {"count", static_cast(spool_ids.size())}}); + m_queue.push_back([this, spool_ids]() { run_push_delete_op(spool_ids); }); + schedule_next(); +} + +void wgtFilaManagerCloudDispatcher::clear_pending() +{ + // Keep the in-flight op running; caller is responsible for ignoring its + // eventual outcome via observer state. + const size_t n = m_queue.size(); + m_queue.clear(); + // Any pending pull we were holding was just dropped; allow future + // enqueue_pull() calls to queue a fresh one again. + m_pending_pull_queued = false; + if (n > 0) { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] clear_pending dropped " << n << " op(s)"; + } +} + +// --------------------------------------------------------------------------- +// Scheduling +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudDispatcher::schedule_next() +{ + if (m_busy) return; + if (m_queue.empty()) return; + + Op op = std::move(m_queue.front()); + m_queue.pop_front(); + + m_busy = true; + notify_state(); + + // Run the op; each op is expected to call on_op_done() via CallAfter from + // its Success / Error callback. + op(); +} + +void wgtFilaManagerCloudDispatcher::on_op_done() +{ + m_busy = false; + m_pulling = false; + notify_state(); + schedule_next(); +} + +// --------------------------------------------------------------------------- +// Ops +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudDispatcher::run_pull_op() +{ + // Clear the "queue already has a pending pull" guard as soon as we pop + // the pull off the queue, so a new enqueue_pull() during this run (e.g. + // a later push_done) can schedule the next pull instead of being dropped. + m_pending_pull_queued = false; + + if (!m_sync) { + on_op_done(); + return; + } + if (!is_user_logged_in()) { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] pull skipped: not logged in"; + on_op_done(); + return; + } + + m_pulling = true; + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] pull started"; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher pull started", + "Queued pull operation started running", + nlohmann::json::object()); + + // wgtFilaManagerCloudSync::pull_from_cloud runs list_spools internally and + // merges into the Store on the UI thread. We don't know added/updated + // counts from it directly; use snapshot before/after to estimate. + auto* store_before = wxGetApp().fila_manager_store(); + size_t before_sz = store_before ? store_before->spools_to_json().size() : 0; + + m_sync->pull_from_cloud(); + + // pull_from_cloud completes asynchronously and is not observable here; + // poll on the sync object's is_syncing() via CallAfter loop. Simpler: + // mark pulling complete after a short settle delay and publish pull_done. + // NOTE: this is a best-effort; CloudSync schedules CallAfter internally, + // so we wait until is_syncing() returns false on the UI thread. + auto check = std::make_shared>(); + *check = [this, check, before_sz]() { + if (m_sync && m_sync->is_syncing()) { + wxTheApp->CallAfter(*check); + return; + } + if (m_sync && m_sync->last_pull_succeeded()) { + update_last_synced_now(); + auto* store_after = wxGetApp().fila_manager_store(); + size_t after_sz = store_after ? store_after->spools_to_json().size() : 0; + int added_estimate = after_sz > before_sz ? static_cast(after_sz - before_sz) : 0; + int updated_estimate = static_cast(std::min(before_sz, after_sz)); + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] pull done, size " << before_sz << " -> " << after_sz; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher pull finished", + "Queued pull operation completed", + {{"before", static_cast(before_sz)}, + {"after", static_cast(after_sz)}, + {"added", added_estimate}, + {"updated", updated_estimate}}); + if (m_on_pull) m_on_pull(added_estimate, updated_estimate); + } else if (m_sync) { + record_error(m_sync->last_pull_error_code(), m_sync->last_pull_error_message()); + wxGetApp().emit_fila_debug_log("data", "error", "Dispatcher pull finished with error", + "Queued pull operation completed with failure state", + {{"code", m_sync->last_pull_error_code()}, + {"error", m_sync->last_pull_error_message()}}); + } + on_op_done(); + }; + wxTheApp->CallAfter(*check); +} + +void wgtFilaManagerCloudDispatcher::run_push_create_op(const FilamentSpool& spool) +{ + if (!m_sync || !is_user_logged_in()) { + if (m_sync && !is_user_logged_in()) { + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_create skipped", + "User not logged in — no cloud HTTP", + {{"op", "create"}}); + } + on_op_done(); + return; + } + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_create"; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_create started", + "Queued create push started running", + {{"setting_id", spool.setting_id}}); + if (!m_client) { on_op_done(); return; } + + nlohmann::json body = wgtFilaManagerCloudSync::spool_to_cloud_json(spool); + m_client->create_spool(body, + [this, spool](const nlohmann::json& resp) { + wxTheApp->CallAfter([this, spool, resp]() { + const std::string spool_id = cloud_spool_id_from_response(resp); + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_create ok " << spool_id; + if (!spool_id.empty()) { + if (auto* store = wxGetApp().fila_manager_store()) { + FilamentSpool local = spool; + local.spool_id = spool_id; + local.cloud_synced = true; + store->add_spool(local); + store->save(); + } + } + update_last_synced_now(); + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_create finished", + "Queued create push completed successfully", + {{"spool_id", spool_id}}); + if (m_on_push_done) m_on_push_done(spool_id, "create"); + on_op_done(); + }); + }, + [this](int code, const std::string& err) { + wxTheApp->CallAfter([this, code, err]() { + record_error(code, err); + wxGetApp().emit_fila_debug_log("data", "error", "Dispatcher push_create failed", + "Queued create push failed", + {{"code", code}, {"error", err}}); + if (m_on_push_failed) m_on_push_failed(std::string(), "create", code, err); + on_op_done(); + }); + }); +} + +void wgtFilaManagerCloudDispatcher::run_push_update_op(const std::string& spool_id, + const nlohmann::json& local_patch) +{ + if (!m_sync || !is_user_logged_in()) { + if (m_sync && !is_user_logged_in()) { + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_update skipped", + "User not logged in — no cloud HTTP", + {{"spool_id", spool_id}, {"op", "update"}}); + } + on_op_done(); + return; + } + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_update " << spool_id; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_update started", + "Queued update push started running", + {{"spool_id", spool_id}}); + auto* store = wxGetApp().fila_manager_store(); + if (!store) { on_op_done(); return; } + const FilamentSpool* spool = store->get_spool(spool_id); + if (!spool || !m_client) { on_op_done(); return; } + + // Update 走 patch 白名单并补齐 update 端必需字段;404 fallback 才用到全量 create body。 + nlohmann::json body = wgtFilaManagerCloudSync::spool_to_cloud_update_json(*spool, local_patch); + nlohmann::json create_body = wgtFilaManagerCloudSync::spool_to_cloud_json(*spool); + + if (body.empty()) { + // patch 里没有任何云端认识的字段(比如用户只改了 favorite 这种仅本地字段) + // — 不打扰云端,直接把本条标记已同步即可。 + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_update skipped (empty cloud patch) " << spool_id; + if (store->mark_synced(spool_id, true)) store->save(); + update_last_synced_now(); + if (m_on_push_done) m_on_push_done(spool_id, "update"); + on_op_done(); + return; + } + + m_client->update_spool(spool_id, body, + [this, spool_id, local_patch](const nlohmann::json& /*resp*/) { + wxTheApp->CallAfter([this, spool_id, local_patch]() { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_update ok " << spool_id; + if (auto* store = wxGetApp().fila_manager_store()) { + store->apply_patch(spool_id, local_patch); + if (store->mark_synced(spool_id, true)) + store->save(); + else + store->save(); + } + update_last_synced_now(); + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_update finished", + "Queued update push completed successfully", + {{"spool_id", spool_id}}); + if (m_on_push_done) m_on_push_done(spool_id, "update"); + on_op_done(); + }); + }, + [this, spool_id, create_body](int code, const std::string& err) { + if (code == 404) { + // Fallback to create for the common "cloud has no record of + // this local spool yet" case (e.g. the local row was created + // while offline and the first update is effectively a create). + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_update 404, fallback create " << spool_id; + m_client->create_spool(create_body, + [this, spool_id](const nlohmann::json&) { + wxTheApp->CallAfter([this, spool_id]() { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_update fallback create ok " << spool_id; + if (auto* store = wxGetApp().fila_manager_store()) { + if (store->mark_synced(spool_id, true)) + store->save(); + } + update_last_synced_now(); + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_update fallback create finished", + "Update push fell back to create and completed successfully", + {{"spool_id", spool_id}}); + if (m_on_push_done) m_on_push_done(spool_id, "update"); + on_op_done(); + }); + }, + [this, spool_id](int c, const std::string& e) { + wxTheApp->CallAfter([this, spool_id, c, e]() { + record_error(c, e); + wxGetApp().emit_fila_debug_log("data", "error", "Dispatcher push_update fallback create failed", + "Update push fell back to create but still failed", + {{"spool_id", spool_id}, {"code", c}, {"error", e}}); + if (m_on_push_failed) m_on_push_failed(spool_id, "create", c, e); + on_op_done(); + }); + }); + return; + } + wxTheApp->CallAfter([this, spool_id, code, err]() { + record_error(code, err); + wxGetApp().emit_fila_debug_log("data", "error", "Dispatcher push_update failed", + "Queued update push failed", + {{"spool_id", spool_id}, {"code", code}, {"error", err}}); + if (m_on_push_failed) m_on_push_failed(spool_id, "update", code, err); + on_op_done(); + }); + }); +} + +void wgtFilaManagerCloudDispatcher::run_push_delete_op(const std::vector& spool_ids) +{ + if (!m_sync || !is_user_logged_in() || !m_client) { + if (m_sync && m_client && !is_user_logged_in() && !spool_ids.empty()) { + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_delete skipped", + "User not logged in — local delete kept, no cloud HTTP", + {{"spool_ids", spool_ids}, {"count", static_cast(spool_ids.size())}}); + } + on_op_done(); + return; + } + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_delete (" << spool_ids.size() << ")"; + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_delete started", + "Queued delete push started running", + {{"spool_ids", spool_ids}, {"count", static_cast(spool_ids.size())}}); + nlohmann::json body; + body["ids"] = spool_ids; + + // Capture first id as representative for error reports. + std::string rep = spool_ids.empty() ? std::string() : spool_ids.front(); + + m_client->batch_delete(body, + [this, spool_ids](const nlohmann::json& /*resp*/) { + wxTheApp->CallAfter([this, spool_ids]() { + BOOST_LOG_TRIVIAL(info) << "[CloudDispatcher] push_delete ok"; + if (auto* store = wxGetApp().fila_manager_store()) { + for (const auto& spool_id : spool_ids) + store->remove_spool(spool_id); + store->save(); + } + update_last_synced_now(); + wxGetApp().emit_fila_debug_log("data", "info", "Dispatcher push_delete finished", + "Queued delete push completed successfully", + {{"spool_ids", spool_ids}, + {"count", static_cast(spool_ids.size())}}); + if (m_on_push_done) m_on_push_done(std::string(), "delete"); + on_op_done(); + }); + }, + [this, rep](int code, const std::string& err) { + wxTheApp->CallAfter([this, rep, code, err]() { + record_error(code, err); + wxGetApp().emit_fila_debug_log("data", "error", "Dispatcher push_delete failed", + "Queued delete push failed", + {{"spool_id", rep}, {"code", code}, {"error", err}}); + if (m_on_push_failed) m_on_push_failed(rep, "delete", code, err); + on_op_done(); + }); + }); +} + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudDispatcher::update_last_synced_now() +{ + m_last_synced_at = now_iso_utc(); + m_last_error_code = 0; + m_last_error_message.clear(); +} + +void wgtFilaManagerCloudDispatcher::record_error(int code, const std::string& msg) +{ + m_last_error_code = code; + m_last_error_message = msg; +} + +void wgtFilaManagerCloudDispatcher::notify_state() +{ + if (m_on_state) m_on_state(); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.h b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.h new file mode 100644 index 0000000000..bd99c3637c --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudDispatcher.h @@ -0,0 +1,114 @@ +#ifndef slic3r_wgtFilaManagerCloudDispatcher_h_ +#define slic3r_wgtFilaManagerCloudDispatcher_h_ + +#include +#include +#include +#include +#include "nlohmann/json.hpp" + +namespace Slic3r { namespace GUI { + +class wgtFilaManagerCloudSync; +class wgtFilaManagerCloudClient; +struct FilamentSpool; + +// Single-slot dispatcher that serializes pull / push calls on top of +// wgtFilaManagerCloudSync. All public methods must be called on the UI thread. +// Completion signalling is the caller's responsibility: each op ultimately +// calls on_op_done() via CallAfter once its success/error callback returns. +class wgtFilaManagerCloudDispatcher { +public: + // Observer callbacks are invoked on the UI thread. + using StateChangedFn = std::function; // syncing status toggled + using PullDoneFn = std::function; + using PushFailedFn = std::function; + // Fires on the UI thread after a successful push_create / push_update + // has been acknowledged by the cloud and the local store's cloud_synced + // flag has already been flipped to true. Useful for observers that want + // to rebroadcast the spool list so the UI can re-render sync dots. + using PushDoneFn = std::function; + + wgtFilaManagerCloudDispatcher(wgtFilaManagerCloudSync* sync, + wgtFilaManagerCloudClient* client); + ~wgtFilaManagerCloudDispatcher() = default; + + // Observer hookup. Pass nullptr to clear. + void set_on_state_changed(StateChangedFn fn) { m_on_state = std::move(fn); } + void set_on_pull_done(PullDoneFn fn) { m_on_pull = std::move(fn); } + void set_on_push_failed(PushFailedFn fn) { m_on_push_failed = std::move(fn); } + void set_on_push_done(PushDoneFn fn) { m_on_push_done = std::move(fn); } + + // --- Queue entry points (UI thread) ------------------------------------- + + // Trigger a full pull from cloud. If already syncing, no-op. + void enqueue_pull(); + + // Push a single spool create body. Local store is updated only after the + // cloud accepts the operation and the follow-up pull reconciles the list. + void enqueue_push_create(const FilamentSpool& spool); + // Push a single spool id (update, with 404 fallback to create). + // `local_patch` carries the fields the user actually edited this time + // (local schema names); Cloud only receives whitelisted/changed fields. + void enqueue_push_update(const std::string& spool_id, + const nlohmann::json& local_patch); + // Push a batch delete for multiple spool ids. + void enqueue_push_delete(const std::vector& spool_ids); + + // Clear any not-yet-started push ops. Does not cancel the in-flight op. + void clear_pending(); + + // Observable state. + bool is_busy() const { return m_busy; } + bool is_pulling() const { return m_pulling; } + std::string last_synced_at() const { return m_last_synced_at; } + int last_error_code() const { return m_last_error_code; } + std::string last_error_message() const { return m_last_error_message; } + +private: + using Op = std::function; + + void schedule_next(); // UI thread + void on_op_done(); // UI thread, dispatched via CallAfter from callbacks + + void run_pull_op(); + void run_push_create_op(const FilamentSpool& spool); + void run_push_update_op(const std::string& spool_id, + const nlohmann::json& local_patch); + void run_push_delete_op(const std::vector& spool_ids); + + void update_last_synced_now(); + void record_error(int code, const std::string& msg); + void notify_state(); + + wgtFilaManagerCloudSync* m_sync = nullptr; + wgtFilaManagerCloudClient* m_client = nullptr; + + std::deque m_queue; + bool m_busy = false; + bool m_pulling = false; + // STUDIO-17956: collapse redundant post-push reconciliation pulls. Each + // push_done (batch add 5 spools -> 5 push_done callbacks) enqueues a pull + // for "cloud is source of truth", but the single-slot dispatcher would + // then run pull 5 times. We only need one. This flag is true while a + // not-yet-started pull sits in m_queue; additional enqueue_pull() calls + // are skipped until run_pull_op() pops it off and clears the flag. + bool m_pending_pull_queued = false; + + std::string m_last_synced_at; + int m_last_error_code = 0; + std::string m_last_error_message; + + StateChangedFn m_on_state; + PullDoneFn m_on_pull; + PushFailedFn m_on_push_failed; + PushDoneFn m_on_push_done; +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_wgtFilaManagerCloudDispatcher_h_ diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.cpp b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.cpp new file mode 100644 index 0000000000..1d7f759e3c --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.cpp @@ -0,0 +1,530 @@ +#include "wgtFilaManagerCloudSync.h" +#include "wgtFilaManagerCloudClient.h" +#include "wgtFilaManagerStore.h" + +#include "slic3r/Utils/NetworkAgent.hpp" +#include "slic3r/GUI/GUI_App.hpp" + +#include +#include +#include + +namespace Slic3r { namespace GUI { + +namespace { + +nlohmann::json extract_cloud_list(const nlohmann::json& data) +{ + if (data.contains("hits") && data["hits"].is_array()) + return data["hits"]; + if (data.is_array()) + return data; + if (data.contains("data")) { + const auto& d = data["data"]; + if (d.is_array()) + return d; + if (d.is_object() && d.contains("hits") && d["hits"].is_array()) + return d["hits"]; + } + if (data.contains("filaments") && data["filaments"].is_array()) + return data["filaments"]; + return nlohmann::json::array(); +} + +// Cloud error callbacks hand us the raw HTTP response body in `err` (see +// wgtFilaManagerCloudClient: `response_body.empty() ? "network request failed" +// : response_body`). That body can carry user-scoped or server-internal +// context, so we only append it to the shipped BambuStudio.log in internal +// builds; external builds keep just the HTTP return code. +inline std::string err_body_tail(const std::string& err) +{ +#if !BBL_RELEASE_TO_PUBLIC + return " " + err; +#else + (void)err; + return std::string(); +#endif +} + +} // namespace + +wgtFilaManagerCloudSync::wgtFilaManagerCloudSync( + wgtFilaManagerStore* store, wgtFilaManagerCloudClient* client) + : m_store(store) + , m_client(client) +{} + +// --------------------------------------------------------------------------- +// Data conversion helpers +// --------------------------------------------------------------------------- + +FilamentSpool wgtFilaManagerCloudSync::cloud_json_to_spool(const nlohmann::json& j) +{ + FilamentSpool s; + + // Accept both cloud camelCase and legacy snake_case keys. Cloud wins when + // both are present. + auto str_any = [&](std::initializer_list keys) -> std::string { + for (const char* key : keys) { + if (!j.contains(key)) continue; + const auto& v = j[key]; + if (v.is_null()) continue; + if (v.is_string()) return v.get(); + if (v.is_number_integer()) return std::to_string(v.get()); + if (v.is_number_unsigned()) return std::to_string(v.get()); + if (v.is_number_float()) return std::to_string(v.get()); + if (v.is_boolean()) return v.get() ? "true" : "false"; + } + return {}; + }; + auto num_f_any = [&](std::initializer_list keys, float def = 0.f) -> float { + for (const char* key : keys) { + if (!j.contains(key)) continue; + const auto& v = j[key]; + if (v.is_null()) continue; + if (v.is_number()) return v.get(); + } + return def; + }; + auto num_i_any = [&](std::initializer_list keys, int def = 0) -> int { + for (const char* key : keys) { + if (!j.contains(key)) continue; + const auto& v = j[key]; + if (v.is_null()) continue; + if (v.is_number()) return v.get(); + } + return def; + }; + + // Identity / preset linkage (cloud FilamentV2 uses int64 id + camelCase). + s.spool_id = str_any({"id", "spool_id"}); + s.setting_id = str_any({"filamentId", "setting_id"}); + s.tag_uid = str_any({"RFID", "rfid", "tag_uid"}); + + // Descriptive fields. + s.brand = str_any({"filamentVendor", "brand"}); + s.material_type = str_any({"filamentType", "material_type"}); + s.series = str_any({"filamentName", "series"}); + s.color_code = str_any({"color", "color_code"}); + s.color_name = str_any({"color_name"}); // cloud has no direct counterpart + + s.diameter = num_f_any({"diameter"}, 1.75f); + + // Weights: cloud uses totalNetWeight / netWeight (nullable int64 grams). + s.initial_weight = num_f_any({"totalNetWeight", "initial_weight"}); + s.net_weight = num_f_any({"netWeight", "net_weight"}); + s.spool_weight = num_f_any({"spool_weight"}); + + // remain_percent is not provided by cloud; derive from weights when we can, + // otherwise honor any locally-provided value (+0.5f for simple rounding). + if (s.initial_weight > 0.f && s.net_weight >= 0.f) { + float pct = s.net_weight / s.initial_weight * 100.0f; + if (pct < 0.f) pct = 0.f; + if (pct > 100.f) pct = 100.f; + s.remain_percent = static_cast(pct + 0.5f); + } else { + s.remain_percent = num_i_any({"remain_percent"}, 100); + } + + // Cloud status is int64: 0=active, 1=info_needed. Legacy payloads may send + // the string directly. + if (j.contains("status")) { + const auto& v = j["status"]; + if (v.is_number_integer()) { + s.status = (v.get() == 1) ? "info_needed" : "active"; + } else if (v.is_string()) { + s.status = v.get(); + } + } + if (s.status.empty()) s.status = "active"; + + // Cloud uses "manual" | "ams"; the local UI still distinguishes AMS-origin + // entries with the legacy "ams_sync" marker. + s.entry_method = str_any({"createType", "entry_method"}); + if (s.entry_method == "ams") + s.entry_method = "ams_sync"; + + // createdAt / updatedAt are unix seconds (int64) on the cloud. Keep them + // stringified so the local schema and on-disk cache don't need to change. + s.created_at = str_any({"createdAt", "created_at"}); + s.updated_at = str_any({"updatedAt", "updated_at"}); + + s.bound_dev_id = str_any({"bound_dev_id"}); + s.bound_ams_id = str_any({"trayIdName", "bound_ams_id"}); + s.note = str_any({"note"}); + + s.favorite = j.contains("favorite") && j["favorite"].is_boolean() && j["favorite"].get(); + + return s; +} + +nlohmann::json wgtFilaManagerCloudSync::spool_to_cloud_json(const FilamentSpool& s) +{ + // Cloud CreateFilamentV2Req / UpdateFilamentV2Req schema (camelCase). + nlohmann::json j; + + // createType: "manual" (手动) | "ams" (AMS 自动). Normalize legacy value + // "ams_sync" that the old local format used. + std::string create_type = s.entry_method; + if (create_type == "ams_sync") create_type = "ams"; + if (create_type == "rfid") create_type = "ams"; + if (create_type.empty()) create_type = "manual"; + j["createType"] = create_type; + + j["filamentVendor"] = s.brand; + j["filamentType"] = s.material_type; + // Swagger marks filamentName / colorType as required. Manual add currently + // models only a single-colour spool and may leave `series` empty, so fall + // back to the material type for the display name and encode monochrome as 2. + j["filamentName"] = s.series.empty() ? s.material_type : s.series; + j["filamentId"] = s.setting_id; + j["isSupport"] = false; // local schema has no equivalent yet + if (!s.tag_uid.empty()) + j["RFID"] = s.tag_uid; + j["color"] = s.color_code; + j["colorType"] = 2; // 2 = 单色, per CreateFilamentV2Req swagger + if (create_type == "ams" && !s.bound_ams_id.empty()) { + j["trayIdName"] = s.bound_ams_id; + j["rolls"] = 1; + } + + // Cloud schema (CreateFilamentV2Req): netWeight = 当前净重 (current + // material remaining), totalNetWeight = 整卷净重 (the spool's full + // net weight when new). After STUDIO-17991 the local store keeps both + // in net-weight units with spool_weight==0, so initial_weight is the + // pure 整卷净重 and maps verbatim onto totalNetWeight. Legacy rows + // still in the 毛重/料盘 shape (spool_weight > 0, initial_weight = 毛重) + // collapse "initial - spool" to recover the 整卷净重 the cloud expects. + // + // STUDIO-18115: previously the manual branch mirrored totalNetWeight + // from material_weight, which silently truncated the user-entered + // 总净重 to the 当前净重 whenever the two differed (e.g. 当前=200, + // 总=1500 was pushed as netWeight=200, totalNetWeight=200 and the + // row came back from cloud showing 200/200 instead of 200/1500). + const float material_weight = s.net_weight > 0.f + ? s.net_weight + : ((s.initial_weight > s.spool_weight) ? (s.initial_weight - s.spool_weight) : 0.f); + const float total_net_weight = (s.spool_weight > 0.f && s.initial_weight > s.spool_weight) + ? (s.initial_weight - s.spool_weight) + : s.initial_weight; + if (material_weight > 0.f) + j["netWeight"] = static_cast(material_weight + 0.5f); + if (total_net_weight > 0.f) + j["totalNetWeight"] = static_cast(total_net_weight + 0.5f); + + if (!s.note.empty()) + j["note"] = s.note; + + return j; +} + +// --------------------------------------------------------------------------- +// Pull: cloud → local +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudSync::pull_from_cloud() +{ + if (m_syncing) return; + + NetworkAgent* agent = wxGetApp().getAgent(); + if (!agent || !agent->is_user_login()) return; + + m_syncing = true; + m_last_pull_succeeded = false; + m_last_pull_error_code = 0; + m_last_pull_error_message.clear(); + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] pull_from_cloud started"; + wxGetApp().emit_fila_debug_log("data", "info", "Cloud pull started", + "Starting pull_from_cloud merge", + nlohmann::json::object()); + + m_client->list_spools({}, + [this](const nlohmann::json& data) { + wxTheApp->CallAfter([this, data]() { + try { + // Cloud ListFilamentV2Resp returns { total, hits: [...] } + // at the root; tolerate a few alternative shapes for + // forward/backward compatibility. + nlohmann::json list = extract_cloud_list(data); + + // Cloud is the source of truth: collect every cloud id we + // are about to keep, then rewrite the local store to match + // exactly that set. Local-only entries (e.g. pushes that + // never succeeded) are dropped on purpose so a pull always + // leaves the local list in sync with the latest cloud + // snapshot. + std::set cloud_ids; + int dropped_local_only = 0; + + for (const auto& item : list) { + FilamentSpool spool = cloud_json_to_spool(item); + if (spool.spool_id.empty()) continue; + spool.cloud_synced = true; + cloud_ids.insert(spool.spool_id); + + if (m_store->get_spool(spool.spool_id)) + m_store->update_spool(spool); + else + m_store->add_spool(spool); + } + + for (const auto& existing : m_store->spools_to_json()) { + const std::string existing_id = existing.value("spool_id", ""); + if (existing_id.empty()) continue; + if (cloud_ids.count(existing_id) == 0) { + m_store->remove_spool(existing_id); + ++dropped_local_only; + } + } + + m_store->save(); + m_last_pull_succeeded = true; + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] pull_from_cloud completed, " + << list.size() << " items kept, " + << dropped_local_only << " local-only entries dropped"; + wxGetApp().emit_fila_debug_log("data", "info", "Cloud pull merged", + "Cloud pull overwrote local store", + {{"count", static_cast(list.size())}, + {"dropped_local_only", dropped_local_only}}); + } catch (const std::exception& e) { + m_last_pull_succeeded = false; + m_last_pull_error_code = -1; + m_last_pull_error_message = e.what(); + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] pull_from_cloud merge error: " << e.what(); + wxGetApp().emit_fila_debug_log("data", "error", "Cloud pull merge error", + "Merging cloud pull result into local store failed", + {{"error", e.what()}}); + } + m_syncing = false; + }); + }, + [this](int code, const std::string& err) { + wxTheApp->CallAfter([this, code, err]() { + m_last_pull_succeeded = false; + m_last_pull_error_code = code; + m_last_pull_error_message = err; + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] pull_from_cloud failed: " << code << err_body_tail(err); + wxGetApp().emit_fila_debug_log("http", "error", "Cloud pull failed", + "list_spools failed during pull_from_cloud", + {{"code", code}, {"error", err}}); + m_syncing = false; + }); + }); +} + +// --------------------------------------------------------------------------- +// Push: local → cloud +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudSync::push_spool_to_cloud(const std::string& spool_id) +{ + const FilamentSpool* spool = m_store->get_spool(spool_id); + if (!spool) return; + + nlohmann::json body = spool_to_cloud_json(*spool); + + m_client->create_spool(body, + [spool_id](const nlohmann::json& /*resp*/) { + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] push_spool_to_cloud ok: " << spool_id; + }, + [spool_id](int code, const std::string& err) { + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] push_spool_to_cloud failed (" + << spool_id << "): " << code << err_body_tail(err); + }); +} + +nlohmann::json wgtFilaManagerCloudSync::spool_to_cloud_update_patch(const nlohmann::json& p) +{ + // UpdateFilamentV2Req(swagger 权威定义,设计于 design-user.api / design-user-swagger.json): + // id int64 required ← 由 client 负责塞入,本函数不处理 + // filamentVendor string optional + // filamentType string optional + // filamentName string optional + // filamentId string optional + // isSupport bool optional + // color string optional + // colorType int64 optional 0=渐变 / 1=拼色 / 2=单色 + // colors []string optional + // netWeight int64 optional + // totalNetWeight int64 optional + // note string optional + // + // 规则:只输出 swagger 白名单字段;本地 patch 里未出现或 null 的字段不发, + // 服务端"只更新提供的字段"。系统专属字段(createType / RFID / trayIdName / + // rolls 等 Create/AmsSync 专属)严禁出现在 Update body,否则 go-zero 严格 + // 校验会把请求打回 400(对应到本地 circuit breaker 就是 -29 internal blocking)。 + nlohmann::json j = nlohmann::json::object(); + if (!p.is_object()) return j; + + auto take_str = [&](const char* local_key, const char* cloud_key) { + if (!p.contains(local_key)) return; + const auto& v = p.at(local_key); + if (v.is_null()) return; + if (v.is_string()) j[cloud_key] = v.get(); + }; + auto take_int = [&](const char* local_key, const char* cloud_key) { + if (!p.contains(local_key)) return; + const auto& v = p.at(local_key); + if (v.is_null()) return; + if (v.is_number()) + j[cloud_key] = static_cast(v.get() + 0.5); + }; + auto take_bool = [&](const char* local_key, const char* cloud_key) { + if (!p.contains(local_key)) return; + const auto& v = p.at(local_key); + if (v.is_null()) return; + if (v.is_boolean()) j[cloud_key] = v.get(); + }; + + // 本地字段 → swagger 字段(只映射本地有对应概念的那些): + take_str("brand", "filamentVendor"); + take_str("material_type", "filamentType"); + take_str("series", "filamentName"); // UI 的 Material Type 实际对应云端 filamentName + take_str("filament_name", "filamentName"); // 兼容未来显式字段 + take_str("setting_id", "filamentId"); + take_bool("is_support", "isSupport"); // 同上 + take_str("color_code", "color"); + take_int("color_type", "colorType"); // 同上 + // colors[] 目前本地没有拼/渐变色概念,若前端 patch 里主动带 colors 数组就透传。 + if (p.contains("colors") && p.at("colors").is_array()) + j["colors"] = p.at("colors"); + take_int("net_weight", "netWeight"); + take_int("total_net_weight","totalNetWeight"); + take_str("note", "note"); + + // swagger 白名单之外的常见本地字段(series / color_name / initial_weight / + // spool_weight / diameter / status / remain_percent / favorite ...)不映射, + // 它们只存在于本地 store,不上报给云端 Update 接口。 + + return j; +} + +nlohmann::json wgtFilaManagerCloudSync::spool_to_cloud_update_json(const FilamentSpool& s, + const nlohmann::json& local_patch) +{ + nlohmann::json j = spool_to_cloud_update_patch(local_patch); + if (j.empty()) + return j; + + auto patch_str = [&](const char* key) -> std::string { + if (!local_patch.is_object() || !local_patch.contains(key)) return {}; + const auto& v = local_patch.at(key); + return v.is_string() ? v.get() : std::string(); + }; + + // Edit requests must include filamentName even when the user only changes + // color/weight/note. The visible "Material Type" field is cloud + // filamentName, stored locally as `series`; filamentType is hidden. + if (!j.contains("filamentName")) { + std::string filament_name = patch_str("series"); + if (filament_name.empty()) filament_name = patch_str("filament_name"); + if (filament_name.empty()) filament_name = s.series.empty() ? s.material_type : s.series; + j["filamentName"] = filament_name; + } + + return j; +} + +void wgtFilaManagerCloudSync::push_update_to_cloud(const std::string& spool_id, + const nlohmann::json& local_patch) +{ + const FilamentSpool* spool = m_store->get_spool(spool_id); + if (!spool) return; + + nlohmann::json body = spool_to_cloud_update_json(*spool, local_patch); + + // 全量 body 仅用于 404 fallback:服务端没记录这条时补一次 create。 + nlohmann::json create_body = spool_to_cloud_json(*spool); + + if (body.empty()) { + // patch 映射后空:本次没有任何云端认识的变化字段,直接标记已同步即可, + // 不再发空 PUT(有些服务端会拒 0 字段更新)。 + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] push_update_to_cloud skipped (empty patch): " << spool_id; + return; + } + + auto fallback_create = [this, create_body, spool_id]() { + m_client->create_spool(create_body, + [spool_id](const nlohmann::json&) { + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] push_update fallback create ok: " << spool_id; + }, + [spool_id](int c, const std::string& e) { + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] push_update fallback create failed (" + << spool_id << "): " << c << err_body_tail(e); + }); + }; + + m_client->update_spool(spool_id, body, + [spool_id](const nlohmann::json& /*resp*/) { + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] push_update_to_cloud ok: " << spool_id; + }, + [spool_id, fallback_create](int code, const std::string& err) { + if (code == 404) { + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] push_update 404, fallback to create: " << spool_id; + fallback_create(); + } else { + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] push_update_to_cloud failed (" + << spool_id << "): " << code << err_body_tail(err); + } + }); +} + +void wgtFilaManagerCloudSync::push_delete_to_cloud(const std::vector& spool_ids) +{ + if (spool_ids.empty()) return; + + // Cloud BatchDeleteFilamentV2Req uses int64 ids. Convert any numeric-looking + // string ids; anything non-numeric is treated as an RFID fallback, matching + // the other request field defined by the schema. + nlohmann::json body; + nlohmann::json id_array = nlohmann::json::array(); + nlohmann::json rfid_array = nlohmann::json::array(); + for (const std::string& key : spool_ids) { + if (key.empty()) continue; + try { + size_t pos = 0; + int64_t n = std::stoll(key, &pos); + if (pos == key.size()) { + id_array.push_back(n); + continue; + } + } catch (const std::exception&) { + } + rfid_array.push_back(key); + } + if (!id_array.empty()) + body["ids"] = id_array; + if (!rfid_array.empty()) + body["RFIDs"] = rfid_array; + + m_client->batch_delete(body, + [](const nlohmann::json& /*resp*/) { + BOOST_LOG_TRIVIAL(info) << "[FilaCloudSync] push_delete_to_cloud ok"; + }, + [](int code, const std::string& err) { + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] push_delete_to_cloud failed: " << code << err_body_tail(err); + }); +} + +// --------------------------------------------------------------------------- +// Filament config +// --------------------------------------------------------------------------- + +void wgtFilaManagerCloudSync::fetch_filament_config( + std::function on_done) +{ + wxGetApp().emit_fila_debug_log("http", "info", "Cloud config request", + "Requesting filament config from cloud", + nlohmann::json::object()); + m_client->get_filament_config( + [on_done](const nlohmann::json& data) { + wxTheApp->CallAfter([on_done, data]() { + if (on_done) on_done(data); + }); + }, + [](int code, const std::string& err) { + BOOST_LOG_TRIVIAL(error) << "[FilaCloudSync] fetch_filament_config failed: " << code << err_body_tail(err); + }); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.h b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.h new file mode 100644 index 0000000000..ae88723f66 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerCloudSync.h @@ -0,0 +1,55 @@ +#ifndef slic3r_wgtFilaManagerCloudSync_h_ +#define slic3r_wgtFilaManagerCloudSync_h_ + +#include +#include +#include +#include "nlohmann/json.hpp" + +namespace Slic3r { namespace GUI { + +class wgtFilaManagerStore; +class wgtFilaManagerCloudClient; +struct FilamentSpool; + +class wgtFilaManagerCloudSync { +public: + wgtFilaManagerCloudSync(wgtFilaManagerStore* store, wgtFilaManagerCloudClient* client); + ~wgtFilaManagerCloudSync() = default; + + void pull_from_cloud(); + void push_spool_to_cloud(const std::string& spool_id); + // Push a selective update. `local_patch` contains only the fields the user + // actually changed this time (local schema names). Fields outside the cloud + // UpdateFilamentV2 whitelist are dropped silently. + void push_update_to_cloud(const std::string& spool_id, const nlohmann::json& local_patch); + void push_delete_to_cloud(const std::vector& spool_ids); + void fetch_filament_config(std::function on_done); + + bool is_syncing() const { return m_syncing; } + bool last_pull_succeeded() const { return m_last_pull_succeeded; } + int last_pull_error_code() const { return m_last_pull_error_code; } + const std::string& last_pull_error_message() const { return m_last_pull_error_message; } + static nlohmann::json spool_to_cloud_json(const FilamentSpool& spool); + // Translate a local-field patch into a cloud UpdateFilamentV2 body. + // Only whitelisted fields are emitted (filamentVendor/filamentType/ + // filamentName/filamentId/color/colorType/colors/netWeight/ + // totalNetWeight/note). Returns an empty object if nothing maps. + static nlohmann::json spool_to_cloud_update_patch(const nlohmann::json& local_patch); + // Build the actual UpdateFilamentV2 body for an existing spool. This keeps + // update-only required fields out of the create path. + static nlohmann::json spool_to_cloud_update_json(const FilamentSpool& spool, const nlohmann::json& local_patch); + static FilamentSpool cloud_json_to_spool(const nlohmann::json& j); + +private: + wgtFilaManagerStore* m_store; + wgtFilaManagerCloudClient* m_client; + bool m_syncing = false; + bool m_last_pull_succeeded = false; + int m_last_pull_error_code = 0; + std::string m_last_pull_error_message; +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_wgtFilaManagerCloudSync_h_ diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerPanel.cpp b/src/slic3r/GUI/fila_manager/wgtFilaManagerPanel.cpp new file mode 100644 index 0000000000..03a1bed39d --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerPanel.cpp @@ -0,0 +1,501 @@ +#include "wgtFilaManagerPanel.h" +#include "wgtFilaManagerStore.h" + +#include +#include + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Widgets/WebView.hpp" +#include "slic3r/GUI/DeviceCore/DevManager.h" +#include "slic3r/GUI/DeviceCore/DevConfigUtil.h" +#include "slic3r/GUI/DeviceCore/DevExtruderSystem.h" +#include "slic3r/GUI/DeviceCore/DevFilaSystem.h" +#include "slic3r/GUI/DeviceManager.hpp" +#include "libslic3r/Utils.hpp" +#include "libslic3r/PresetBundle.hpp" + +#include +#include + +namespace Slic3r { namespace GUI { + +/* ================================================================ + * Construction / lifecycle + * ================================================================ */ + +wgtFilaManagerPanel::wgtFilaManagerPanel(wxWindow* parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style) + : wxPanel(parent, id, pos, size, style) +{ + wxString strlang = wxGetApp().current_language_code_safe(); + if (!strlang.empty()) + m_home_url = wxString::Format("file://%s/web/fila_manager/index.html?lang=%s", + from_u8(resources_dir()), strlang); + else + m_home_url = wxString::Format("file://%s/web/fila_manager/index.html", + from_u8(resources_dir())); + + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + + m_browser = WebView::CreateWebView(this, m_home_url); + if (m_browser == nullptr) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] Failed to create WebView"; + SetSizer(sizer); + return; + } + +#if !BBL_RELEASE_TO_PUBLIC + m_browser->EnableAccessToDevTools(true); + m_browser->EnableContextMenu(true); +#endif + + sizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); + + m_browser->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, + &wgtFilaManagerPanel::OnWebMsg, this, m_browser->GetId()); + m_browser->Bind(wxEVT_WEBVIEW_LOADED, + [this](wxWebViewEvent&) { InitBridge(); }); + + register_handlers(); + + SetSizer(sizer); + Layout(); + Fit(); +} + +wgtFilaManagerPanel::~wgtFilaManagerPanel() {} + +void wgtFilaManagerPanel::InitBridge() +{ + static const std::string bridge = R"JS( + if (!window.__cppPush) { + window.__cppPush = function(pkt) { + try { + document.dispatchEvent( + new CustomEvent('cpp:fila', { detail: pkt }) + ); + } catch(e) { console.error('[FM] __cppPush error:', e); } + }; + } + )JS"; + + WebView::RunScript(m_browser, wxString(bridge)); + BOOST_LOG_TRIVIAL(info) << "[FilaManager] bridge injected"; + + if (!m_bridge_ready) { + m_bridge_ready = true; + flush_msg_queue(); + } +} + +void wgtFilaManagerPanel::msw_rescale() {} + +void wgtFilaManagerPanel::on_sys_color_changed() +{ + if (m_bridge_ready) { + bool dark = wxGetApp().app_config->get("dark_color_mode") == "1"; + push_to_web("theme_changed", {{"theme", dark ? "dark" : "light"}}); + } +} + +bool wgtFilaManagerPanel::Show(bool show) +{ + if (show && m_bridge_ready) { + auto* store = wxGetApp().fila_manager_store(); + if (store && store->is_dirty()) { + push_to_web("spool_list", build_spool_list()); + store->clear_dirty(); + } + } + return wxPanel::Show(show); +} + +/* ================================================================ + * C++ → JS transport + * ================================================================ */ + +void wgtFilaManagerPanel::SendMsg(nlohmann::json msg) +{ + msg["v"] = FM_PROTOCOL_VERSION; + msg["ts"] = now_ms(); + + std::string js = "window.__cppPush(" + msg.dump() + ");"; + + if (!m_bridge_ready) { + m_msg_queue.push_back(js); + BOOST_LOG_TRIVIAL(info) << "[FilaManager] queued (bridge not ready), queue=" << m_msg_queue.size(); + return; + } + + if (!m_browser) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] SendMsg: m_browser is null"; + return; + } + + CallAfter([this, js] { + if (!m_browser) return; + if (!WebView::RunScript(m_browser, js)) + BOOST_LOG_TRIVIAL(error) << "[FilaManager] SendMsg RunScript failed"; + }); +} + +void wgtFilaManagerPanel::flush_msg_queue() +{ + if (m_msg_queue.empty()) return; + BOOST_LOG_TRIVIAL(info) << "[FilaManager] flushing " << m_msg_queue.size() << " queued messages"; + for (auto& js : m_msg_queue) { + CallAfter([this, js] { + if (!m_browser) return; + WebView::RunScript(m_browser, js); + }); + } + m_msg_queue.clear(); +} + +void wgtFilaManagerPanel::send_response(int seq, int code, const nlohmann::json& data) +{ + BOOST_LOG_TRIVIAL(info) << "[FilaManager] → response seq=" << seq << " code=" << code; + SendMsg({{"type", "response"}, {"seq", seq}, {"code", code}, {"data", data}}); +} + +void wgtFilaManagerPanel::push_to_web(const std::string& command, const nlohmann::json& data) +{ + BOOST_LOG_TRIVIAL(info) << "[FilaManager] → push cmd=" << command; + SendMsg({{"type", "push"}, {"command", command}, {"data", data}}); +} + +/* ================================================================ + * JS → C++ message dispatch + * ================================================================ */ + +void wgtFilaManagerPanel::OnWebMsg(wxWebViewEvent& evt) +{ + try { + // ToStdString() uses the current C locale, which on Windows CJK + // builds mangles non-ASCII characters (Chinese notes, emoji, etc.) + // before the JSON parser sees them. Force UTF-8 to match the + // C++->JS direction (SendMsg builds the script via nlohmann dump + // and needs the request round-trip to stay in UTF-8). + nlohmann::json j = nlohmann::json::parse(evt.GetString().ToUTF8().data()); + std::string type = j.value("type", ""); + + if (type != "request") { + BOOST_LOG_TRIVIAL(warning) << "[FilaManager] unexpected msg type: " << type; + return; + } + + int seq = j.value("seq", 0); + std::string cmd = j.value("command", ""); + nlohmann::json data = j.contains("data") ? j["data"] : nlohmann::json::object(); + BOOST_LOG_TRIVIAL(info) << "[FilaManager] ← request seq=" << seq << " cmd=" << cmd; + + auto it = m_handlers.find(cmd); + if (it != m_handlers.end()) { + try { + it->second(seq, data); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] handler error cmd=" << cmd << ": " << e.what(); + send_response(seq, -1, {{"error", std::string("internal error: ") + e.what()}}); + } + } else { + BOOST_LOG_TRIVIAL(warning) << "[FilaManager] unknown cmd=" << cmd; + send_response(seq, -1, {{"error", "unknown command: " + cmd}}); + } + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] Bad JS message: " << e.what(); + } +} + +/* ================================================================ + * Command registry — each handler is a self-contained lambda + * ================================================================ */ + +void wgtFilaManagerPanel::register_handlers() +{ + m_handlers["init"] = [this](int seq, const nlohmann::json& /*data*/) { + if (!m_bridge_ready) m_bridge_ready = true; + + bool dark = wxGetApp().app_config->get("dark_color_mode") == "1"; + nlohmann::json result; + result["theme"] = dark ? "dark" : "light"; + result["spools"] = build_spool_list(); + result["presets"] = build_preset_options(); + send_response(seq, 0, result); + flush_msg_queue(); + }; + + m_handlers["get_spool_list"] = [this](int seq, const nlohmann::json&) { + send_response(seq, 0, build_spool_list()); + }; + + m_handlers["get_preset_options"] = [this](int seq, const nlohmann::json&) { + send_response(seq, 0, build_preset_options()); + }; + + m_handlers["get_machine_list"] = [this](int seq, const nlohmann::json&) { + send_response(seq, 0, build_machine_list()); + }; + + m_handlers["get_ams_data"] = [this](int seq, const nlohmann::json& data) { + std::string dev_id = data.value("dev_id", ""); + if (!dev_id.empty()) { + auto* mgr = wxGetApp().getDeviceManager(); + if (mgr) mgr->set_selected_machine(dev_id); + } + send_response(seq, 0, build_ams_data()); + }; + + /* ---- Spool CRUD ---- */ + + auto respond_spool_list = [this](int seq) { + send_response(seq, 0, build_spool_list()); + }; + + m_handlers["add_spool"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { store->add_spool(FilamentSpool::from_json(data)); store->save(); } + respond_spool_list(seq); + }; + + m_handlers["batch_add"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { + int qty = data.value("quantity", 1); + nlohmann::json sd = data.contains("spool") ? data["spool"] : nlohmann::json::object(); + for (int i = 0; i < qty; ++i) store->add_spool(FilamentSpool::from_json(sd)); + store->save(); + } + respond_spool_list(seq); + }; + + m_handlers["update_spool"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { store->update_spool(FilamentSpool::from_json(data)); store->save(); } + respond_spool_list(seq); + }; + + m_handlers["remove_spool"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { store->remove_spool(data.value("spool_id", "")); store->save(); } + respond_spool_list(seq); + }; + + m_handlers["batch_remove"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store && data.contains("spool_ids")) { + for (auto& sid : data["spool_ids"]) store->remove_spool(sid.get()); + store->save(); + } + respond_spool_list(seq); + }; + + m_handlers["mark_empty"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { + const FilamentSpool* sp = store->get_spool(data.value("spool_id", "")); + if (sp) { + FilamentSpool u = *sp; + u.status = "empty"; u.remain_percent = 0; + store->update_spool(u); store->save(); + } + } + respond_spool_list(seq); + }; + + m_handlers["toggle_favorite"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { + const FilamentSpool* sp = store->get_spool(data.value("spool_id", "")); + if (sp) { + FilamentSpool u = *sp; + u.favorite = !u.favorite; + store->update_spool(u); store->save(); + } + } + respond_spool_list(seq); + }; + + m_handlers["archive_spool"] = [this, respond_spool_list](int seq, const nlohmann::json& data) { + auto* store = wxGetApp().fila_manager_store(); + if (store) { + const FilamentSpool* sp = store->get_spool(data.value("spool_id", "")); + if (sp) { + FilamentSpool u = *sp; + u.status = "archived"; + store->update_spool(u); store->save(); + } + } + respond_spool_list(seq); + }; +} + +/* ================================================================ + * Data builders + * ================================================================ */ + +nlohmann::json wgtFilaManagerPanel::build_spool_list() +{ + auto* store = wxGetApp().fila_manager_store(); + return store ? store->spools_to_json() : nlohmann::json::array(); +} + +nlohmann::json wgtFilaManagerPanel::build_preset_options() +{ + auto* bundle = wxGetApp().preset_bundle; + if (!bundle) + return {{"vendors", nlohmann::json::array()}}; + + MachineObject* obj = nullptr; + if (auto* dev_mgr = wxGetApp().getDeviceManager()) + obj = dev_mgr->get_selected_machine(); + + std::set printer_names; + if (obj && obj->GetExtderSystem()) { + std::ostringstream stream; + stream << std::fixed << std::setprecision(1) << obj->GetExtderSystem()->GetNozzleDiameter(0); + printer_names = bundle->get_printer_names_by_printer_type_and_nozzle( + DevPrinterConfigUtil::get_printer_display_name(obj->printer_type), + stream.str()); + } + + auto& filaments = bundle->filaments; + std::map>> vendor_type_items; + std::set filament_id_set; + for (auto it = filaments.begin(); it != filaments.end(); ++it) { + Preset& preset = *it; + if (filaments.get_preset_base(*it) != &preset) + continue; + if (obj && !it->is_system && !obj->is_support_user_preset) + continue; + if (!printer_names.empty()) { + ConfigOption* printer_opt = it->config.option("compatible_printers"); + ConfigOptionStrings* printer_strs = dynamic_cast(printer_opt); + if (!printer_strs) + continue; + + bool compatible_printer = false; + for (const auto& printer_str : printer_strs->values) { + if (printer_names.find(printer_str) != printer_names.end()) { + compatible_printer = true; + break; + } + } + if (!compatible_printer) + continue; + } + + std::string vendor = it->config.get_filament_vendor(); + std::string type = it->config.get_filament_type(); + if (vendor.empty()) continue; + if (type.empty()) type = "Other"; + + const std::string dedupe_key = it->filament_id.empty() + ? (vendor + "\n" + type + "\n" + it->name) + : it->filament_id; + if (!filament_id_set.insert(dedupe_key).second) + continue; + + std::string shown_name = filaments.get_preset_alias(*it, true); + if (shown_name.empty()) + shown_name = it->display_name(); + if (shown_name.empty()) + continue; + + vendor_type_items[vendor][type].push_back({ + {"name", shown_name}, + {"series", shown_name}, + {"filament_id", it->filament_id}, + {"setting_id", it->setting_id} + }); + } + + nlohmann::json vendors_arr = nlohmann::json::array(); + for (auto& [vname, type_map] : vendor_type_items) { + nlohmann::json types_arr = nlohmann::json::array(); + for (auto& [tname, items] : type_map) { + nlohmann::json series_arr = nlohmann::json::array(); + for (auto& item : items) { + const std::string name = item.value("name", ""); + if (!name.empty()) series_arr.push_back(name); + } + types_arr.push_back({{"name", tname}, {"series", series_arr}, {"items", items}}); + } + vendors_arr.push_back({{"name", vname}, {"types", types_arr}}); + } + return {{"vendors", vendors_arr}}; +} + +nlohmann::json wgtFilaManagerPanel::build_machine_list() +{ + nlohmann::json result = {{"machines", nlohmann::json::array()}}; + try { + auto* dev_mgr = wxGetApp().getDeviceManager(); + if (!dev_mgr) return result; + + std::map ml = dev_mgr->get_my_machine_list(); + for (auto& [id, obj] : dev_mgr->get_user_machinelist()) { + if (obj && ml.find(id) == ml.end()) ml[id] = obj; + } + + nlohmann::json arr = nlohmann::json::array(); + for (auto& [id, obj] : ml) { + if (!obj) continue; + std::string name = obj->get_dev_name(); + if (name.empty()) name = id; + arr.push_back({{"dev_id", id}, {"dev_name", name}, {"is_online", obj->is_online()}}); + } + result["machines"] = arr; + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] build_machine_list: " << e.what(); + } + return result; +} + +nlohmann::json wgtFilaManagerPanel::build_ams_data() +{ + nlohmann::json empty = {{"selected_dev_id", ""}, {"ams_units", nlohmann::json::array()}}; + try { + auto* dev_mgr = wxGetApp().getDeviceManager(); + if (!dev_mgr) return empty; + + MachineObject* sel = dev_mgr->get_selected_machine(); + std::string sel_id = sel ? sel->get_dev_id() : ""; + + nlohmann::json ams_arr = nlohmann::json::array(); + if (sel) { + auto fila_sys = sel->GetFilaSystem(); + if (fila_sys) { + for (auto& [ams_id, ams] : fila_sys->GetAmsList()) { + if (!ams) continue; + nlohmann::json trays = nlohmann::json::array(); + for (auto& [slot_id, tray] : ams->GetTrays()) { + nlohmann::json t; + t["slot_id"] = slot_id; + t["is_exists"] = tray && tray->is_exists; + if (tray && tray->is_exists) { + t["tag_uid"] = tray->tag_uid; + t["setting_id"] = tray->setting_id; + t["fila_type"] = tray->m_fila_type; + t["sub_brands"] = tray->sub_brands; + std::string color = tray->color; + if (!color.empty() && color[0] != '#') color = "#" + color; + t["color"] = color; + t["weight"] = tray->weight; + t["remain"] = tray->remain; + t["diameter"] = tray->diameter; + t["is_bbl"] = tray->is_bbl; + } + trays.push_back(t); + } + ams_arr.push_back({{"ams_id", ams_id}, {"ams_type", static_cast(ams->GetAmsType())}, {"trays", trays}}); + } + } + } + return {{"selected_dev_id", sel_id}, {"ams_units", ams_arr}}; + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] build_ams_data: " << e.what(); + return empty; + } +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerPanel.h b/src/slic3r/GUI/fila_manager/wgtFilaManagerPanel.h new file mode 100644 index 0000000000..b8d7d3bee3 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerPanel.h @@ -0,0 +1,67 @@ +#ifndef slic3r_wgtFilaManagerPanel_h_ +#define slic3r_wgtFilaManagerPanel_h_ + +#include +#include +#include "nlohmann/json.hpp" +#include +#include +#include +#include +#include + +namespace Slic3r { namespace GUI { + +#define FM_PROTOCOL_VERSION "1.0" + +class wgtFilaManagerPanel : public wxPanel +{ +public: + wgtFilaManagerPanel(wxWindow* parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL); + ~wgtFilaManagerPanel(); + + void msw_rescale(); + void on_sys_color_changed(); + bool Show(bool show) override; + +private: + /* ===== Bridge lifecycle ===== */ + void InitBridge(); + void OnWebMsg(wxWebViewEvent& evt); + + /* ===== C++ → JS channel ===== */ + void SendMsg(nlohmann::json msg); + void send_response(int seq, int code, const nlohmann::json& data); + void push_to_web(const std::string& command, const nlohmann::json& data); + void flush_msg_queue(); + + /* ===== Command registry ===== */ + using CmdHandler = std::function; + void register_handlers(); + std::unordered_map m_handlers; + + /* ===== Data builders ===== */ + nlohmann::json build_spool_list(); + nlohmann::json build_preset_options(); + nlohmann::json build_machine_list(); + nlohmann::json build_ams_data(); + + static int64_t now_ms() { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + + /* ===== State ===== */ + wxWebView* m_browser { nullptr }; + wxString m_home_url; + bool m_bridge_ready { false }; + std::vector m_msg_queue; +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_wgtFilaManagerPanel_h_ diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerStore.cpp b/src/slic3r/GUI/fila_manager/wgtFilaManagerStore.cpp new file mode 100644 index 0000000000..3eda2e2f4b --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerStore.cpp @@ -0,0 +1,292 @@ +#include "wgtFilaManagerStore.h" +#include "libslic3r/Utils.hpp" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace Slic3r { namespace GUI { + +namespace fs = boost::filesystem; + +static std::string generate_uuid() +{ + static boost::uuids::random_generator gen; + return boost::uuids::to_string(gen()); +} + +static std::string now_iso8601() +{ + auto now = std::chrono::system_clock::now(); + std::time_t t = std::chrono::system_clock::to_time_t(now); + std::tm tm{}; +#ifdef _WIN32 + localtime_s(&tm, &t); +#else + localtime_r(&t, &tm); +#endif + std::ostringstream ss; + ss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%S"); + return ss.str(); +} + +// ---------- FilamentSpool serialization ---------- + +nlohmann::json FilamentSpool::to_json() const +{ + return nlohmann::json{ + {"spool_id", spool_id}, + {"setting_id", setting_id}, + {"tag_uid", tag_uid}, + {"brand", brand}, + {"material_type", material_type}, + {"series", series}, + {"color_name", color_name}, + {"color_code", color_code}, + {"diameter", diameter}, + {"initial_weight", initial_weight}, + {"spool_weight", spool_weight}, + {"remain_percent", remain_percent}, + {"status", status}, + {"entry_method", entry_method}, + {"created_at", created_at}, + {"updated_at", updated_at}, + {"bound_dev_id", bound_dev_id}, + {"bound_ams_id", bound_ams_id}, + {"note", note}, + {"favorite", favorite}, + {"net_weight", net_weight}, + {"cloud_synced", cloud_synced} + }; +} + +FilamentSpool FilamentSpool::from_json(const nlohmann::json& j) +{ + FilamentSpool s; + auto get = [&](const char* key, auto& dst) { + if (j.contains(key)) j.at(key).get_to(dst); + }; + get("spool_id", s.spool_id); + get("setting_id", s.setting_id); + get("tag_uid", s.tag_uid); + get("brand", s.brand); + get("material_type", s.material_type); + get("series", s.series); + get("color_name", s.color_name); + get("color_code", s.color_code); + get("diameter", s.diameter); + get("initial_weight", s.initial_weight); + get("spool_weight", s.spool_weight); + get("remain_percent", s.remain_percent); + get("status", s.status); + get("entry_method", s.entry_method); + get("created_at", s.created_at); + get("updated_at", s.updated_at); + get("bound_dev_id", s.bound_dev_id); + get("bound_ams_id", s.bound_ams_id); + get("note", s.note); + get("favorite", s.favorite); + get("net_weight", s.net_weight); + get("cloud_synced", s.cloud_synced); + return s; +} + +// ---------- wgtFilaManagerStore ---------- + +std::string wgtFilaManagerStore::get_storage_path() const +{ + return (fs::path(data_dir()) / "filament_inventory" / "spools.json").string(); +} + +void wgtFilaManagerStore::load() +{ + std::string path = get_storage_path(); + fs::path dir = fs::path(path).parent_path(); + if (!fs::exists(dir)) + fs::create_directories(dir); + + if (!fs::exists(path)) return; + + try { + boost::nowide::ifstream ifs(path); + nlohmann::json j; + ifs >> j; + m_spools.clear(); + nlohmann::json spool_list = nlohmann::json::array(); + if (j.is_array()) { + spool_list = j; + } else if (j.is_object()) { + if (j.contains("spools") && j["spools"].is_array()) + spool_list = j["spools"]; + } + if (spool_list.is_array()) { + for (auto& item : spool_list) { + FilamentSpool spool = FilamentSpool::from_json(item); + m_spools[spool.spool_id] = std::move(spool); + } + } + BOOST_LOG_TRIVIAL(info) << "[FilaManager] Loaded " << m_spools.size() << " spools"; + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "[FilaManager] Failed to load spools: " << e.what(); + } + + m_dirty = false; +} + +void wgtFilaManagerStore::save() +{ + std::string path = get_storage_path(); + fs::path dir = fs::path(path).parent_path(); + if (!fs::exists(dir)) + fs::create_directories(dir); + + nlohmann::json arr = nlohmann::json::array(); + for (auto& [id, spool] : m_spools) + arr.push_back(spool.to_json()); + nlohmann::json root = { + {"spools", arr} + }; + + std::string tmp = path + ".tmp"; + { + boost::nowide::ofstream ofs(tmp); + ofs << root.dump(2); + } + + boost::system::error_code ec; + fs::rename(tmp, path, ec); + if (ec) + BOOST_LOG_TRIVIAL(error) << "[FilaManager] Failed to save: " << ec.message(); + + m_dirty = false; +} + +// ---------- CRUD ---------- + +std::string wgtFilaManagerStore::add_spool(const FilamentSpool& spool) +{ + FilamentSpool s = spool; + if (s.spool_id.empty()) s.spool_id = generate_uuid(); + if (s.created_at.empty()) s.created_at = now_iso8601(); + s.updated_at = now_iso8601(); + const std::string created_id = s.spool_id; + m_spools[created_id] = std::move(s); + m_dirty = true; + return created_id; +} + +void wgtFilaManagerStore::update_spool(const FilamentSpool& spool) +{ + auto it = m_spools.find(spool.spool_id); + if (it == m_spools.end()) return; + FilamentSpool s = spool; + s.updated_at = now_iso8601(); + it->second = std::move(s); + m_dirty = true; +} + +bool wgtFilaManagerStore::apply_patch(const std::string& spool_id, const nlohmann::json& patch) +{ + auto it = m_spools.find(spool_id); + if (it == m_spools.end()) return false; + FilamentSpool& s = it->second; + + // 仅合并用户可编辑字段;不接受 null(表示"未提供")。系统字段 spool_id / + // tag_uid / entry_method / created_at / bound_* / cloud_synced 故意不在此处 + // 合并,避免前端 patch 清掉它们(见 STUDIO-17964 Problem A)。 + auto get_if = [&](const char* key, auto& dst) { + if (!patch.contains(key)) return; + const auto& v = patch.at(key); + if (v.is_null()) return; + try { v.get_to(dst); } catch (...) {} + }; + get_if("setting_id", s.setting_id); + get_if("brand", s.brand); + get_if("material_type", s.material_type); + get_if("series", s.series); + get_if("color_name", s.color_name); + get_if("color_code", s.color_code); + get_if("diameter", s.diameter); + get_if("initial_weight", s.initial_weight); + get_if("spool_weight", s.spool_weight); + get_if("remain_percent", s.remain_percent); + get_if("status", s.status); + get_if("note", s.note); + get_if("favorite", s.favorite); + get_if("net_weight", s.net_weight); + + s.updated_at = now_iso8601(); + s.cloud_synced = false; + m_dirty = true; + return true; +} + +void wgtFilaManagerStore::remove_spool(const std::string& spool_id) +{ + m_spools.erase(spool_id); + m_dirty = true; +} + +bool wgtFilaManagerStore::mark_synced(const std::string& spool_id, bool synced) +{ + auto it = m_spools.find(spool_id); + if (it == m_spools.end()) return false; + if (it->second.cloud_synced == synced) return false; + it->second.cloud_synced = synced; + m_dirty = true; + return true; +} + +const FilamentSpool* wgtFilaManagerStore::get_spool(const std::string& spool_id) const +{ + auto it = m_spools.find(spool_id); + return it != m_spools.end() ? &it->second : nullptr; +} + +// ---------- AMS matching ---------- + +const FilamentSpool* wgtFilaManagerStore::find_by_tag_uid(const std::string& tag_uid) const +{ + if (tag_uid.empty()) return nullptr; + for (auto& [id, spool] : m_spools) { + if (spool.tag_uid == tag_uid) + return &spool; + } + return nullptr; +} + +const FilamentSpool* wgtFilaManagerStore::find_by_setting_and_color( + const std::string& setting_id, const std::string& color) const +{ + if (setting_id.empty()) return nullptr; + + const FilamentSpool* match = nullptr; + int count = 0; + for (auto& [id, spool] : m_spools) { + if (spool.setting_id == setting_id && spool.color_code == color) { + match = &spool; + ++count; + } + } + return count == 1 ? match : nullptr; +} + +// ---------- JSON for WebView ---------- + +nlohmann::json wgtFilaManagerStore::spools_to_json() const +{ + nlohmann::json arr = nlohmann::json::array(); + for (auto& [id, spool] : m_spools) + arr.push_back(spool.to_json()); + return arr; +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerStore.h b/src/slic3r/GUI/fila_manager/wgtFilaManagerStore.h new file mode 100644 index 0000000000..5cacb78086 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerStore.h @@ -0,0 +1,90 @@ +#ifndef slic3r_wgtFilaManagerStore_h_ +#define slic3r_wgtFilaManagerStore_h_ + +#include +#include +#include +#include "nlohmann/json.hpp" + +namespace Slic3r { namespace GUI { + +struct FilamentSpool { + std::string spool_id; + std::string setting_id; + std::string tag_uid; + + std::string brand; + std::string material_type; + std::string series; + std::string color_name; + std::string color_code; + float diameter = 1.75f; + + float initial_weight = 0; + float spool_weight = 0; + int remain_percent = 100; + std::string status = "active"; // "active" | "low" | "empty" | "archived" + + std::string entry_method; // "manual" | "ams_sync" + std::string created_at; + std::string updated_at; + + std::string bound_dev_id; + std::string bound_ams_id; + + std::string note; + + bool favorite = false; + float net_weight = 0; + + // Cloud synchronization marker. Cloud is the source of truth: this flag + // is true iff the spool was present in the latest cloud pull. + bool cloud_synced = false; + + nlohmann::json to_json() const; + static FilamentSpool from_json(const nlohmann::json& j); +}; + +class wgtFilaManagerStore { +public: + wgtFilaManagerStore() = default; + ~wgtFilaManagerStore() = default; + + void load(); + void save(); + + std::string add_spool(const FilamentSpool& spool); + void update_spool(const FilamentSpool& spool); + // Selectively merge user-editable fields from `patch` into the existing + // spool without touching system-managed metadata (spool_id / tag_uid / + // entry_method / created_at / bound_* / cloud_synced). Returns true if an + // existing spool was updated. + bool apply_patch(const std::string& spool_id, const nlohmann::json& patch); + void remove_spool(const std::string& spool_id); + const FilamentSpool* get_spool(const std::string& spool_id) const; + + // Flip the cloud_synced flag without rewriting other fields. + // Returns true if the flag actually changed (used by callers to decide + // whether to re-save and re-publish the list). + bool mark_synced(const std::string& spool_id, bool synced); + + const FilamentSpool* find_by_tag_uid(const std::string& tag_uid) const; + const FilamentSpool* find_by_setting_and_color( + const std::string& setting_id, const std::string& color) const; + + bool is_dirty() const { return m_dirty; } + void set_dirty() { m_dirty = true; } + void clear_dirty() { m_dirty = false; } + + nlohmann::json spools_to_json() const; + +private: + std::string get_storage_path() const; + + std::map m_spools; + bool m_dirty = false; +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_wgtFilaManagerStore_h_ diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerSync.cpp b/src/slic3r/GUI/fila_manager/wgtFilaManagerSync.cpp new file mode 100644 index 0000000000..417a903975 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerSync.cpp @@ -0,0 +1,101 @@ +#include "wgtFilaManagerSync.h" +#include "wgtFilaManagerStore.h" + +#include + +#include "slic3r/GUI/DeviceCore/DevFilaSystem.h" +#include "slic3r/GUI/DeviceManager.hpp" + +namespace Slic3r { namespace GUI { + +wgtFilaManagerSync::wgtFilaManagerSync(wgtFilaManagerStore* store) + : m_store(store) +{} + +void wgtFilaManagerSync::on_device_update(MachineObject* obj) +{ + if (!obj || !m_store) return; + sync_all_trays(obj); +} + +void wgtFilaManagerSync::sync_all_trays(MachineObject* obj) +{ + if (!obj || !m_store) return; + + auto fila_sys = obj->GetFilaSystem(); + if (!fila_sys) return; + + std::string dev_id = obj->get_dev_id(); + + for (auto& [ams_id, ams] : fila_sys->GetAmsList()) { + if (!ams) continue; + for (auto& [slot_id, tray] : ams->GetTrays()) { + if (!tray || (tray->setting_id.empty() && tray->tag_uid.empty())) + continue; + + const FilamentSpool* matched = match_tray(*tray); + if (matched) { + FilamentSpool updated = *matched; + updated.remain_percent = tray->remain; + updated.bound_dev_id = dev_id; + updated.bound_ams_id = ams_id; + if (!tray->tag_uid.empty()) updated.tag_uid = tray->tag_uid; + updated.status = tray->remain == 0 ? "empty" : (tray->remain < 20 ? "low" : "active"); + m_store->update_spool(updated); + } else { + m_store->add_spool(create_spool_from_tray(*tray, dev_id, ams_id)); + } + } + } + + for (auto& tray : obj->vt_slot) { + if (tray.setting_id.empty() && tray.tag_uid.empty()) + continue; + + const FilamentSpool* matched = match_tray(tray); + if (matched) { + FilamentSpool updated = *matched; + updated.remain_percent = tray.remain; + updated.bound_dev_id = dev_id; + updated.bound_ams_id = "ext"; + if (!tray.tag_uid.empty()) updated.tag_uid = tray.tag_uid; + updated.status = tray.remain == 0 ? "empty" : (tray.remain < 20 ? "low" : "active"); + m_store->update_spool(updated); + } else { + m_store->add_spool(create_spool_from_tray(tray, dev_id, "ext")); + } + } + + m_store->set_dirty(); +} + +const FilamentSpool* wgtFilaManagerSync::match_tray(const DevAmsTray& tray) +{ + if (!tray.tag_uid.empty()) { + auto* sp = m_store->find_by_tag_uid(tray.tag_uid); + if (sp) return sp; + } + if (!tray.setting_id.empty()) { + auto* sp = m_store->find_by_setting_and_color(tray.setting_id, tray.color); + if (sp) return sp; + } + return nullptr; +} + +FilamentSpool wgtFilaManagerSync::create_spool_from_tray(const DevAmsTray& tray, + const std::string& dev_id, + const std::string& ams_id) +{ + FilamentSpool spool; + spool.tag_uid = tray.tag_uid; + spool.setting_id = tray.setting_id; + spool.color_code = tray.color; + spool.remain_percent = tray.remain; + spool.entry_method = "ams_sync"; + spool.bound_dev_id = dev_id; + spool.bound_ams_id = ams_id; + spool.status = tray.remain < 20 ? "low" : "active"; + return spool; +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/fila_manager/wgtFilaManagerSync.h b/src/slic3r/GUI/fila_manager/wgtFilaManagerSync.h new file mode 100644 index 0000000000..bb5f5c90c6 --- /dev/null +++ b/src/slic3r/GUI/fila_manager/wgtFilaManagerSync.h @@ -0,0 +1,35 @@ +#ifndef slic3r_wgtFilaManagerSync_h_ +#define slic3r_wgtFilaManagerSync_h_ + +#include + +namespace Slic3r { +class MachineObject; +class DevAmsTray; +} // namespace Slic3r + +namespace Slic3r { namespace GUI { + +class wgtFilaManagerStore; +struct FilamentSpool; + +class wgtFilaManagerSync { +public: + explicit wgtFilaManagerSync(wgtFilaManagerStore* store); + ~wgtFilaManagerSync() = default; + + void on_device_update(MachineObject* obj); + void sync_all_trays(MachineObject* obj); + +private: + const FilamentSpool* match_tray(const DevAmsTray& tray); + FilamentSpool create_spool_from_tray(const DevAmsTray& tray, + const std::string& dev_id, + const std::string& ams_id); + + wgtFilaManagerStore* m_store; +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_wgtFilaManagerSync_h_ diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index 1403ba5924..f5ad471157 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -1613,9 +1613,13 @@ bool CalibUtils::is_support_auto_pa_cali(std::string filament_id) return not_support_auto_pa_cali_filaments.find(filament_id) == not_support_auto_pa_cali_filaments.end(); } -std::vector CalibUtils::get_supported_nozzle_diameters_by_model(const std::string &printer_model) +std::vector CalibUtils::get_supported_nozzle_diameters_by_model(const MachineObject *obj) { std::vector result; + if (!obj) return result; + + std::string printer_model = DevPrinterConfigUtil::get_printer_display_name(obj->printer_type); + PresetBundle *preset_bundle = wxGetApp().preset_bundle; if (!preset_bundle || printer_model.empty()) return result; @@ -1633,9 +1637,13 @@ std::vector CalibUtils::get_supported_nozzle_diameters_by_model(con return result; } -std::vector CalibUtils::get_supported_nozzle_volume_types_by_model_and_nozzle(const std::string &model_id, const std::string &nozzle_diameter) +std::vector CalibUtils::get_supported_nozzle_volume_types_by_model_and_nozzle(const MachineObject *obj, const std::string &nozzle_diameter) { std::vector result; + if (!obj) return result; + + std::string model_id = DevPrinterConfigUtil::get_printer_display_name(obj->printer_type); + PresetBundle *preset_bundle = wxGetApp().preset_bundle; if (!preset_bundle || model_id.empty()) return result; @@ -1659,20 +1667,26 @@ std::vector CalibUtils::get_supported_nozzle_volume_types_by_m return std::vector(unique_types.begin(), unique_types.end()); } -std::map> CalibUtils::get_supported_nozzle_volume_and_diameters(const MachineObject *obj) +std::map> CalibUtils::get_supported_nozzle_volume_and_diameters(const MachineObject *obj, bool with_hybrid) { std::map> volume_diameters_map; if (!obj) return volume_diameters_map; std::string printer_model = DevPrinterConfigUtil::get_printer_display_name(obj->printer_type); - std::vector diameters = get_supported_nozzle_diameters_by_model(printer_model); + std::vector diameters = get_supported_nozzle_diameters_by_model(obj); for (auto& diameter : diameters) { - std::vector volumes = get_supported_nozzle_volume_types_by_model_and_nozzle(printer_model, diameter); + std::vector volumes = get_supported_nozzle_volume_types_by_model_and_nozzle(obj, diameter); for (auto& volume : volumes) { + // high flow type does not support 0.2mm nozzle + if (diameter == "0.2") { + if (volume == NozzleVolumeType::nvtHighFlow) continue; + if (volume == NozzleVolumeType::nvtTPUHighFlow) continue; + } + volume_diameters_map[volume].insert(DevNozzle::ToNozzleDiameterType(diameter)); } } @@ -1682,7 +1696,9 @@ std::map> CalibUtils::get_support for (const auto& [volume, diameters] : volume_diameters_map) { hybrid_diameters_set.insert(diameters.begin(), diameters.end()); } - volume_diameters_map[NozzleVolumeType::nvtHybrid] = hybrid_diameters_set; + if (with_hybrid) { + volume_diameters_map[NozzleVolumeType::nvtHybrid] = hybrid_diameters_set; + } } return volume_diameters_map; diff --git a/src/slic3r/Utils/CalibUtils.hpp b/src/slic3r/Utils/CalibUtils.hpp index 7b5e7ab451..e3bd01bbce 100644 --- a/src/slic3r/Utils/CalibUtils.hpp +++ b/src/slic3r/Utils/CalibUtils.hpp @@ -75,13 +75,13 @@ class CalibUtils static bool is_support_auto_pa_cali(std::string filament_id); // Get all supported nozzle diameters for a given printer model - static std::vector get_supported_nozzle_diameters_by_model(const std::string &printer_model); + static std::vector get_supported_nozzle_diameters_by_model(const MachineObject *obj); // Get all supported NozzleVolumeTypes for a given printer model and nozzle diameter - static std::vector get_supported_nozzle_volume_types_by_model_and_nozzle(const std::string &printer_model, const std::string &nozzle_diameter); + static std::vector get_supported_nozzle_volume_types_by_model_and_nozzle(const MachineObject *obj, const std::string &nozzle_diameter); // key:supported volume type; value: volume type supported diameter - static std::map> get_supported_nozzle_volume_and_diameters(const MachineObject *obj); + static std::map> get_supported_nozzle_volume_and_diameters(const MachineObject *obj, bool with_hybrid=true); static int get_selected_calib_idx(const std::vector &pa_calib_values, int cali_idx); static bool get_pa_k_n_value_by_cali_idx(const MachineObject* obj, int cali_idx, float& out_k, float& out_n); diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index f207ce6e48..564943799b 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -101,6 +101,11 @@ func_get_my_message NetworkAgent::get_my_message_ptr = nullptr; func_check_user_task_report NetworkAgent::check_user_task_report_ptr = nullptr; func_get_user_print_info NetworkAgent::get_user_print_info_ptr = nullptr; func_get_user_tasks NetworkAgent::get_user_tasks_ptr = nullptr; +func_get_filament_spools NetworkAgent::get_filament_spools_ptr = nullptr; +func_create_filament_spool NetworkAgent::create_filament_spool_ptr = nullptr; +func_update_filament_spool NetworkAgent::update_filament_spool_ptr = nullptr; +func_delete_filament_spools NetworkAgent::delete_filament_spools_ptr = nullptr; +func_get_filament_config NetworkAgent::get_filament_config_ptr = nullptr; func_get_printer_firmware NetworkAgent::get_printer_firmware_ptr = nullptr; func_get_task_plate_index NetworkAgent::get_task_plate_index_ptr = nullptr; func_get_user_info NetworkAgent::get_user_info_ptr = nullptr; @@ -348,6 +353,11 @@ int NetworkAgent::initialize_network_module(bool using_backup, bool validate_cer check_user_task_report_ptr = reinterpret_cast(get_network_function("bambu_network_check_user_task_report")); get_user_print_info_ptr = reinterpret_cast(get_network_function("bambu_network_get_user_print_info")); get_user_tasks_ptr = reinterpret_cast(get_network_function("bambu_network_get_user_tasks")); + get_filament_spools_ptr = reinterpret_cast(get_network_function("bambu_network_get_filament_spools")); + create_filament_spool_ptr = reinterpret_cast(get_network_function("bambu_network_create_filament_spool")); + update_filament_spool_ptr = reinterpret_cast(get_network_function("bambu_network_update_filament_spool")); + delete_filament_spools_ptr = reinterpret_cast(get_network_function("bambu_network_delete_filament_spools")); + get_filament_config_ptr = reinterpret_cast(get_network_function("bambu_network_get_filament_config")); get_printer_firmware_ptr = reinterpret_cast(get_network_function("bambu_network_get_printer_firmware")); get_task_plate_index_ptr = reinterpret_cast(get_network_function("bambu_network_get_task_plate_index")); get_user_info_ptr = reinterpret_cast(get_network_function("bambu_network_get_user_info")); @@ -473,6 +483,11 @@ int NetworkAgent::unload_network_module() check_user_task_report_ptr = nullptr; get_user_print_info_ptr = nullptr; get_user_tasks_ptr = nullptr; + get_filament_spools_ptr = nullptr; + create_filament_spool_ptr = nullptr; + update_filament_spool_ptr = nullptr; + delete_filament_spools_ptr = nullptr; + get_filament_config_ptr = nullptr; get_printer_firmware_ptr = nullptr; get_task_plate_index_ptr = nullptr; get_user_info_ptr = nullptr; @@ -1314,6 +1329,66 @@ int NetworkAgent::get_user_tasks(TaskQueryParams params, std::string* http_body) return ret; } +int NetworkAgent::get_filament_spools(FilamentQueryParams params, std::string* http_body) +{ + if (!network_agent || !get_filament_spools_ptr) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": unavailable (network_agent=" + << network_agent << " func_ptr=" << (void*)get_filament_spools_ptr << ")"; + return BAMBU_NETWORK_ERR_INVALID_HANDLE; + } + int ret = get_filament_spools_ptr(network_agent, params, http_body); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%") %network_agent %ret; + return ret; +} + +int NetworkAgent::create_filament_spool(std::string request_body, std::string* http_body) +{ + if (!network_agent || !create_filament_spool_ptr) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": unavailable (network_agent=" + << network_agent << " func_ptr=" << (void*)create_filament_spool_ptr << ")"; + return BAMBU_NETWORK_ERR_INVALID_HANDLE; + } + int ret = create_filament_spool_ptr(network_agent, request_body, http_body); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%") %network_agent %ret; + return ret; +} + +int NetworkAgent::update_filament_spool(std::string spool_id, std::string request_body, std::string* http_body) +{ + if (!network_agent || !update_filament_spool_ptr) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": unavailable (network_agent=" + << network_agent << " func_ptr=" << (void*)update_filament_spool_ptr << ")"; + return BAMBU_NETWORK_ERR_INVALID_HANDLE; + } + int ret = update_filament_spool_ptr(network_agent, spool_id, request_body, http_body); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%, spool_id=%3%") %network_agent %ret %spool_id; + return ret; +} + +int NetworkAgent::delete_filament_spools(FilamentDeleteParams params, std::string* http_body) +{ + if (!network_agent || !delete_filament_spools_ptr) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": unavailable (network_agent=" + << network_agent << " func_ptr=" << (void*)delete_filament_spools_ptr << ")"; + return BAMBU_NETWORK_ERR_INVALID_HANDLE; + } + int ret = delete_filament_spools_ptr(network_agent, params, http_body); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%") %network_agent %ret; + return ret; +} + +int NetworkAgent::get_filament_config(std::string* http_body) +{ + if (!network_agent || !get_filament_config_ptr) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": unavailable (network_agent=" + << network_agent << " func_ptr=" << (void*)get_filament_config_ptr << ")"; + return BAMBU_NETWORK_ERR_INVALID_HANDLE; + } + int ret = get_filament_config_ptr(network_agent, http_body); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%") %network_agent %ret; + return ret; +} + int NetworkAgent::get_printer_firmware(std::string dev_id, unsigned* http_code, std::string* http_body) { int ret = 0; diff --git a/src/slic3r/Utils/NetworkAgent.hpp b/src/slic3r/Utils/NetworkAgent.hpp index 2872257cdc..7a4fe1eb41 100644 --- a/src/slic3r/Utils/NetworkAgent.hpp +++ b/src/slic3r/Utils/NetworkAgent.hpp @@ -79,6 +79,11 @@ typedef int (*func_get_my_message)(void *agent, int type, int after, int limit, typedef int (*func_check_user_task_report)(void *agent, int* task_id, bool* printable); typedef int (*func_get_user_print_info)(void *agent, unsigned int* http_code, std::string* http_body); typedef int (*func_get_user_tasks)(void *agent, TaskQueryParams params, std::string* http_body); +typedef int (*func_get_filament_spools)(void *agent, FilamentQueryParams params, std::string* http_body); +typedef int (*func_create_filament_spool)(void *agent, std::string request_body, std::string* http_body); +typedef int (*func_update_filament_spool)(void *agent, std::string spool_id, std::string request_body, std::string* http_body); +typedef int (*func_delete_filament_spools)(void *agent, FilamentDeleteParams params, std::string* http_body); +typedef int (*func_get_filament_config)(void *agent, std::string* http_body); typedef int (*func_get_printer_firmware)(void *agent, std::string dev_id, unsigned* http_code, std::string* http_body); typedef int (*func_get_task_plate_index)(void *agent, std::string task_id, int* plate_index); typedef int (*func_get_user_info)(void *agent, int* identifier); @@ -200,6 +205,11 @@ class NetworkAgent int check_user_task_report(int* task_id, bool* printable); int get_user_print_info(unsigned int* http_code, std::string* http_body); int get_user_tasks(TaskQueryParams params, std::string* http_body); + int get_filament_spools(FilamentQueryParams params, std::string* http_body); + int create_filament_spool(std::string request_body, std::string* http_body); + int update_filament_spool(std::string spool_id, std::string request_body, std::string* http_body); + int delete_filament_spools(FilamentDeleteParams params, std::string* http_body); + int get_filament_config(std::string* http_body); int get_printer_firmware(std::string dev_id, unsigned* http_code, std::string* http_body); int get_task_plate_index(std::string task_id, int* plate_index); int get_user_info(int* identifier); @@ -311,6 +321,11 @@ class NetworkAgent static func_check_user_task_report check_user_task_report_ptr; static func_get_user_print_info get_user_print_info_ptr; static func_get_user_tasks get_user_tasks_ptr; + static func_get_filament_spools get_filament_spools_ptr; + static func_create_filament_spool create_filament_spool_ptr; + static func_update_filament_spool update_filament_spool_ptr; + static func_delete_filament_spools delete_filament_spools_ptr; + static func_get_filament_config get_filament_config_ptr; static func_get_printer_firmware get_printer_firmware_ptr; static func_get_task_plate_index get_task_plate_index_ptr; static func_get_user_info get_user_info_ptr; diff --git a/src/slic3r/Utils/bambu_networking.hpp b/src/slic3r/Utils/bambu_networking.hpp index 095751b246..702e85effd 100644 --- a/src/slic3r/Utils/bambu_networking.hpp +++ b/src/slic3r/Utils/bambu_networking.hpp @@ -4,6 +4,7 @@ #include #include #include +#include extern std::string g_log_folder; extern std::string g_log_start_time; @@ -37,6 +38,11 @@ namespace BBL { #define BAMBU_NETWORK_ERR_NO_CORRESPONDING_BUCKET -24 #define BAMBU_NETWORK_ERR_GET_INSTANCE_ID_FAILED -25 #define BAMBU_NETWORK_SIGNED_ERROR -26 +#define BAMBU_NETWORK_ERR_GET_FILAMENTS_FAILED -27 +#define BAMBU_NETWORK_ERR_CREATE_FILAMENT_FAILED -28 +#define BAMBU_NETWORK_ERR_UPDATE_FILAMENT_FAILED -29 +#define BAMBU_NETWORK_ERR_DELETE_FILAMENT_FAILED -30 +#define BAMBU_NETWORK_ERR_GET_FILAMENT_CONFIG_FAILED -31 //bind error #define BAMBU_NETWORK_ERR_BIND_CREATE_SOCKET_FAILED -1010 //failed to create socket @@ -97,7 +103,7 @@ namespace BBL { #define BAMBU_NETWORK_LIBRARY "bambu_networking" #define BAMBU_NETWORK_AGENT_NAME "bambu_network_agent" -#define BAMBU_NETWORK_AGENT_VERSION "02.06.00.50" +#define BAMBU_NETWORK_AGENT_VERSION "02.06.01.50" //iot preset type strings #define IOT_PRINTER_TYPE_STRING "printer" @@ -248,6 +254,22 @@ struct TaskQueryParams int limit = 20; }; +struct FilamentQueryParams +{ + std::string category; + std::string status; + std::string spool_id; + std::string rfid; + int offset = 0; + int limit = 20; +}; + +struct FilamentDeleteParams +{ + std::vector ids; + std::vector rfids; +}; + struct PublishParams { std::string project_name; std::string project_3mf_file; diff --git a/version.inc b/version.inc index 1f4ffbee49..891daa460b 100644 --- a/version.inc +++ b/version.inc @@ -13,7 +13,7 @@ endif() # The build_version should start from 50 in master branch -set(SLIC3R_VERSION "02.06.00.51") +set(SLIC3R_VERSION "02.06.01.55") string(REPLACE "." "," SLIC3R_COMMA_SEPARATED_VERSION ${SLIC3R_VERSION}) set(SLIC3R_COMMA_SEPARATED_VERSION "${SLIC3R_COMMA_SEPARATED_VERSION}")