diff --git a/resources/QIDISlicer.icns b/resources/QIDISlicer.icns
new file mode 100644
index 0000000..5d36b24
Binary files /dev/null and b/resources/QIDISlicer.icns differ
diff --git a/resources/icons/Q2_thumbnail.png b/resources/icons/Q2_thumbnail.png
new file mode 100644
index 0000000..e7e712d
Binary files /dev/null and b/resources/icons/Q2_thumbnail.png differ
diff --git a/resources/localization/QIDISlicer.pot b/resources/localization/QIDISlicer.pot
index 7fdfbda..60f3f39 100644
--- a/resources/localization/QIDISlicer.pot
+++ b/resources/localization/QIDISlicer.pot
@@ -19396,4 +19396,25 @@ msgid""
msgstr""
msgid "Learn more"
-msgstr""
\ No newline at end of file
+msgstr""
+
+msgid "Export GCODE.3MF file:"
+msgstr ""
+
+msgid "Export File"
+msgstr ""
+
+msgid "Export all gcode.3mf"
+msgstr ""
+
+msgid "Sync filament info from the box"
+msgstr ""
+
+msgid "Sync Box information"
+msgstr ""
+
+msgid "Please select the printer in the list to get box info"
+msgstr ""
+
+msgid "This Printer has not connect the box, please check."
+msgstr ""
\ No newline at end of file
diff --git a/resources/localization/be/QIDISlicer.mo b/resources/localization/be/QIDISlicer.mo
index 910282b..422c029 100644
Binary files a/resources/localization/be/QIDISlicer.mo and b/resources/localization/be/QIDISlicer.mo differ
diff --git a/resources/localization/be/QIDISlicer_be.po b/resources/localization/be/QIDISlicer_be.po
index 66efc23..f6e338b 100644
--- a/resources/localization/be/QIDISlicer_be.po
+++ b/resources/localization/be/QIDISlicer_be.po
@@ -30366,4 +30366,25 @@ msgstr ""
"Вам трэба ўручную выдаліць папку WebView.\n"
msgid "Learn more"
-msgstr "Даведацца больш"
\ No newline at end of file
+msgstr "Даведацца больш"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Экспартаваць файл GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Экспартаваць файл"
+
+msgid "Export all gcode.3mf"
+msgstr "Экспартаваць усе gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Сінхранізаваць інфармацыю аб філаменце з скрыні"
+
+msgid "Sync Box information"
+msgstr "Сінхранізаваць інфармацыю скрыні"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Выберыце друкарку з спісу, каб атрымаць інфармацыю аб скрыні"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Гэтая друкарка не падключана да скрыні, калі ласка, праверце."
\ No newline at end of file
diff --git a/resources/localization/ca/QIDISlicer.mo b/resources/localization/ca/QIDISlicer.mo
index 9db6c21..06c132f 100644
Binary files a/resources/localization/ca/QIDISlicer.mo and b/resources/localization/ca/QIDISlicer.mo differ
diff --git a/resources/localization/ca/QIDISlicer_ca.po b/resources/localization/ca/QIDISlicer_ca.po
index e4be060..73673e8 100644
--- a/resources/localization/ca/QIDISlicer_ca.po
+++ b/resources/localization/ca/QIDISlicer_ca.po
@@ -30303,4 +30303,25 @@ msgstr ""
"Cal que suprimiu manualment la carpeta WebView.\n"
msgid "Learn more"
-msgstr "Aprèn més"
\ No newline at end of file
+msgstr "Aprèn més"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Exporta fitxer GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Exporta fitxer"
+
+msgid "Export all gcode.3mf"
+msgstr "Exporta tots els gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Sincronitza informació del filament des de la caixa"
+
+msgid "Sync Box information"
+msgstr "Sincronitza informació de la caixa"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Selecciona la impressora de la llista per obtenir informació de la caixa"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Aquesta impressora no està connectada a la caixa, comproveu-ho."
\ No newline at end of file
diff --git a/resources/localization/cs/QIDISlicer.mo b/resources/localization/cs/QIDISlicer.mo
index 261667f..68c64dd 100644
Binary files a/resources/localization/cs/QIDISlicer.mo and b/resources/localization/cs/QIDISlicer.mo differ
diff --git a/resources/localization/cs/QIDISlicer_cs.po b/resources/localization/cs/QIDISlicer_cs.po
index ace0efb..5526646 100644
--- a/resources/localization/cs/QIDISlicer_cs.po
+++ b/resources/localization/cs/QIDISlicer_cs.po
@@ -30708,4 +30708,25 @@ msgstr ""
"Musíte ručně odstranit složku WebView.\n"
msgid "Learn more"
-msgstr "Zjistit více"
\ No newline at end of file
+msgstr "Zjistit více"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Exportovat soubor GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Exportovat soubor"
+
+msgid "Export all gcode.3mf"
+msgstr "Exportovat všechny gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Synchronizovat informace o filamentu z boxu"
+
+msgid "Sync Box information"
+msgstr "Synchronizovat informace z boxu"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Vyberte tiskárnu ze seznamu pro získání informací o boxu"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Tato tiskárna není připojena k boxu, prosím zkontrolujte."
\ No newline at end of file
diff --git a/resources/localization/de/QIDISlicer.mo b/resources/localization/de/QIDISlicer.mo
index 5b940ee..269d421 100644
Binary files a/resources/localization/de/QIDISlicer.mo and b/resources/localization/de/QIDISlicer.mo differ
diff --git a/resources/localization/de/QIDISlicer_de.po b/resources/localization/de/QIDISlicer_de.po
index aafd7d1..48e3d97 100644
--- a/resources/localization/de/QIDISlicer_de.po
+++ b/resources/localization/de/QIDISlicer_de.po
@@ -31230,4 +31230,25 @@ msgstr ""
"Sie müssen den WebView-Ordner manuell löschen.\n"
msgid "Learn more"
-msgstr "Mehr erfahren"
\ No newline at end of file
+msgstr "Mehr erfahren"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF-Datei exportieren:"
+
+msgid "Export File"
+msgstr "Datei exportieren"
+
+msgid "Export all gcode.3mf"
+msgstr "Alle gcode.3mf exportieren"
+
+msgid "Sync filament info from the box"
+msgstr "Filamentinformationen vom Kasten synchronisieren"
+
+msgid "Sync Box information"
+msgstr "Kasteninformationen synchronisieren"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Bitte wählen Sie den Drucker aus der Liste aus, um Kasteninformationen zu erhalten"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Dieser Drucker ist nicht mit dem Kasten verbunden, bitte überprüfen."
\ No newline at end of file
diff --git a/resources/localization/en/QIDISlicer.mo b/resources/localization/en/QIDISlicer.mo
index efbf553..81b6f02 100644
Binary files a/resources/localization/en/QIDISlicer.mo and b/resources/localization/en/QIDISlicer.mo differ
diff --git a/resources/localization/en/QIDISlicer_en.po b/resources/localization/en/QIDISlicer_en.po
index 833fe30..0593efb 100644
--- a/resources/localization/en/QIDISlicer_en.po
+++ b/resources/localization/en/QIDISlicer_en.po
@@ -28224,4 +28224,25 @@ msgid ""
msgstr ""
msgid "Learn more"
+msgstr ""
+
+msgid "Export GCODE.3MF file:"
+msgstr ""
+
+msgid "Export File"
+msgstr ""
+
+msgid "Export all gcode.3mf"
+msgstr ""
+
+msgid "Sync filament info from the box"
+msgstr ""
+
+msgid "Sync Box information"
+msgstr ""
+
+msgid "Please select the printer in the list to get box info"
+msgstr ""
+
+msgid "This Printer has not connect the box, please check."
msgstr ""
\ No newline at end of file
diff --git a/resources/localization/es/QIDISlicer.mo b/resources/localization/es/QIDISlicer.mo
index e6492a2..efe14ba 100644
Binary files a/resources/localization/es/QIDISlicer.mo and b/resources/localization/es/QIDISlicer.mo differ
diff --git a/resources/localization/es/QIDISlicer_es.po b/resources/localization/es/QIDISlicer_es.po
index a94d1c5..1d34846 100644
--- a/resources/localization/es/QIDISlicer_es.po
+++ b/resources/localization/es/QIDISlicer_es.po
@@ -31033,4 +31033,25 @@ msgstr ""
"Debes eliminar manualmente la carpeta WebView.\n"
msgid "Learn more"
-msgstr "Aprende más"
\ No newline at end of file
+msgstr "Aprende más"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Exportar archivo GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Exportar archivo"
+
+msgid "Export all gcode.3mf"
+msgstr "Exportar todos los archivos gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Sincronizar información del filamento desde la caja"
+
+msgid "Sync Box information"
+msgstr "Sincronizar información de la caja"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Seleccione la impresora de la lista para obtener información de la caja"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Esta impresora no está conectada a la caja, por favor verifique."
\ No newline at end of file
diff --git a/resources/localization/fi/QIDISlicer.mo b/resources/localization/fi/QIDISlicer.mo
index 1dc03f5..bf142d8 100644
Binary files a/resources/localization/fi/QIDISlicer.mo and b/resources/localization/fi/QIDISlicer.mo differ
diff --git a/resources/localization/fi/QIDISlicer_fi.po b/resources/localization/fi/QIDISlicer_fi.po
index 2b00c22..c52ffc4 100644
--- a/resources/localization/fi/QIDISlicer_fi.po
+++ b/resources/localization/fi/QIDISlicer_fi.po
@@ -28664,4 +28664,25 @@ msgstr ""
"Sinun on poistettava WebView-kansio manuaalisesti.\n"
msgid "Learn more"
-msgstr "Lue lisää"
\ No newline at end of file
+msgstr "Lue lisää"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Vie GCODE.3MF-tiedosto:"
+
+msgid "Export File"
+msgstr "Vie tiedosto"
+
+msgid "Export all gcode.3mf"
+msgstr "Vie kaikki gcode.3mf-tiedostot"
+
+msgid "Sync filament info from the box"
+msgstr "Synkronoi langan tiedot laatikosta"
+
+msgid "Sync Box information"
+msgstr "Synkronoi laatikon tiedot"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Valitse tulostin listasta saadaksesi laatikon tiedot"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Tämä tulostin ei ole yhteydessä laatikkoon, tarkista yhteys."
\ No newline at end of file
diff --git a/resources/localization/fr/QIDISlicer.mo b/resources/localization/fr/QIDISlicer.mo
index 3b36c5e..7cf7ec3 100644
Binary files a/resources/localization/fr/QIDISlicer.mo and b/resources/localization/fr/QIDISlicer.mo differ
diff --git a/resources/localization/fr/QIDISlicer_fr.po b/resources/localization/fr/QIDISlicer_fr.po
index 46fe289..b504f7b 100644
--- a/resources/localization/fr/QIDISlicer_fr.po
+++ b/resources/localization/fr/QIDISlicer_fr.po
@@ -31313,4 +31313,25 @@ msgstr ""
"Vous devez supprimer manuellement le dossier WebView.\n"
msgid "Learn more"
-msgstr "En savoir plus"
\ No newline at end of file
+msgstr "En savoir plus"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Exporter le fichier GCODE.3MF :"
+
+msgid "Export File"
+msgstr "Exporter le fichier"
+
+msgid "Export all gcode.3mf"
+msgstr "Exporter tous les fichiers gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Synchroniser les informations du filament depuis la boîte"
+
+msgid "Sync Box information"
+msgstr "Synchroniser les informations de la boîte"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Veuillez sélectionner l'imprimante dans la liste pour obtenir les informations de la boîte"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Cette imprimante n'est pas connectée à la boîte, veuillez vérifier."
\ No newline at end of file
diff --git a/resources/localization/hu/QIDISlicer.mo b/resources/localization/hu/QIDISlicer.mo
index 37c27a6..5cf3cca 100644
Binary files a/resources/localization/hu/QIDISlicer.mo and b/resources/localization/hu/QIDISlicer.mo differ
diff --git a/resources/localization/hu/QIDISlicer_hu.po b/resources/localization/hu/QIDISlicer_hu.po
index ed4aae4..02b1ee1 100644
--- a/resources/localization/hu/QIDISlicer_hu.po
+++ b/resources/localization/hu/QIDISlicer_hu.po
@@ -30114,4 +30114,25 @@ msgstr ""
"Manuálisan törölnie kell a WebView mappát.\n"
msgid "Learn more"
-msgstr "Tudj meg többet"
\ No newline at end of file
+msgstr "Tudj meg többet"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF fájl exportálása:"
+
+msgid "Export File"
+msgstr "Fájl exportálása"
+
+msgid "Export all gcode.3mf"
+msgstr "Összes gcode.3mf exportálása"
+
+msgid "Sync filament info from the box"
+msgstr "Filament információk szinkronizálása a dobozból"
+
+msgid "Sync Box information"
+msgstr "Doboz információk szinkronizálása"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Válassza ki a nyomtatót a listából a doboz információkhoz"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Ez a nyomtató nincs csatlakoztatva a dobozhoz, kérem ellenőrizze."
\ No newline at end of file
diff --git a/resources/localization/it/QIDISlicer.mo b/resources/localization/it/QIDISlicer.mo
index 62243e3..a9619aa 100644
Binary files a/resources/localization/it/QIDISlicer.mo and b/resources/localization/it/QIDISlicer.mo differ
diff --git a/resources/localization/it/QIDISlicer_it.po b/resources/localization/it/QIDISlicer_it.po
index ee388a7..41ef73a 100644
--- a/resources/localization/it/QIDISlicer_it.po
+++ b/resources/localization/it/QIDISlicer_it.po
@@ -31071,4 +31071,25 @@ msgstr ""
"È necessario eliminare manualmente la cartella WebView.\n"
msgid "Learn more"
-msgstr "Scopri di più"
\ No newline at end of file
+msgstr "Scopri di più"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Esporta file GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Esporta file"
+
+msgid "Export all gcode.3mf"
+msgstr "Esporta tutti i file gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Sincronizza informazioni filamento dalla scatola"
+
+msgid "Sync Box information"
+msgstr "Sincronizza informazioni scatola"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Seleziona la stampante dall'elenco per ottenere informazioni sulla scatola"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Questa stampante non è connessa alla scatola, verificare per favore."
\ No newline at end of file
diff --git a/resources/localization/ja/QIDISlicer.mo b/resources/localization/ja/QIDISlicer.mo
index 985f9a3..2359ff4 100644
Binary files a/resources/localization/ja/QIDISlicer.mo and b/resources/localization/ja/QIDISlicer.mo differ
diff --git a/resources/localization/ja/QIDISlicer_ja.po b/resources/localization/ja/QIDISlicer_ja.po
index 520e4d1..13606b6 100644
--- a/resources/localization/ja/QIDISlicer_ja.po
+++ b/resources/localization/ja/QIDISlicer_ja.po
@@ -30670,4 +30670,25 @@ msgstr ""
"WebViewフォルダを手動で削除する必要があります。\n"
msgid "Learn more"
-msgstr "詳細を見る"
\ No newline at end of file
+msgstr "詳細を見る"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MFファイルをエクスポート:"
+
+msgid "Export File"
+msgstr "ファイルをエクスポート"
+
+msgid "Export all gcode.3mf"
+msgstr "すべてのgcode.3mfをエクスポート"
+
+msgid "Sync filament info from the box"
+msgstr "ボックスからフィラメント情報を同期"
+
+msgid "Sync Box information"
+msgstr "ボックス情報を同期"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "ボックス情報を取得するにはリストからプリンターを選択してください"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "このプリンターはボックスに接続されていません。確認してください。"
\ No newline at end of file
diff --git a/resources/localization/ko/QIDISlicer.mo b/resources/localization/ko/QIDISlicer.mo
index 412b994..f29ee8a 100644
Binary files a/resources/localization/ko/QIDISlicer.mo and b/resources/localization/ko/QIDISlicer.mo differ
diff --git a/resources/localization/ko/QIDISlicer_ko_KR.po b/resources/localization/ko/QIDISlicer_ko_KR.po
index bbcafee..9bbe01d 100644
--- a/resources/localization/ko/QIDISlicer_ko_KR.po
+++ b/resources/localization/ko/QIDISlicer_ko_KR.po
@@ -28907,4 +28907,25 @@ msgstr ""
"WebView 폴더를 수동으로 삭제해야 합니다.\n"
msgid "Learn more"
-msgstr "자세히 알아보기"
\ No newline at end of file
+msgstr "자세히 알아보기"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF 파일 내보내기:"
+
+msgid "Export File"
+msgstr "파일 내보내기"
+
+msgid "Export all gcode.3mf"
+msgstr "모든 gcode.3mf 내보내기"
+
+msgid "Sync filament info from the box"
+msgstr "박스에서 필라멘트 정보 동기화"
+
+msgid "Sync Box information"
+msgstr "박스 정보 동기화"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "박스 정보를 얻으려면 목록에서 프린터를 선택하세요"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "이 프린터는 박스에 연결되어 있지 않습니다. 확인해 주세요."
\ No newline at end of file
diff --git a/resources/localization/ko_KR/QIDISlicer.mo b/resources/localization/ko_KR/QIDISlicer.mo
index bb6c7ec..9786e40 100644
Binary files a/resources/localization/ko_KR/QIDISlicer.mo and b/resources/localization/ko_KR/QIDISlicer.mo differ
diff --git a/resources/localization/ko_KR/QIDISlicer_ko.po b/resources/localization/ko_KR/QIDISlicer_ko.po
index 3c5de78..223d55c 100644
--- a/resources/localization/ko_KR/QIDISlicer_ko.po
+++ b/resources/localization/ko_KR/QIDISlicer_ko.po
@@ -29094,4 +29094,25 @@ msgstr ""
"WebView 폴더를 수동으로 삭제해야 합니다.\n"
msgid "Learn more"
-msgstr "자세히 알아보기"
\ No newline at end of file
+msgstr "자세히 알아보기"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF 파일 내보내기:"
+
+msgid "Export File"
+msgstr "파일 내보내기"
+
+msgid "Export all gcode.3mf"
+msgstr "모든 gcode.3mf 내보내기"
+
+msgid "Sync filament info from the box"
+msgstr "박스에서 필라멘트 정보 동기화"
+
+msgid "Sync Box information"
+msgstr "박스 정보 동기화"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "박스 정보를 얻으려면 목록에서 프린터를 선택하세요"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "이 프린터는 박스에 연결되어 있지 않습니다. 확인해 주세요."
\ No newline at end of file
diff --git a/resources/localization/ko_KR/QIDISlicer_ko_KR.mo b/resources/localization/ko_KR/QIDISlicer_ko_KR.mo
index fdcb0cf..39b90bd 100644
Binary files a/resources/localization/ko_KR/QIDISlicer_ko_KR.mo and b/resources/localization/ko_KR/QIDISlicer_ko_KR.mo differ
diff --git a/resources/localization/ko_KR/QIDISlicer_ko_KR.po b/resources/localization/ko_KR/QIDISlicer_ko_KR.po
index b7ff700..dd9a1f4 100644
--- a/resources/localization/ko_KR/QIDISlicer_ko_KR.po
+++ b/resources/localization/ko_KR/QIDISlicer_ko_KR.po
@@ -29094,4 +29094,25 @@ msgstr ""
"WebView 폴더를 수동으로 삭제해야 합니다.\n"
msgid "Learn more"
-msgstr "자세히 알아보기"
\ No newline at end of file
+msgstr "자세히 알아보기"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF 파일 내보내기:"
+
+msgid "Export File"
+msgstr "파일 내보내기"
+
+msgid "Export all gcode.3mf"
+msgstr "모든 gcode.3mf 내보내기"
+
+msgid "Sync filament info from the box"
+msgstr "박스에서 필라멘트 정보 동기화"
+
+msgid "Sync Box information"
+msgstr "박스 정보 동기화"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "박스 정보를 얻으려면 목록에서 프린터를 선택하세요"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "이 프린터는 박스에 연결되어 있지 않습니다. 확인해 주세요."
\ No newline at end of file
diff --git a/resources/localization/nl/QIDISlicer.mo b/resources/localization/nl/QIDISlicer.mo
index 994ea27..a83aa48 100644
Binary files a/resources/localization/nl/QIDISlicer.mo and b/resources/localization/nl/QIDISlicer.mo differ
diff --git a/resources/localization/nl/QIDISlicer_nl.po b/resources/localization/nl/QIDISlicer_nl.po
index e29385e..ad5347d 100644
--- a/resources/localization/nl/QIDISlicer_nl.po
+++ b/resources/localization/nl/QIDISlicer_nl.po
@@ -29721,4 +29721,25 @@ msgstr ""
"U moet de WebView-map handmatig verwijderen.\n"
msgid "Learn more"
-msgstr "Meer informatie"
\ No newline at end of file
+msgstr "Meer informatie"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF-bestand exporteren:"
+
+msgid "Export File"
+msgstr "Bestand exporteren"
+
+msgid "Export all gcode.3mf"
+msgstr "Alle gcode.3mf exporteren"
+
+msgid "Sync filament info from the box"
+msgstr "Filamentinformatie synchroniseren vanuit de box"
+
+msgid "Sync Box information"
+msgstr "Boxinformatie synchroniseren"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Selecteer de printer in de lijst om boxinformatie te krijgen"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Deze printer is niet verbonden met de box, controleer dit alstublieft."
\ No newline at end of file
diff --git a/resources/localization/pl/QIDISlicer.mo b/resources/localization/pl/QIDISlicer.mo
index 78afaee..7554af3 100644
Binary files a/resources/localization/pl/QIDISlicer.mo and b/resources/localization/pl/QIDISlicer.mo differ
diff --git a/resources/localization/pl/QIDISlicer_pl.po b/resources/localization/pl/QIDISlicer_pl.po
index dfe6558..8b36834 100644
--- a/resources/localization/pl/QIDISlicer_pl.po
+++ b/resources/localization/pl/QIDISlicer_pl.po
@@ -31058,4 +31058,25 @@ msgstr ""
"Musisz ręcznie usunąć folder WebView.\n"
msgid "Learn more"
-msgstr "Dowiedz się więcej"
\ No newline at end of file
+msgstr "Dowiedz się więcej"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Eksportuj plik GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Eksportuj plik"
+
+msgid "Export all gcode.3mf"
+msgstr "Eksportuj wszystkie pliki gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Synchronizuj informacje o filamentach z boxa"
+
+msgid "Sync Box information"
+msgstr "Synchronizuj informacje z boxa"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Wybierz drukarkę z listy, aby uzyskać informacje o boxie"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Ta drukarka nie jest podłączona do boxa, proszę to sprawdzić."
\ No newline at end of file
diff --git a/resources/localization/pt_BR/QIDISlicer.mo b/resources/localization/pt_BR/QIDISlicer.mo
index 868479d..d950837 100644
Binary files a/resources/localization/pt_BR/QIDISlicer.mo and b/resources/localization/pt_BR/QIDISlicer.mo differ
diff --git a/resources/localization/pt_BR/QIDISlicer_pt_BR.po b/resources/localization/pt_BR/QIDISlicer_pt_BR.po
index 86939b0..ff3ab05 100644
--- a/resources/localization/pt_BR/QIDISlicer_pt_BR.po
+++ b/resources/localization/pt_BR/QIDISlicer_pt_BR.po
@@ -29756,4 +29756,25 @@ msgstr ""
"Você precisa excluir manualmente a pasta WebView.\n"
msgid "Learn more"
-msgstr "Saiba mais"
\ No newline at end of file
+msgstr "Saiba mais"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Exportar arquivo GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Exportar arquivo"
+
+msgid "Export all gcode.3mf"
+msgstr "Exportar todos os arquivos gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Sincronizar informações do filamento da caixa"
+
+msgid "Sync Box information"
+msgstr "Sincronizar informações da caixa"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Selecione a impressora na lista para obter informações da caixa"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Esta impressora não está conectada à caixa, verifique."
\ No newline at end of file
diff --git a/resources/localization/ru/QIDISlicer.mo b/resources/localization/ru/QIDISlicer.mo
index 60c4d30..16cc643 100644
Binary files a/resources/localization/ru/QIDISlicer.mo and b/resources/localization/ru/QIDISlicer.mo differ
diff --git a/resources/localization/ru/QIDISlicer_ru.po b/resources/localization/ru/QIDISlicer_ru.po
index 2c9eed2..458238e 100644
--- a/resources/localization/ru/QIDISlicer_ru.po
+++ b/resources/localization/ru/QIDISlicer_ru.po
@@ -30770,4 +30770,25 @@ msgstr ""
"Вам нужно вручную удалить папку WebView.\n"
msgid "Learn more"
-msgstr "Узнать больше"
\ No newline at end of file
+msgstr "Узнать больше"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Экспорт файла GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Экспорт файла"
+
+msgid "Export all gcode.3mf"
+msgstr "Экспортировать все файлы gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Синхронизировать информацию о филаменте из бокса"
+
+msgid "Sync Box information"
+msgstr "Синхронизировать информацию бокса"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Выберите принтер из списка для получения информации о боксе"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Этот принтер не подключен к боксу, пожалуйста, проверьте подключение."
\ No newline at end of file
diff --git a/resources/localization/sl/QIDISlicer.mo b/resources/localization/sl/QIDISlicer.mo
index cb3c609..88dac7e 100644
Binary files a/resources/localization/sl/QIDISlicer.mo and b/resources/localization/sl/QIDISlicer.mo differ
diff --git a/resources/localization/sl/QIDISlicer.po b/resources/localization/sl/QIDISlicer.po
index 6bb659e..dd70a26 100644
--- a/resources/localization/sl/QIDISlicer.po
+++ b/resources/localization/sl/QIDISlicer.po
@@ -29499,4 +29499,25 @@ msgstr ""
"Mapo WebView morate ročno izbrisati.\n"
msgid "Learn more"
-msgstr "Izvedi več"
\ No newline at end of file
+msgstr "Izvedi več"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Izvozi datoteko GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Izvozi datoteko"
+
+msgid "Export all gcode.3mf"
+msgstr "Izvozi vse datoteke gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Sinhroniziraj informacije o filamentu iz škatle"
+
+msgid "Sync Box information"
+msgstr "Sinhroniziraj informacije škatle"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Izberite tiskalnik s seznama za pridobitev informacij o škatli"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Ta tiskalnik ni povezan s škatlo, prosimo preverite."
\ No newline at end of file
diff --git a/resources/localization/tr/QIDISlicer.mo b/resources/localization/tr/QIDISlicer.mo
index 2222dc1..c3239b0 100644
Binary files a/resources/localization/tr/QIDISlicer.mo and b/resources/localization/tr/QIDISlicer.mo differ
diff --git a/resources/localization/tr/QIDISlicer_tr.po b/resources/localization/tr/QIDISlicer_tr.po
index 3401172..74ca826 100644
--- a/resources/localization/tr/QIDISlicer_tr.po
+++ b/resources/localization/tr/QIDISlicer_tr.po
@@ -29808,4 +29808,25 @@ msgstr ""
"WebView klasörünü manuel olarak silmeniz gerekiyor.\n"
msgid "Learn more"
-msgstr "Daha fazla bilgi edin"
\ No newline at end of file
+msgstr "Daha fazla bilgi edin"
+
+msgid "Export GCODE.3MF file:"
+msgstr "GCODE.3MF dosyasını dışa aktar:"
+
+msgid "Export File"
+msgstr "Dosyayı Dışa Aktar"
+
+msgid "Export all gcode.3mf"
+msgstr "Tüm gcode.3mf dosyalarını dışa aktar"
+
+msgid "Sync filament info from the box"
+msgstr "Kutudan filament bilgilerini senkronize et"
+
+msgid "Sync Box information"
+msgstr "Kutu bilgilerini senkronize et"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Kutu bilgilerini almak için listeden yazıcıyı seçin"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Bu yazıcı kutuya bağlı değil, lütfen kontrol edin."
\ No newline at end of file
diff --git a/resources/localization/uk/QIDISlicer.mo b/resources/localization/uk/QIDISlicer.mo
index af07e5f..0f67a81 100644
Binary files a/resources/localization/uk/QIDISlicer.mo and b/resources/localization/uk/QIDISlicer.mo differ
diff --git a/resources/localization/uk/QIDISlicer_uk.po b/resources/localization/uk/QIDISlicer_uk.po
index 527fb27..0d7d754 100644
--- a/resources/localization/uk/QIDISlicer_uk.po
+++ b/resources/localization/uk/QIDISlicer_uk.po
@@ -29239,4 +29239,25 @@ msgstr ""
"Вам потрібно вручну видалити теку WebView.\n"
msgid "Learn more"
-msgstr "Дізнатися більше"
\ No newline at end of file
+msgstr "Дізнатися більше"
+
+msgid "Export GCODE.3MF file:"
+msgstr "Експортувати файл GCODE.3MF:"
+
+msgid "Export File"
+msgstr "Експортувати файл"
+
+msgid "Export all gcode.3mf"
+msgstr "Експортувати всі файли gcode.3mf"
+
+msgid "Sync filament info from the box"
+msgstr "Синхронізувати інформацію про філамент із коробки"
+
+msgid "Sync Box information"
+msgstr "Синхронізувати інформацію коробки"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "Виберіть принтер зі списку, щоб отримати інформацію про коробку"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "Цей принтер не підключений до коробки, будь ласка, перевірте."
\ No newline at end of file
diff --git a/resources/localization/zh_CN/QIDISlicer.mo b/resources/localization/zh_CN/QIDISlicer.mo
index ba0772b..1988f1e 100644
Binary files a/resources/localization/zh_CN/QIDISlicer.mo and b/resources/localization/zh_CN/QIDISlicer.mo differ
diff --git a/resources/localization/zh_CN/QIDISlicer_zh_CN.po b/resources/localization/zh_CN/QIDISlicer_zh_CN.po
index f4d3d4d..c6429ca 100644
--- a/resources/localization/zh_CN/QIDISlicer_zh_CN.po
+++ b/resources/localization/zh_CN/QIDISlicer_zh_CN.po
@@ -28995,4 +28995,25 @@ msgstr ""
"您需要手动删除WebView文件夹。\n"
msgid "Learn more"
-msgstr "了解更多"
\ No newline at end of file
+msgstr "了解更多"
+
+msgid "Export GCODE.3MF file:"
+msgstr "导出GCODE.3MF文件:"
+
+msgid "Export File"
+msgstr "导出文件"
+
+msgid "Export all gcode.3mf"
+msgstr "导出所有gcode.3mf文件"
+
+msgid "Sync filament info from the box"
+msgstr "从盒子同步线材信息"
+
+msgid "Sync Box information"
+msgstr "同步盒子信息"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "请从列表中选择打印机以获取盒子信息"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "此打印机未连接盒子,请检查。"
\ No newline at end of file
diff --git a/resources/localization/zh_TW/QIDISlicer.mo b/resources/localization/zh_TW/QIDISlicer.mo
index 5f3c68e..924a9e4 100644
Binary files a/resources/localization/zh_TW/QIDISlicer.mo and b/resources/localization/zh_TW/QIDISlicer.mo differ
diff --git a/resources/localization/zh_TW/QIDISlicer_zh_TW.po b/resources/localization/zh_TW/QIDISlicer_zh_TW.po
index 8190f0d..85ad2ce 100644
--- a/resources/localization/zh_TW/QIDISlicer_zh_TW.po
+++ b/resources/localization/zh_TW/QIDISlicer_zh_TW.po
@@ -29081,4 +29081,25 @@ msgstr ""
"您需要手動刪除WebView資料夾。\n"
msgid "Learn more"
-msgstr "瞭解更多"
\ No newline at end of file
+msgstr "瞭解更多"
+
+msgid "Export GCODE.3MF file:"
+msgstr "匯出GCODE.3MF檔案:"
+
+msgid "Export File"
+msgstr "匯出檔案"
+
+msgid "Export all gcode.3mf"
+msgstr "匯出所有gcode.3mf檔案"
+
+msgid "Sync filament info from the box"
+msgstr "從盒子同步線材資訊"
+
+msgid "Sync Box information"
+msgstr "同步盒子資訊"
+
+msgid "Please select the printer in the list to get box info"
+msgstr "請從清單中選擇印表機以取得盒子資訊"
+
+msgid "This Printer has not connect the box, please check."
+msgstr "此印表機未連接盒子,請檢查。"
\ No newline at end of file
diff --git a/resources/profiles/QIDITechnology.ini b/resources/profiles/QIDITechnology.ini
index 80b158d..3cf43f1 100644
--- a/resources/profiles/QIDITechnology.ini
+++ b/resources/profiles/QIDITechnology.ini
@@ -15,6 +15,15 @@ force_update = 1
# also the first model installed & the first nozzle installed will be activated after install.
# Printer model name will be shown by the installation wizard.
+[printer_model:Q2]
+name = Q2
+variants = 0.4; 0.2; 0.6; 0.8
+technology = FFF
+family = Q
+bed_model = Q2_bed.stl
+bed_texture = Q2_bed.svg
+default_materials = QIDI ABS Odorless @Q2 0.4 nozzle
+
[printer_model:X-Plus 4]
name = X-Plus 4
variants = 0.4; 0.2; 0.6; 0.8
@@ -256,6 +265,10 @@ xy_contour_compensation = 0
xy_hole_compensation = 0
# Machine Print preset
+[print:*Q2*]
+inherits = *common*
+wipe_tower = 1
+
[print:*X-Plus 4*]
inherits = *common*
wipe_tower = 1
@@ -425,6 +438,63 @@ inherits = *0.8 nozzle*
layer_height = 0.48
# Print preset
+
+# Q2 0.2 nozzle Print preset
+[print:0.08mm Extra High @Q2 0.2 nozzle]
+inherits = *Q2*; *0.08mm Extra High*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[print:0.12mm Fine @Q2 0.2 nozzle]
+inherits = *Q2*; *0.12mm Fine*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+# Q2 0.4 nozzle Print preset
+[print:0.12mm Extra High @Q2 0.4 nozzle]
+inherits = *Q2*; *0.12mm Extra High*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[print:0.16mm High @Q2 0.4 nozzle]
+inherits = *Q2*; *0.16mm High*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[print:0.20mm Fine @Q2 0.4 nozzle]
+inherits = *Q2*; *0.20mm Fine*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[print:0.20mm Strength @Q2 0.4 nozzle]
+inherits = *Q2*; *0.20mm Strength*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[print:0.24mm Quick @Q2 0.4 nozzle]
+inherits = *Q2*; *0.24mm Quick*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+# Q2 4 0.6 nozzle Print preset
+[print:0.24mm High @Q2 0.6 nozzle]
+inherits = *Q2*; *0.24mm High*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[print:0.30mm Fine @Q2 0.6 nozzle]
+inherits = *Q2*; *0.30mm Fine*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[print:0.36mm Fine @Q2 0.6 nozzle]
+inherits = *Q2*; *0.36mm Quick*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+# Q2 0.8 nozzle Print preset
+[print:0.32mm High @Q2 0.8 nozzle]
+inherits = *Q2*; *0.32mm High*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[print:0.40mm Fine @Q2 0.8 nozzle]
+inherits = *Q2*; *0.40mm Fine*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[print:0.48mm Fine @Q2 0.8 nozzle]
+inherits = *Q2*; *0.48mm Quick*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
# X-Plus 4 0.2 nozzle Print preset
[print:0.08mm Extra High @X-Plus 4 0.2 nozzle]
inherits = *X-Plus 4*; *0.08mm Extra High*
@@ -874,7 +944,7 @@ chamber_temperature = 55
[filament:*QIDI ABS-GF*]
inherits = *common*
advance_pressure = 0.01
-bed_temperature = 100
+bed_temperature = 90
disable_fan_first_layers = 3
enable_auxiliary_fan = 0
enable_dynamic_fan_speeds = 1
@@ -885,7 +955,7 @@ filament_density = 1.15
filament_flush_temp = 280
filament_max_volumetric_speed = 12
filament_type = ABS-GF
-first_layer_bed_temperature = 100
+first_layer_bed_temperature = 90
first_layer_temperature = 270
max_fan_speed = 20
min_fan_speed = 20
@@ -1610,6 +1680,1124 @@ temperature = 250
inherits = *common*
filament_vendor = HATCHBOX
+# Q2 0.2 nozzle QIDI filament preset
+[filament:QIDI ABS Odorless @Q2 0.2 nozzle]
+inherits = *QIDI ABS Odorless*
+filament_max_volumetric_speed = 2
+temperature = 260
+chamber_temperature = 0
+filament_id = QD_1_1_14
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI ABS Rapido @Q2 0.2 nozzle]
+inherits = *QIDI ABS Rapido*
+filament_max_volumetric_speed = 2
+temperature = 260
+chamber_temperature = 0
+filament_id = QD_1_1_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI ABS Rapido Metal @Q2 0.2 nozzle]
+inherits = *QIDI ABS Rapido Metal*
+advance_pressure = 0.03
+filament_max_volumetric_speed = 2
+temperature = 260
+chamber_temperature = 0
+filament_id = QD_1_1_13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI ASA @Q2 0.2 nozzle]
+inherits = *QIDI ASA*
+filament_max_volumetric_speed = 2
+temperature = 255
+chamber_temperature = 0
+filament_id = QD_1_1_18
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI PETG-Tough @Q2 0.2 nozzle]
+inherits = *QIDI PETG-Tough*
+filament_max_volumetric_speed = 1
+filament_id = QD_1_1_40
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI PLA Rapido @Q2 0.2 nozzle]
+inherits = *QIDI PLA Rapido*
+filament_max_volumetric_speed = 2
+temperature = 210
+filament_id = QD_1_1_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI PLA Rapido Matte @Q2 0.2 nozzle]
+inherits = *QIDI PLA Rapido Matte*
+filament_max_volumetric_speed = 2
+temperature = 210
+filament_id = QD_1_1_2
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:QIDI PLA Rapido Metal @Q2 0.2 nozzle]
+inherits = *QIDI PLA Rapido Metal*
+advance_pressure = 0.038
+filament_max_volumetric_speed = 2
+temperature = 210
+filament_id = QD_1_1_3
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+# Q2 0.2 nozzle Generic filament preset
+[filament:Generic ABS @Q2 0.2 nozzle]
+inherits = *Generic ABS*
+filament_max_volumetric_speed = 2
+temperature = 250
+filament_id = QD_0_0_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Generic PETG @Q2 0.2 nozzle]
+inherits = *Generic PETG*
+filament_max_volumetric_speed = 1
+first_layer_temperature = 245
+filament_id = QD_0_0_41
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Generic PLA @Q2 0.2 nozzle]
+inherits = *Generic PLA*
+first_layer_temperature = 220
+filament_max_volumetric_speed = 2
+temperature = 220
+filament_id = QD_0_0_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Generic PLA+ @Q2 0.2 nozzle]
+inherits = *Generic PLA+*
+first_layer_temperature = 230
+filament_max_volumetric_speed = 2
+temperature = 230
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Generic PC @Q2 0.2 nozzle]
+inherits = *Generic PC*
+filament_max_volumetric_speed = 1
+extrusion_multiplier = 0.94
+chamber_minimal_temperature = 0
+chamber_temperature = 0
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:PolyLite ABS @Q2 0.2 nozzle]
+inherits = *PolyLite ABS*
+advance_pressure = 0.054
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 2
+slowdown_below_layer_time = 6
+temperature = 255
+chamber_temperature = 0
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:PolyLite PLA @Q2 0.2 nozzle]
+inherits = *PolyLite PLA*
+advance_pressure = 0.062
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 2
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Overture ABS @Q2 0.2 nozzle]
+inherits = *Overture ABS*
+advance_pressure = 0.054
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 2
+slowdown_below_layer_time = 6
+temperature = 255
+chamber_temperature = 0
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Overture PLA @Q2 0.2 nozzle]
+inherits = *Overture PLA*
+advance_pressure = 0.062
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 2
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Bambu ABS @Q2 0.2 nozzle]
+inherits = *Bambu ABS*
+filament_max_volumetric_speed = 2
+temperature = 260
+chamber_temperature = 0
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Bambu PETG @Q2 0.2 nozzle]
+inherits = *Bambu PETG*
+filament_max_volumetric_speed = 1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:Bambu PLA @Q2 0.2 nozzle]
+inherits = *Bambu PLA*
+filament_max_volumetric_speed = 2
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:HATCHBOX ABS @Q2 0.2 nozzle]
+inherits = *HATCHBOX ABS*
+filament_max_volumetric_speed = 2
+temperature = 260
+chamber_temperature = 0
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:HATCHBOX PETG @Q2 0.2 nozzle]
+inherits = *HATCHBOX PETG*
+filament_max_volumetric_speed = 1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+[filament:HATCHBOX PLA @Q2 0.2 nozzle]
+inherits = *HATCHBOX PLA*
+filament_max_volumetric_speed = 2
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.2
+
+# Q2 0.4 nozzle QIDI filament preset
+[filament:QIDI ABS Odorless @Q2 0.4 nozzle]
+inherits = *QIDI ABS Odorless*
+advance_pressure = 0.03
+chamber_minimal_temperature = 55
+temperature = 260
+filament_id = QD_1_1_14
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI ABS Rapido @Q2 0.4 nozzle]
+inherits = *QIDI ABS Rapido*
+advance_pressure = 0.03
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 260
+filament_id = QD_1_1_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI ABS Rapido Metal @Q2 0.4 nozzle]
+inherits = *QIDI ABS Rapido Metal*
+advance_pressure = 0.03
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 260
+filament_id = QD_1_1_13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI ABS-GF @Q2 0.4 nozzle]
+inherits = *QIDI ABS-GF*
+advance_pressure = 0.03
+chamber_minimal_temperature = 0
+filament_max_volumetric_speed = 12
+first_layer_temperature = 260
+temperature = 270
+filament_id = QD_1_1_12
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI ASA @Q2 0.4 nozzle]
+inherits = *QIDI ASA*
+advance_pressure = 0.03
+chamber_minimal_temperature = 55
+temperature = 255
+filament_id = QD_1_1_18
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI ASA-Aero @Q2 0.4 nozzle]
+inherits = *QIDI ASA-Aero*
+chamber_minimal_temperature = 60
+temperature = 260
+filament_id = QD_1_1_19
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PA12-CF @Q2 0.4 nozzle]
+inherits = *QIDI PA12-CF*
+advance_pressure = 0.035
+filament_max_volumetric_speed = 8
+first_layer_temperature = 280
+temperature = 280
+filament_id = QD_1_1_27
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PAHT-CF @Q2 0.4 nozzle]
+inherits = *QIDI PAHT-CF*
+advance_pressure = 0.032
+first_layer_temperature = 300
+temperature = 300
+filament_id = QD_1_1_30
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PAHT-GF @Q2 0.4 nozzle]
+inherits = *QIDI PAHT-GF*
+advance_pressure = 0.027
+first_layer_temperature = 300
+temperature = 300
+filament_id = QD_1_1_31
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PC/ABS-FR @Q2 0.4 nozzle]
+inherits = *QIDI PC/ABS-FR*
+advance_pressure = 0.042
+chamber_minimal_temperature = 55
+filament_id = QD_1_1_34
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PET-CF @Q2 0.4 nozzle]
+inherits = *QIDI PET-CF*
+advance_pressure = 0.032
+filament_max_volumetric_speed = 8
+first_layer_temperature = 280
+temperature = 280
+filament_id = QD_1_1_37
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PETG-Tough @Q2 0.4 nozzle]
+inherits = *QIDI PETG-Tough*
+advance_pressure = 0.056
+filament_max_volumetric_speed = 13
+filament_id = QD_1_1_40
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PET-GF @Q2 0.4 nozzle]
+inherits = *QIDI PET-GF*
+advance_pressure = 0.022
+filament_max_volumetric_speed = 10
+first_layer_temperature = 310
+temperature = 310
+filament_id = QD_1_1_38
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PLA Rapido @Q2 0.4 nozzle]
+inherits = *QIDI PLA Rapido*
+advance_pressure = 0.034
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PLA Rapido Matte @Q2 0.4 nozzle]
+inherits = *QIDI PLA Rapido Matte*
+advance_pressure = 0.034
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_2
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PLA Rapido Metal @Q2 0.4 nozzle]
+inherits = *QIDI PLA Rapido Metal*
+advance_pressure = 0.038
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_3
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PLA Rapido Silk @Q2 0.4 nozzle]
+inherits = *QIDI PLA Rapido Silk*
+advance_pressure = 0.034
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_1_1_4
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PLA-CF @Q2 0.4 nozzle]
+inherits = *QIDI PLA-CF*
+advance_pressure = 0.034
+extrusion_multiplier = 0.93
+filament_max_volumetric_speed = 15
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_1_1_5
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI PPS-CF @Q2 0.4 nozzle]
+inherits = *QIDI PPS-CF*
+advance_pressure = 0.03
+chamber_minimal_temperature = 60
+filament_id = QD_1_1_44
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI TPU 95A-HF @Q2 0.4 nozzle]
+inherits = *QIDI TPU 95A-HF*
+filament_id = QD_1_1_50
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI UltraPA @Q2 0.4 nozzle]
+inherits = *QIDI UltraPA*
+filament_max_volumetric_speed = 4
+filament_id = QD_1_1_24
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI UltraPA-CF25 @Q2 0.4 nozzle]
+inherits = *QIDI UltraPA-CF25*
+advance_pressure = 0.026
+filament_id = QD_1_1_26
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI WOOD Rapido @Q2 0.4 nozzle]
+inherits = *QIDI WOOD Rapido*
+advance_pressure = 0.044
+filament_max_volumetric_speed = 18
+temperature = 210
+filament_id = QD_1_1_6
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI TPU-Aero @Q2 0.4 nozzle]
+inherits = *QIDI TPU-Aero*
+filament_id = QD_1_1_49
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI Support For PET/PA @Q2 0.4 nozzle]
+inherits = *QIDI Support For PET/PA*
+filament_id = QD_1_1_33
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:QIDI Support For PAHT @Q2 0.4 nozzle]
+inherits = *QIDI Support For PAHT*
+filament_id = QD_1_1_32
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+# Q2 0.4 nozzle Generic filament preset
+[filament:Generic ABS @Q2 0.4 nozzle]
+inherits = *Generic ABS*
+advance_pressure = 0.03
+temperature = 250
+filament_id = QD_0_0_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Generic PETG @Q2 0.4 nozzle]
+inherits = *Generic PETG*
+advance_pressure = 0.056
+first_layer_temperature = 245
+filament_id = QD_0_0_41
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Generic PLA @Q2 0.4 nozzle]
+inherits = *Generic PLA*
+advance_pressure = 0.034
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_0_0_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Generic PLA+ @Q2 0.4 nozzle]
+inherits = *Generic PLA+*
+advance_pressure = 0.034
+first_layer_temperature = 230
+temperature = 230
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Generic PLA Silk @Q2 0.4 nozzle]
+inherits = *Generic PLA Silk*
+advance_pressure = 0.032
+filament_id = QD_0_0_4
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Generic TPU 95A @Q2 0.4 nozzle]
+inherits = *Generic TPU 95A*
+filament_id = QD_0_0_50
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Generic PC @Q2 0.4 nozzle]
+inherits = *Generic PC*
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:PolyLite ABS @Q2 0.4 nozzle]
+inherits = *PolyLite ABS*
+advance_pressure = 0.033
+chamber_minimal_temperature = 60
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 17
+slowdown_below_layer_time = 6
+temperature = 255
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:PolyLite PLA @Q2 0.4 nozzle]
+inherits = *PolyLite PLA*
+advance_pressure = 0.037
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 11
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Overture ABS @Q2 0.4 nozzle]
+inherits = *Overture ABS*
+advance_pressure = 0.033
+chamber_minimal_temperature = 60
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 17
+slowdown_below_layer_time = 6
+temperature = 255
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Overture PLA @Q2 0.4 nozzle]
+inherits = *Overture PLA*
+advance_pressure = 0.037
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 11
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Bambu ABS @Q2 0.4 nozzle]
+inherits = *Bambu ABS*
+advance_pressure = 0.03
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 260
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Bambu PETG @Q2 0.4 nozzle]
+inherits = *Bambu PETG*
+advance_pressure = 0.056
+filament_max_volumetric_speed = 13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:Bambu PLA @Q2 0.4 nozzle]
+inherits = *Bambu PLA*
+advance_pressure = 0.034
+filament_max_volumetric_speed = 24.5
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:HATCHBOX ABS @Q2 0.4 nozzle]
+inherits = *HATCHBOX ABS*
+advance_pressure = 0.03
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 260
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:HATCHBOX PETG @Q2 0.4 nozzle]
+inherits = *HATCHBOX PETG*
+advance_pressure = 0.056
+filament_max_volumetric_speed = 13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+[filament:HATCHBOX PLA @Q2 0.4 nozzle]
+inherits = *HATCHBOX PLA*
+advance_pressure = 0.034
+filament_max_volumetric_speed = 24.5
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.4
+
+# Q2 0.6 nozzle QIDI filament preset
+[filament:QIDI ABS Odorless @Q2 0.6 nozzle]
+inherits = *QIDI ABS Odorless*
+advance_pressure = 0.014
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 250
+filament_id = QD_1_1_14
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI ABS Rapido @Q2 0.6 nozzle]
+inherits = *QIDI ABS Rapido*
+advance_pressure = 0.014
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 250
+filament_id = QD_1_1_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI ABS Rapido Metal @Q2 0.6 nozzle]
+inherits = *QIDI ABS Rapido Metal*
+advance_pressure = 0.016
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 250
+filament_id = QD_1_1_13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI ABS-GF @Q2 0.6 nozzle]
+inherits = *QIDI ABS-GF*
+chamber_minimal_temperature = 0
+filament_max_volumetric_speed = 12
+first_layer_temperature = 260
+temperature = 270
+filament_id = QD_1_1_12
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI ASA @Q2 0.6 nozzle]
+inherits = *QIDI ASA*
+advance_pressure = 0.014
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 13
+temperature = 255
+filament_id = QD_1_1_18
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PA12-CF @Q2 0.6 nozzle]
+inherits = *QIDI PA12-CF*
+advance_pressure = 0.035
+filament_max_volumetric_speed = 8
+first_layer_temperature = 280
+temperature = 280
+filament_id = QD_1_1_27
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PAHT-CF @Q2 0.6 nozzle]
+inherits = *QIDI PAHT-CF*
+advance_pressure = 0.032
+first_layer_temperature = 300
+temperature = 300
+filament_id = QD_1_1_30
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PAHT-GF @Q2 0.6 nozzle]
+inherits = *QIDI PAHT-GF*
+advance_pressure = 0.015
+first_layer_temperature = 300
+temperature = 300
+filament_id = QD_1_1_31
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PC/ABS-FR @Q2 0.6 nozzle]
+inherits = *QIDI PC/ABS-FR*
+advance_pressure = 0.031
+chamber_minimal_temperature = 55
+filament_id = QD_1_1_34
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PET-CF @Q2 0.6 nozzle]
+inherits = *QIDI PET-CF*
+advance_pressure = 0.025
+filament_max_volumetric_speed = 8
+first_layer_temperature = 280
+temperature = 280
+filament_id = QD_1_1_37
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PETG-Tough @Q2 0.6 nozzle]
+inherits = *QIDI PETG-Tough*
+filament_max_volumetric_speed = 13
+filament_id = QD_1_1_40
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PET-GF @Q2 0.6 nozzle]
+inherits = *QIDI PET-GF*
+advance_pressure = 0.014
+filament_max_volumetric_speed = 10
+first_layer_temperature = 310
+temperature = 310
+filament_id = QD_1_1_38
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PLA Rapido @Q2 0.6 nozzle]
+inherits = *QIDI PLA Rapido*
+advance_pressure = 0.016
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PLA Rapido Matte @Q2 0.6 nozzle]
+inherits = *QIDI PLA Rapido Matte*
+advance_pressure = 0.016
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_2
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PLA Rapido Metal @Q2 0.6 nozzle]
+inherits = *QIDI PLA Rapido Metal*
+advance_pressure = 0.020
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_3
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PLA Rapido Silk @Q2 0.6 nozzle]
+inherits = *QIDI PLA Rapido Silk*
+advance_pressure = 0.021
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_1_1_4
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PLA-CF @Q2 0.6 nozzle]
+inherits = *QIDI PLA-CF*
+advance_pressure = 0.012
+extrusion_multiplier = 0.93
+filament_max_volumetric_speed = 15
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_1_1_5
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI PPS-CF @Q2 0.6 nozzle]
+inherits = *QIDI PPS-CF*
+advance_pressure = 0.021
+chamber_minimal_temperature = 60
+filament_id = QD_1_1_44
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI TPU 95A-HF @Q2 0.6 nozzle]
+inherits = *QIDI TPU 95A-HF*
+filament_id = QD_1_1_50
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI UltraPA @Q2 0.6 nozzle]
+inherits = *QIDI UltraPA*
+filament_max_volumetric_speed = 4
+filament_id = QD_1_1_24
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI UltraPA-CF25 @Q2 0.6 nozzle]
+inherits = *QIDI UltraPA-CF25*
+advance_pressure = 0.022
+filament_id = QD_1_1_26
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI WOOD Rapido @Q2 0.6 nozzle]
+inherits = *QIDI WOOD Rapido*
+advance_pressure = 0.024
+filament_max_volumetric_speed = 18
+temperature = 210
+filament_id = QD_1_1_6
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI TPU-Aero @Q2 0.6 nozzle]
+inherits = *QIDI TPU-Aero*
+filament_id = QD_1_1_49
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI Support For PET/PA @Q2 0.6 nozzle]
+inherits = *QIDI Support For PET/PA*
+filament_id = QD_1_1_33
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:QIDI Support For PAHT @Q2 0.6 nozzle]
+inherits = *QIDI Support For PAHT*
+filament_id = QD_1_1_32
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+# Q2 0.6 nozzle Generic filament preset
+[filament:Generic ABS @Q2 0.6 nozzle]
+inherits = *Generic ABS*
+advance_pressure = 0.014
+filament_max_volumetric_speed = 24.5
+temperature = 250
+filament_id = QD_0_0_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Generic PETG @Q2 0.6 nozzle]
+inherits = *Generic PETG*
+first_layer_temperature = 245
+filament_id = QD_0_0_41
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Generic PLA @Q2 0.6 nozzle]
+inherits = *Generic PLA*
+advance_pressure = 0.016
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_0_0_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Generic PLA+ @Q2 0.6 nozzle]
+inherits = *Generic PLA+*
+advance_pressure = 0.016
+first_layer_temperature = 230
+temperature = 230
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Generic PLA Silk @Q2 0.6 nozzle]
+inherits = *Generic PLA Silk*
+advance_pressure = 0.014
+filament_id = QD_0_0_4
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Generic TPU 95A @Q2 0.6 nozzle]
+inherits = *Generic TPU 95A*
+filament_id = QD_0_0_50
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Generic PC @Q2 0.6 nozzle]
+inherits = *Generic PC*
+advance_pressure = 0.03
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:PolyLite ABS @Q2 0.6 nozzle]
+inherits = *PolyLite ABS*
+advance_pressure = 0.02
+chamber_minimal_temperature = 60
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 17
+slowdown_below_layer_time = 6
+temperature = 255
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:PolyLite PLA @Q2 0.6 nozzle]
+inherits = *PolyLite PLA*
+advance_pressure = 0.019
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 11
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Overture ABS @Q2 0.6 nozzle]
+inherits = *Overture ABS*
+advance_pressure = 0.02
+chamber_minimal_temperature = 60
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 17
+slowdown_below_layer_time = 6
+temperature = 255
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Overture PLA @Q2 0.6 nozzle]
+inherits = *Overture PLA*
+advance_pressure = 0.019
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 11
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Bambu ABS @Q2 0.6 nozzle]
+inherits = *Bambu ABS*
+advance_pressure = 0.014
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 250
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Bambu PETG @Q2 0.6 nozzle]
+inherits = *Bambu PETG*
+filament_max_volumetric_speed = 13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:Bambu PLA @Q2 0.6 nozzle]
+inherits = *Bambu PLA*
+advance_pressure = 0.016
+filament_max_volumetric_speed = 24.5
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:HATCHBOX ABS @Q2 0.6 nozzle]
+inherits = *HATCHBOX ABS*
+advance_pressure = 0.014
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+temperature = 250
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:HATCHBOX PETG @Q2 0.6 nozzle]
+inherits = *HATCHBOX PETG*
+filament_max_volumetric_speed = 13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+[filament:HATCHBOX PLA @Q2 0.6 nozzle]
+inherits = *HATCHBOX PLA*
+advance_pressure = 0.016
+filament_max_volumetric_speed = 24.5
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.6
+
+# Q2 0.8 nozzle QIDI filament preset
+[filament:QIDI ABS Odorless @Q2 0.8 nozzle]
+inherits = *QIDI ABS Odorless*
+advance_pressure = 0.011
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+min_print_speed = 10
+temperature = 250
+filament_id = QD_1_1_14
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI ABS Rapido @Q2 0.8 nozzle]
+inherits = *QIDI ABS Rapido*
+advance_pressure = 0.011
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+min_print_speed = 10
+temperature = 250
+filament_id = QD_1_1_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI ABS Rapido Metal @Q2 0.8 nozzle]
+inherits = *QIDI ABS Rapido Metal*
+advance_pressure = 0.008
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+min_print_speed = 10
+temperature = 250
+filament_id = QD_1_1_13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI ABS-GF @Q2 0.8 nozzle]
+inherits = *QIDI ABS-GF*
+chamber_minimal_temperature = 0
+filament_max_volumetric_speed = 12
+first_layer_temperature = 260
+temperature = 270
+filament_id = QD_1_1_12
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI ASA @Q2 0.8 nozzle]
+inherits = *QIDI ASA*
+advance_pressure = 0.011
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 13
+min_print_speed = 10
+temperature = 255
+filament_id = QD_1_1_18
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PA12-CF @Q2 0.8 nozzle]
+inherits = *QIDI PA12-CF*
+advance_pressure = 0.035
+filament_max_volumetric_speed = 8
+first_layer_temperature = 280
+temperature = 280
+filament_id = QD_1_1_27
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PAHT-CF @Q2 0.8 nozzle]
+inherits = *QIDI PAHT-CF*
+advance_pressure = 0.032
+first_layer_temperature = 300
+temperature = 300
+filament_id = QD_1_1_30
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PAHT-GF @Q2 0.8 nozzle]
+inherits = *QIDI PAHT-GF*
+advance_pressure = 0.01
+first_layer_temperature = 300
+temperature = 300
+filament_id = QD_1_1_31
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PC/ABS-FR @Q2 0.8 nozzle]
+inherits = *QIDI PC/ABS-FR*
+advance_pressure = 0.024
+chamber_minimal_temperature = 55
+filament_id = QD_1_1_34
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PET-CF @Q2 0.8 nozzle]
+inherits = *QIDI PET-CF*
+advance_pressure = 0.025
+filament_max_volumetric_speed = 8
+first_layer_temperature = 280
+temperature = 280
+filament_id = QD_1_1_37
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PETG-Tough @Q2 0.8 nozzle]
+inherits = *QIDI PETG-Tough*
+filament_max_volumetric_speed = 13
+filament_id = QD_1_1_40
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PET-GF @Q2 0.8 nozzle]
+inherits = *QIDI PET-GF*
+advance_pressure = 0.01
+filament_max_volumetric_speed = 10
+first_layer_temperature = 310
+temperature = 310
+filament_id = QD_1_1_38
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PLA Rapido @Q2 0.8 nozzle]
+inherits = *QIDI PLA Rapido*
+advance_pressure = 0.008
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PLA Rapido Matte @Q2 0.8 nozzle]
+inherits = *QIDI PLA Rapido Matte*
+advance_pressure = 0.008
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_2
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PLA Rapido Metal @Q2 0.8 nozzle]
+inherits = *QIDI PLA Rapido Metal*
+advance_pressure = 0.01
+filament_max_volumetric_speed = 24.5
+temperature = 210
+filament_id = QD_1_1_3
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PLA-CF @Q2 0.8 nozzle]
+inherits = *QIDI PLA-CF*
+advance_pressure = 0.008
+extrusion_multiplier = 0.93
+filament_max_volumetric_speed = 18
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_1_1_5
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI PPS-CF @Q2 0.8 nozzle]
+inherits = *QIDI PPS-CF*
+advance_pressure = 0.008
+chamber_minimal_temperature = 60
+filament_id = QD_1_1_44
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI TPU 95A-HF @Q2 0.8 nozzle]
+inherits = *QIDI TPU 95A-HF*
+temperature = 220
+filament_id = QD_1_1_50
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI UltraPA @Q2 0.8 nozzle]
+inherits = *QIDI UltraPA*
+filament_max_volumetric_speed = 4
+filament_id = QD_1_1_24
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI UltraPA-CF25 @Q2 0.8 nozzle]
+inherits = *QIDI UltraPA-CF25*
+advance_pressure = 0.02
+filament_id = QD_1_1_26
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI WOOD Rapido @Q2 0.8 nozzle]
+inherits = *QIDI WOOD Rapido*
+advance_pressure = 0.012
+filament_max_volumetric_speed = 18
+temperature = 210
+filament_id = QD_1_1_6
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI Support For PET/PA @Q2 0.8 nozzle]
+inherits = *QIDI Support For PET/PA*
+filament_id = QD_1_1_33
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:QIDI Support For PAHT @Q2 0.8 nozzle]
+inherits = *QIDI Support For PAHT*
+filament_id = QD_1_1_32
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+# Q2 0.8 nozzle Generic filament preset
+[filament:Generic ABS @Q2 0.8 nozzle]
+inherits = *Generic ABS*
+advance_pressure = 0.011
+filament_max_volumetric_speed = 24.5
+temperature = 250
+filament_id = QD_0_0_11
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Generic PETG @Q2 0.8 nozzle]
+inherits = *Generic PETG*
+first_layer_temperature = 245
+filament_id = QD_0_0_41
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Generic PLA @Q2 0.8 nozzle]
+inherits = *Generic PLA*
+advance_pressure = 0.008
+first_layer_temperature = 220
+temperature = 220
+filament_id = QD_0_0_1
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Generic PLA+ @Q2 0.8 nozzle]
+inherits = *Generic PLA+*
+advance_pressure = 0.008
+first_layer_temperature = 230
+temperature = 230
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Generic TPU 95A @Q2 0.8 nozzle]
+inherits = *Generic TPU 95A*
+temperature = 220
+filament_id = QD_0_0_50
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Generic PC @Q2 0.8 nozzle]
+inherits = *Generic PC*
+advance_pressure = 0.008
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:PolyLite ABS @Q2 0.8 nozzle]
+inherits = *PolyLite ABS*
+advance_pressure = 0.01
+chamber_minimal_temperature = 60
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 17
+min_print_speed = 10
+slowdown_below_layer_time = 6
+temperature = 255
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:PolyLite PLA @Q2 0.8 nozzle]
+inherits = *PolyLite PLA*
+advance_pressure = 0.012
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 11
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Overture ABS @Q2 0.8 nozzle]
+inherits = *Overture ABS*
+advance_pressure = 0.01
+chamber_minimal_temperature = 60
+extrusion_multiplier = 0.96
+filament_max_volumetric_speed = 17
+min_print_speed = 10
+slowdown_below_layer_time = 6
+temperature = 255
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Overture PLA @Q2 0.8 nozzle]
+inherits = *Overture PLA*
+advance_pressure = 0.012
+extrusion_multiplier = 1
+filament_max_volumetric_speed = 11
+slowdown_below_layer_time = 10
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Bambu ABS @Q2 0.8 nozzle]
+inherits = *Bambu ABS*
+advance_pressure = 0.011
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+min_print_speed = 10
+temperature = 250
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Bambu PETG @Q2 0.8 nozzle]
+inherits = *Bambu PETG*
+filament_max_volumetric_speed = 13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:Bambu PLA @Q2 0.8 nozzle]
+inherits = *Bambu PLA*
+advance_pressure = 0.008
+filament_max_volumetric_speed = 24.5
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:HATCHBOX ABS @Q2 0.8 nozzle]
+inherits = *HATCHBOX ABS*
+advance_pressure = 0.011
+chamber_minimal_temperature = 55
+filament_max_volumetric_speed = 24.5
+min_print_speed = 10
+temperature = 250
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:HATCHBOX PETG @Q2 0.8 nozzle]
+inherits = *HATCHBOX PETG*
+filament_max_volumetric_speed = 13
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
+[filament:HATCHBOX PLA @Q2 0.8 nozzle]
+inherits = *HATCHBOX PLA*
+advance_pressure = 0.008
+filament_max_volumetric_speed = 24.5
+temperature = 210
+compatible_printers_condition = printer_model=="Q2" and nozzle_diameter[0]==0.8
+
# X-Plus 4 0.2 nozzle QIDI filament preset
[filament:QIDI ABS Odorless @X-Plus 4 0.2 nozzle]
inherits = *QIDI ABS Odorless*
@@ -1842,7 +3030,7 @@ advance_pressure = 0.035
filament_max_volumetric_speed = 8
first_layer_temperature = 280
temperature = 280
-filament_id = QD_0_1_25
+filament_id = QD_0_1_27
compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4
[filament:QIDI PAHT-CF @X-Plus 4 0.4 nozzle]
@@ -2159,7 +3347,7 @@ advance_pressure = 0.035
filament_max_volumetric_speed = 8
first_layer_temperature = 280
temperature = 280
-filament_id = QD_0_1_25
+filament_id = QD_0_1_27
compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6
[filament:QIDI PAHT-CF @X-Plus 4 0.6 nozzle]
@@ -2478,7 +3666,7 @@ advance_pressure = 0.035
filament_max_volumetric_speed = 8
first_layer_temperature = 280
temperature = 280
-filament_id = QD_0_1_25
+filament_id = QD_0_1_27
compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8
[filament:QIDI PAHT-CF @X-Plus 4 0.8 nozzle]
@@ -6267,6 +7455,68 @@ wipe_device = 0
wipe_distance = 2
z_offset = 0
box_id =
+is_support_3mf = 0
+
+# Q2 preset
+[printer:*Q2*]
+inherits = *common*
+printer_model = Q2
+autoemit_temperature_commands = 0
+auxiliary_fan = 1
+bed_exclude_area = 0x0,0x16,11x16,11x0,0x0
+bed_shape = 0x0,270x0,270x270,0x270
+before_layer_gcode = TIMELAPSE_TAKE_FRAME
+box_temperature_control = 1
+chamber_temperature_control = 1
+end_gcode = DISABLE_BOX_HEATER\nM141 S0\nM140 S0\nDISABLE_ALL_SENSOR\nG1 E-3 F1800\nG0 Z{max_layer_z + 3} F600\nUNLOAD_FILAMENT T=[current_extruder]\nG0 Y270 F12000\nG0 X90 Y270 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}\nM104 S0
+layer_gcode = G92 E0\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1}
+machine_max_feedrate_z = 20
+max_print_height = 260
+retract_lift_below = 259
+single_extruder_multi_material = 1
+start_gcode = PRINT_START BED=[first_layer_bed_temperature] HOTEND=[first_layer_temperature] CHAMBER=[chamber_minimal_temperature] EXTRUDER=[initial_extruder]\nSET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nM83\nM140 S[first_layer_bed_temperature]\nM104 S[first_layer_temperature]\nM141 S[chamber_minimal_temperature]\nG4 P3000\nT[initial_tool]\nG1 X108.000 Y1 F30000\nG0 Z[first_layer_height] F600\nG1 E3 F1800\nG90\nM83\nG0 X128 E8 F{external_perimeter_speed/10/(24/20) * 60}\nG0 X133 E.3742 F{external_perimeter_speed/10/(0.3*0.5)/4 * 60}\nG0 X138 E.3742 F{external_perimeter_speed/10/(0.3*0.5) * 60}\nG0 X143 E.3742 F{external_perimeter_speed/10/(0.3*0.5)/4 * 60}\nG0 X148 E.3742 F{external_perimeter_speed/10/(0.3*0.5) * 60}\nG0 X153 E.3742 F{external_perimeter_speed/10/(0.3*0.5)/4 * 60}\nG91\nG1 X1 Z-0.300\nG1 X4\nG1 Z1 F1200\nG90\nM400\nG1 X108.000 Y2.5 F30000\nG0 Z[first_layer_height] F600\nM83\nG0 X128 E10 F{external_perimeter_speed/10/(24/20) * 60}\nG0 X133 E.3742 F{external_perimeter_speed/10/(0.3*0.5)/4 * 60}\nG0 X138 E.3742 F{external_perimeter_speed/10/(0.3*0.5) * 60}\nG0 X143 E.3742 F{external_perimeter_speed/10/(0.3*0.5)/4 * 60}\nG0 X148 E.3742 F{external_perimeter_speed/10/(0.3*0.5) * 60}\nG0 X153 E.3742 F{external_perimeter_speed/10/(0.3*0.5)/4 * 60}\nG91\nG1 X1 Z-0.300\nG1 X4\nG1 Z1 F1200\nG90\nM400\nG1 Z1 F600
+toolchange_gcode = G1 Z{max_layer_z + 3.0} F1200\nTOOL_CHANGE_START F=[current_extruder] T=[next_extruder]\nDISABLE_ALL_SENSOR\nM106 S255\nMOVE_TO_TRASH\nG1 E-10 F300\nM400\nCUT_FILAMENT T=[current_extruder]\nMOVE_TO_TRASH\n{if filament_flush_temp[current_extruder] >= filament_flush_temp[next_extruder]}\nM104 S{filament_flush_temp[current_extruder]}\n{else}\nM104 S{filament_flush_temp[next_extruder]}\n{endif}\nM106 P2 S0\nUNLOAD_T[current_extruder]\nT[next_extruder]\n{if filament_flush_temp[current_extruder] >= filament_flush_temp[next_extruder]}\nM104 S{filament_flush_temp[current_extruder]}\n{else}\nM104 S{filament_flush_temp[next_extruder]}\n{endif}\n; FLUSH_START\nM106 S25\nG1 E15 F900\nG1 E30 F300\n; FLUSH_END\n; FLUSH_START\nG1 E{65.5 * 0.58} F611\nG1 E{65.5 * 0.02} F50\nG1 E{65.5 * 0.18} F611\nG1 E{65.5 * 0.02} F50\nG1 E{65.5 * 0.18} F611\nG1 E{65.5 * 0.02} F50\nG1 E-2 F1800\n; FLUSH_END\n; FLUSH_START\nG1 X92 F9000\nG1 E2 F300\nG1 E{75 * 0.58} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E-2 F1800\n; FLUSH_END\n; FLUSH_START\nG1 X85 F9000\nG1 E2 F300\nG1 E{75 * 0.58} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E-2 F1800\n; FLUSH_END\nM400\nM106 S255\nM104 S{temperature[next_extruder]}\nG1 E10 F25\nM109 S{temperature[next_extruder]}\nG1 E-5 F1800\nCLEAR_OOZE\nTOOL_CHANGE_END\nG1 Y270 F8000\nM400\n{if layer_num > disable_fan_first_layers[next_extruder]}\nM106 S{max_fan_speed[next_extruder]}\n{if seal_print}\nM106 P2 S{enable_auxiliary_fan[next_extruder]}\n{else}\nM106 P2 S{enable_auxiliary_fan_unseal[next_extruder]}\n{endif}\n{else}\nM106 S0\nM106 P2 S0\n{endif}\nENABLE_ALL_SENSOR\n
+wipe_device = 1
+box_id = 1
+nozzle_volume = 125
+is_support_3mf = 1
+
+[printer:Q2 0.2 nozzle]
+inherits = *Q2*
+default_filament_profile = Generic PLA @Q2 0.2 nozzle
+default_print_profile = 0.12mm Fine @Q2 0.2 nozzle
+max_layer_height = 0.14
+min_layer_height = 0.04
+nozzle_diameter = 0.2
+printer_variant = 0.2
+retract_length = 0.4
+
+[printer:Q2 0.4 nozzle]
+inherits = *Q2*
+default_filament_profile = Generic PLA @Q2 0.4 nozzle
+default_print_profile = 0.20mm Fine @Q2 0.4 nozzle
+retract_length = 0.8
+
+[printer:Q2 0.6 nozzle]
+inherits = *Q2*
+default_filament_profile = Generic PLA @Q2 0.6 nozzle
+default_print_profile = 0.30mm Fine @Q2 0.6 nozzle
+max_layer_height = 0.42
+min_layer_height = 0.12
+nozzle_diameter = 0.6
+printer_variant = 0.6
+retract_before_travel = 3
+retract_length = 1.4
+
+[printer:Q2 0.8 nozzle]
+inherits = *Q2*
+default_filament_profile = Generic PLA @Q2 0.8 nozzle
+default_print_profile = 0.40mm Fine @Q2 0.8 nozzle
+max_layer_height = 0.56
+min_layer_height = 0.16
+nozzle_diameter = 0.8
+printer_variant = 0.8
+retract_length = 3
# X-Plus 4 preset
[printer:*X-Plus 4*]
diff --git a/resources/profiles/QIDITechnology/Q2_bed.stl b/resources/profiles/QIDITechnology/Q2_bed.stl
new file mode 100644
index 0000000..ca300b0
Binary files /dev/null and b/resources/profiles/QIDITechnology/Q2_bed.stl differ
diff --git a/resources/profiles/QIDITechnology/Q2_bed.svg b/resources/profiles/QIDITechnology/Q2_bed.svg
new file mode 100644
index 0000000..8dc6ecb
--- /dev/null
+++ b/resources/profiles/QIDITechnology/Q2_bed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/profiles/QIDITechnology/Q2_thumbnail.png b/resources/profiles/QIDITechnology/Q2_thumbnail.png
new file mode 100644
index 0000000..356a6cc
Binary files /dev/null and b/resources/profiles/QIDITechnology/Q2_thumbnail.png differ
diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp
index c2e651e..7532faa 100644
--- a/src/libslic3r/Format/3mf.cpp
+++ b/src/libslic3r/Format/3mf.cpp
@@ -46,6 +46,8 @@ namespace pt = boost::property_tree;
#include
+#include "nlohmann/json.hpp"
+
// Slightly faster than sprintf("%.9g"), but there is an issue with the karma floating point formatter,
// https://github.com/boostorg/spirit/pull/586
// where the exported string is one digit shorter than it should be to guarantee lossless round trip.
@@ -90,6 +92,12 @@ const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE = "Metadata/QIDI_Slicer_custom_g
const std::string WIPE_TOWER_INFORMATION_FILE = "Metadata/QIDI_Slicer_wipe_tower_information.xml";
const std::string CUT_INFORMATION_FILE = "Metadata/QIDI_Slicer_cut_information.xml";
+//y29
+const std::string QDS_MODEL_CONFIG_FILE = "Metadata/model_settings.config";
+const std::string QDS_MODEL_CONFIG_RELS_FILE = "Metadata/_rels/model_settings.config.rels";
+const std::string QDS_SLICE_INFO_CONFIG_FILE = "Metadata/slice_info.config";
+const std::string QDS_PROJECT_CONFIG_FILE = "Metadata/project_settings.config";
+
static constexpr const char *RELATIONSHIP_TAG = "Relationship";
static constexpr const char* TARGET_ATTR = "Target";
@@ -196,6 +204,20 @@ static constexpr const char *DEPTH_ATTR = "depth";
static constexpr const char *USE_SURFACE_ATTR = "use_surface";
// static constexpr const char *FIX_TRANSFORMATION_ATTR = "transform";
+//y29
+static constexpr const char* PLATE_TAG = "plate";
+static constexpr const char* PLATERID_ATTR = "plater_id";
+static constexpr const char* GCODE_FILE_ATTR = "gcode_file";
+static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file";
+static constexpr const char* SLICE_HEADER_TAG = "header";
+static constexpr const char* SLICE_HEADER_ITEM_TAG = "header_item";
+static constexpr const char* PLATE_IDX_ATTR = "index";
+static constexpr const char* PRINTER_MODEL_ID_ATTR = "printer_model_id";
+static constexpr const char* NOZZLE_DIAMETERS_ATTR = "nozzle_diameters";
+static constexpr const char* SLICE_PREDICTION_ATTR = "prediction";
+static constexpr const char* SLICE_WEIGHT_ATTR = "weight";
+static constexpr const char *LAYER_FILAMENT_LISTS_TAG = "layer_filament_lists";
+static constexpr const char *LAYER_FILAMENT_LIST_TAG = "layer_filament_list";
const unsigned int VALID_OBJECT_TYPES_COUNT = 1;
const char* VALID_OBJECT_TYPES[] =
@@ -2762,14 +2784,21 @@ namespace Slic3r {
bool m_fullpath_sources{ true };
bool m_zip64 { true };
+ //y29
+ std::vector m_plates_gcode;
+ std::vector m_thumbnails;
+
public:
- bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64);
+ //y29
+ bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailsList* thumbnail_datas, bool zip64, bool export_gcode_3mf = false, std::string temp_gcode_path = "", bool all_gcodes = false, std::vector plate_datas = std::vector());
static void add_transformation(std::stringstream &stream, const Transform3d &tr);
private:
void _publish(Model &model);
- bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data);
+ //y29
+ bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailsList* thumbnail_datas, bool export_gcode_3mf = false, std::string temp_gcode_path = "", bool all_gcodes = false, std::vector plate_datas = std::vector());
bool _add_content_types_file_to_archive(mz_zip_archive& archive);
- bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data);
+ //y29
+ bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, int idx);
bool _add_relationships_file_to_archive(mz_zip_archive& archive);
bool _add_model_file_to_archive(const std::string& filename, mz_zip_archive& archive, const Model& model, IdToObjectDataMap& objects_data);
bool _add_object_to_model_stream(mz_zip_writer_staged_context &context, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets);
@@ -2784,17 +2813,24 @@ namespace Slic3r {
bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data);
bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config);
bool _add_wipe_tower_information_file_to_archive( mz_zip_archive& archive, Model& model);
+ bool _add_gcode_file_to_archive(mz_zip_archive& archive, std::string gcode_path, bool all_gcodes = false);
+ bool _add_QDS_model_config_file_to_archive(mz_zip_archive& archive, bool all_gcodes = false);
+ bool _add_slice_info_config_file_to_archive(mz_zip_archive &archive, const Model &model, const DynamicPrintConfig& config, bool all_gcodes = false, std::vector plate_datas = std::vector());
+ bool _add_gcode_info_config_file_to_archive(mz_zip_archive &archive, std::vector plate_datas = std::vector());
+ bool _add_project_settings_file_to_archive(mz_zip_archive &archive, const DynamicPrintConfig& config);
};
- bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64)
+ //y29
+ bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const std::vector* thumbnail_datas, bool zip64, bool export_gcode_3mf, std::string temp_gcode_path, bool all_gcodes, std::vector plate_datas)
{
clear_errors();
m_fullpath_sources = fullpath_sources;
m_zip64 = zip64;
- return _save_model_to_file(filename, model, config, thumbnail_data);
+ return _save_model_to_file(filename, model, config, thumbnail_datas, export_gcode_3mf, temp_gcode_path, all_gcodes, plate_datas);
}
- bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data)
+ //y29
+ bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const std::vector* thumbnail_datas, bool export_gcode_3mf, std::string temp_gcode_path, bool all_gcodes, std::vector plate_datas)
{
mz_zip_archive archive;
mz_zip_zero_struct(&archive);
@@ -2812,9 +2848,25 @@ namespace Slic3r {
return false;
}
- if (thumbnail_data != nullptr && thumbnail_data->is_valid()) {
+ //y29
+ if (thumbnail_datas != nullptr && !thumbnail_datas->empty()) {
// Adds the file Metadata/thumbnail.png.
- if (!_add_thumbnail_file_to_archive(archive, *thumbnail_data)) {
+ m_thumbnails.clear();
+ for (int i = 0; i < (*thumbnail_datas).size(); i++){
+ ThumbnailData data = (*thumbnail_datas)[i];
+ if (data.is_valid()){
+ if (!_add_thumbnail_file_to_archive(archive, data, i)) {
+ close_zip_writer(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+ }
+ }
+ }
+
+ //y29
+ if(export_gcode_3mf){
+ if (!_add_gcode_file_to_archive(archive, temp_gcode_path, all_gcodes)) {
close_zip_writer(&archive);
boost::filesystem::remove(filename);
return false;
@@ -2917,6 +2969,41 @@ namespace Slic3r {
return false;
}
+ //y29
+ if(export_gcode_3mf){
+ if (!_add_QDS_model_config_file_to_archive(archive, all_gcodes)) {
+ close_zip_writer(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+ }
+
+ //y29
+ if(export_gcode_3mf){
+ if (!_add_slice_info_config_file_to_archive(archive, model, *config, all_gcodes, plate_datas)) {
+ close_zip_writer(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+ }
+
+ //y29
+ if(export_gcode_3mf){
+ if (!_add_gcode_info_config_file_to_archive(archive, plate_datas)) {
+ close_zip_writer(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+ }
+ //y29
+ if(export_gcode_3mf){
+ if (!_add_project_settings_file_to_archive(archive, *config)) {
+ close_zip_writer(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+ }
+
if (!mz_zip_writer_finalize_archive(&archive)) {
close_zip_writer(&archive);
boost::filesystem::remove(filename);
@@ -2949,15 +3036,170 @@ namespace Slic3r {
return true;
}
- bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data)
+ //y29
+ bool _3MF_Exporter::_add_slice_info_config_file_to_archive(mz_zip_archive& archive, const Model& model, const DynamicPrintConfig& config, bool all_gcodes, std::vector plate_datas)
+ {
+ std::stringstream stream;
+ // Store mesh transformation in full precision, as the volumes are stored transformed and they need to be transformed back
+ // when loaded as accurately as possible.
+ stream << std::setprecision(std::numeric_limits::max_digits10);
+ stream << std::setiosflags(std::ios::fixed) << std::setprecision(2);
+ stream << "\n";
+ stream << "<" << CONFIG_TAG << ">\n";
+
+ // save slice header for debug
+ stream << " <" << SLICE_HEADER_TAG << ">\n";
+ stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-QDT-Client-Type" << "\" " << VALUE_ATTR << "=\"" << "slicer" << "\"/>\n";
+ stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-QDT-Client-Version" << "\" " << VALUE_ATTR << "=\"" << SLIC3R_VERSION << "\"/>\n";
+ stream << " " << SLICE_HEADER_TAG << ">\n";
+
+ int current_bed_idx = s_multiple_beds.get_active_bed();
+ int bed_count = s_multiple_beds.get_number_of_beds();
+ for(int idx = 0; idx < plate_datas.size(); idx++){
+ PlateData plate_data = plate_datas[idx];
+ if(plate_data.plate_index != current_bed_idx + 1 && !all_gcodes)
+ continue;
+ stream << " <" << PLATE_TAG << ">\n";
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATE_IDX_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data.plate_index << "\"/>\n";
+
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PRINTER_MODEL_ID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data.printer_model << "\"/>\n";
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << NOZZLE_DIAMETERS_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data.nozzle_diameters << "\"/>\n";
+
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_PREDICTION_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data.gcode_prediction << "\"/>\n";
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_WEIGHT_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data.gcode_weight << "\"/>\n";
+
+ std::vector filament_msg = plate_data.filament_msg;
+ for(int i = 0; i < filament_msg.size(); i++){
+ stream << filament_msg[i] << "\n";
+ }
+ stream << " " << PLATE_TAG << ">\n";
+ }
+ stream << "" << CONFIG_TAG << ">\n";
+
+ std::string out = stream.str();
+
+ if (!mz_zip_writer_add_mem(&archive, QDS_SLICE_INFO_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
+ add_error("Unable to add model config file to archive");
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", store slice-info to 3mf, length %1%, failed\n") % out.length();
+ return false;
+ }
+
+ return true;
+ }
+
+ //y29
+ bool _3MF_Exporter::_add_gcode_file_to_archive(mz_zip_archive& archive, std::string gcode_path, bool all_gcodes)
+ {
+ m_plates_gcode.clear();
+ std::vector gcode_files;
+ const auto temp_dir = boost::filesystem::path(gcode_path).parent_path();
+ std::string prefix = boost::filesystem::path(gcode_path).filename().string();
+ prefix = prefix.substr(0, prefix.find('_'));
+ for (const auto& entry : boost::filesystem::directory_iterator(temp_dir)) {
+ if (entry.is_regular_file()) {
+ const std::string filename = entry.path().filename().string();
+ if (boost::starts_with(filename, prefix) && boost::ends_with(filename, ".gcode"))
+ gcode_files.push_back(entry.path().string());
+ }
+ }
+
+ bool all_success = true;
+
+ int current_bed_idx = s_multiple_beds.get_active_bed();
+ std::string current_gcode_name = "";
+ if(!all_gcodes)
+ current_gcode_name = (boost::format(".%1%_%2%.gcode") %get_current_pid() %(current_bed_idx)).str();
+
+ int idx = 1;
+ for (const auto& file_path : gcode_files) {
+ if(file_path.find(current_gcode_name) == std::string::npos && !current_gcode_name.empty()){
+ idx++;
+ continue;
+ }
+ std::ifstream file(file_path, std::ios::binary | std::ios::ate);
+ if (!file.is_open()) {
+ add_error("Unable to open gcode file: " + file_path);
+ all_success = false;
+ continue;
+ }
+
+ std::streamsize file_size = file.tellg();
+ file.seekg(0, std::ios::beg);
+
+ std::vector buffer(file_size);
+ if (!file.read(buffer.data(), file_size)) {
+ add_error("Unable to read gcode file: " + file_path);
+ all_success = false;
+ idx++;
+ continue;
+ }
+ file.close();
+
+ std::string filename;
+ if(!current_gcode_name.empty())
+ filename = (boost::format("Metadata/plate_%1%.gcode") % (current_bed_idx + 1)).str();
+ else
+ filename = (boost::format("Metadata/plate_%1%.gcode") % idx).str();
+
+ bool res = mz_zip_writer_add_mem(&archive, filename.c_str(), buffer.data(), buffer.size(), MZ_DEFAULT_COMPRESSION);
+ if (!res) {
+ add_error("Unable to add gcode file to archive: " + filename);
+ all_success = false;
+ }
+
+ m_plates_gcode.push_back(filename);
+ idx++;
+ }
+
+ return all_success;
+ }
+
+ bool _3MF_Exporter::_add_gcode_info_config_file_to_archive(mz_zip_archive &archive, std::vector plate_datas){
+ bool res = true;
+
+ for(int i = 0; i < plate_datas.size(); i++){
+ nlohmann::json j;
+ j["filament_ids"] = plate_datas[i].used_extruders;
+ j["filament_colors"] = plate_datas[i].filament_colors;
+ std::string out = j.dump();
+ std::string json_file_name = (boost::format("Metadata/plate_%1%.json") % (plate_datas[i].plate_index)).str();
+ if (!mz_zip_writer_add_mem(&archive, json_file_name.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
+ add_error("Unable to add json file to archive");
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to add json file to archive\n");
+ return false;
+ }
+ }
+ return res;
+ }
+
+ bool _3MF_Exporter::_add_project_settings_file_to_archive(mz_zip_archive &archive, const DynamicPrintConfig& config){
+ bool res = true;
+
+ nlohmann::json j;
+ j["filament_colour"] = config.option("filament_colour")->values;
+ j["filament_type"] = config.option("filament_type")->values;
+ std::string out = j.dump();
+ std::string json_file_name = (boost::format(QDS_PROJECT_CONFIG_FILE)).str();
+ if (!mz_zip_writer_add_mem(&archive, json_file_name.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
+ add_error("Unable to add json file to archive");
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to add json file to archive\n");
+ return false;
+ }
+ return res;
+ }
+
+ //y29
+ bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, int idx)
{
bool res = false;
size_t png_size = 0;
void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)thumbnail_data.pixels.data(), thumbnail_data.width, thumbnail_data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1);
if (png_data != nullptr) {
- res = mz_zip_writer_add_mem(&archive, THUMBNAIL_FILE.c_str(), (const void*)png_data, png_size, MZ_DEFAULT_COMPRESSION);
+ std::string thumbnail_name = (boost::format("Metadata/plate_%1%.png") % (idx+1)).str();
+ res = mz_zip_writer_add_mem(&archive, thumbnail_name.c_str(), (const void*)png_data, png_size, MZ_DEFAULT_COMPRESSION);
mz_free(png_data);
+ m_thumbnails.push_back(thumbnail_name);
}
if (!res)
@@ -3663,6 +3905,42 @@ namespace Slic3r {
return true;
}
+ //y29
+ bool _3MF_Exporter::_add_QDS_model_config_file_to_archive(mz_zip_archive& archive, bool all_gcodes){
+ std::stringstream stream;
+ // Store mesh transformation in full precision, as the volumes are stored transformed and they need to be transformed back
+ // when loaded as accurately as possible.
+ stream << std::setprecision(std::numeric_limits::max_digits10);
+ stream << "\n";
+ stream << "<" << CONFIG_TAG << ">\n";
+
+ int current_bed_idx = s_multiple_beds.get_active_bed();
+ int bed_count = s_multiple_beds.get_number_of_beds();
+ for(int i = 0; i < bed_count; i++){
+ stream << " <" << PLATE_TAG << ">\n";
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATERID_ATTR << "\" " << VALUE_ATTR << "=\"" << i + 1 << "\"/>\n";
+ if(current_bed_idx == i && !all_gcodes)
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << (boost::format("plate_%1%.gcode") % (current_bed_idx + 1)).str() << "\"/>\n";
+ else if(all_gcodes)
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << (boost::format("plate_%1%.gcode") % (i + 1)).str() << "\"/>\n";
+ else
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << "" << "\"/>\n";
+ stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << THUMBNAIL_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << m_thumbnails[i] << "\"/>\n";
+ stream << " " << PLATE_TAG << ">\n";
+ }
+
+ stream << "" << CONFIG_TAG << ">\n";
+
+ std::string out = stream.str();
+ if (!mz_zip_writer_add_mem(&archive, QDS_MODEL_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format("Unable to add model config file to archive\n");
+ add_error("Unable to add model config file to archive");
+ return false;
+ }
+
+ return true;
+ }
+
bool _3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data)
{
enum class MetadataType{
@@ -3994,7 +4272,8 @@ bool load_3mf(
return res;
}
-bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64)
+//y29
+bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const std::vector* thumbnail_datas, bool zip64, bool export_gcode_3mf, std::string temp_gcode_path, bool all_gcodes, std::vector plate_datas)
{
// All export should use "C" locales for number formatting.
CNumericLocalesSetter locales_setter;
@@ -4003,7 +4282,7 @@ bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config,
return false;
_3MF_Exporter exporter;
- bool res = exporter.save_model_to_file(path, *model, config, fullpath_sources, thumbnail_data, zip64);
+ bool res = exporter.save_model_to_file(path, *model, config, fullpath_sources, thumbnail_datas, zip64, export_gcode_3mf, temp_gcode_path, all_gcodes, plate_datas);
if (!res)
exporter.log_errors();
diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp
index e38645b..b20b0e5 100644
--- a/src/libslic3r/Format/3mf.hpp
+++ b/src/libslic3r/Format/3mf.hpp
@@ -29,6 +29,20 @@ namespace Slic3r {
*/
+ //y29
+ struct PlateData {
+ int plate_index;
+ std::string printer_model;
+ float nozzle_diameters;
+ std::string gcode_filename;
+ int gcode_prediction;
+ float gcode_weight;
+ std::vector filament_msg;
+ std::vector used_extruders;
+ std::vector filament_colors;
+ };
+
+
enum {
support_points_format_version = 1
};
@@ -57,7 +71,9 @@ namespace Slic3r {
// Save the given model and the config data contained in the given Print into a 3mf file.
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
- extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data = nullptr, bool zip64 = true);
+ //y29
+
+ extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const std::vector* thumbnail_datas = nullptr, bool zip64 = true, bool export_gcode_3mf = false, std::string temp_gcode_path = "", bool all_gcodes = false, std::vector plate_datas = std::vector());
} // namespace Slic3r
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 2b17772..16523d2 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1036,7 +1036,8 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
throw Slic3r::ExportError(error_str);
}
- if (!thumbnails.empty())
+ //y29
+ if (!thumbnails.empty() && !m_config.is_support_3mf)
GCodeThumbnails::export_thumbnails_to_file(thumbnail_cb, thumbnails,
[&file](const char* sz) { file.write(sz); },
[&print]() { print.throw_if_canceled(); });
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 61a41c2..6b06f2e 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -609,7 +609,9 @@ static std::vector s_Preset_printer_options {
"box_id",
"nozzle_volume",
//Y30
- "box_temperature_control"
+ "box_temperature_control",
+ //y29
+ "is_support_3mf"
};
static std::vector s_Preset_sla_print_options {
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index cb0a601..bd81eab 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -2777,6 +2777,12 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat(0.0));
//y25
+ //y29
+ def = this->add("is_support_3mf", coBool);
+ def->label = L("Support 3MF");
+ def->tooltip = L("The machine supports export .gcode.3mf file.");
+ def->set_default_value(new ConfigOptionBool(false));
+
def = this->add("filament_id", coStrings);
def->set_default_value(new ConfigOptionStrings { "" });
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 56cea39..1985af7 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -1056,6 +1056,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, z_offset))
//y25
((ConfigOptionString, box_id))
+ //y29
+ ((ConfigOptionBool, is_support_3mf))
)
PRINT_CONFIG_CLASS_DERIVED_DEFINE0(
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index 64cab90..577fa2c 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -99,10 +99,18 @@ std::pair SlicingProcessCompletedEvent::format_error_message(
void BackgroundSlicingProcess::set_temp_output_path(int bed_idx)
{
boost::filesystem::path temp_path(wxStandardPaths::Get().GetTempDir().utf8_str().data());
- temp_path /= (boost::format(".%1%_%2%.gcode") % get_current_pid() % bed_idx).str();
- m_temp_output_path = temp_path.string();
+ //y29
+ boost::filesystem::path temp_gcode_path = temp_path/(boost::format(".%1%_%2%.gcode") % get_current_pid() % bed_idx).str();
+ m_temp_output_path = temp_gcode_path.string();
+
+ boost::filesystem::path temp_3mf_path = temp_path/(boost::format(".%1%.gcode.3mf") % get_current_pid()).str();
+ m_temp_3mf_output_path = temp_3mf_path.string();
}
+//y29
+std::string BackgroundSlicingProcess::temp_3mf_output_path() const { return m_temp_3mf_output_path; }
+std::string BackgroundSlicingProcess::temp_gcode_output_path() const { return m_temp_output_path; }
+
BackgroundSlicingProcess::~BackgroundSlicingProcess()
{
this->stop();
@@ -112,12 +120,17 @@ BackgroundSlicingProcess::~BackgroundSlicingProcess()
// in the same directory that starts the same (see set_temp_output_path).
const auto temp_dir = boost::filesystem::path(m_temp_output_path).parent_path();
std::string prefix = boost::filesystem::path(m_temp_output_path).filename().string();
+ //y29
+ std::string _3mf_prefix = boost::filesystem::path(m_temp_3mf_output_path).filename().string();
prefix = prefix.substr(0, prefix.find('_'));
+ _3mf_prefix = _3mf_prefix.substr(0, _3mf_prefix.find('.'));
for (const auto& entry : boost::filesystem::directory_iterator(temp_dir)) {
if (entry.is_regular_file()) {
const std::string filename = entry.path().filename().string();
if (boost::starts_with(filename, prefix) && boost::ends_with(filename, ".gcode"))
boost::filesystem::remove(entry);
+ if(boost::starts_with(filename, _3mf_prefix) && boost::ends_with(filename, ".gcode.3mf"))
+ boost::filesystem::remove(entry);
}
}
}
@@ -780,7 +793,8 @@ void BackgroundSlicingProcess::prepare_upload(PrintHostJob &upload_job)
m_print->set_status(100, GUI::format(_L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"), upload_job.printhost->get_host()));
- upload_job.upload_data.source_path = std::move(source_path);
+ if(upload_job.upload_data.source_path.empty())
+ upload_job.upload_data.source_path = std::move(source_path);
GUI::wxGetApp().printhost_job_queue().enqueue(std::move(upload_job));
}
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp
index 573fc66..ddf5e76 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp
@@ -177,6 +177,10 @@ public:
void finalize_gcode(const std::string &path, const bool path_on_removable_media);
void prepare_upload(PrintHostJob &upload_job);
+ //y29
+ std::string temp_3mf_output_path() const;
+ std::string temp_gcode_output_path() const;
+
private:
void thread_proc();
// Calls thread_proc(), catches all C++ exceptions and shows them using wxApp::OnUnhandledException().
@@ -227,6 +231,8 @@ private:
// Temporary G-code, there is one defined for the BackgroundSlicingProcess,
// differentiated from the other processes by a process ID.
std::string m_temp_output_path;
+ //y29
+ std::string m_temp_3mf_output_path;
// Output path provided by the user. The output path may be set even if the slicing is running,
// but once set, it cannot be re-set.
std::string m_export_path;
diff --git a/src/slic3r/GUI/FrequentlyChangedParameters.cpp b/src/slic3r/GUI/FrequentlyChangedParameters.cpp
index 8d93e45..1db81b3 100644
--- a/src/slic3r/GUI/FrequentlyChangedParameters.cpp
+++ b/src/slic3r/GUI/FrequentlyChangedParameters.cpp
@@ -317,7 +317,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent)
auto add_sync_btn = [this](wxWindow* parent) {
//y26
- auto sync_btn = new wxButton(parent, wxID_ANY, _L("Syn filament info from the box"), wxDefaultPosition, wxSize(200, 30), wxBU_EXACTFIT);
+ auto sync_btn = new wxButton(parent, wxID_ANY, _L("Sync filament info from the box"), wxDefaultPosition, wxSize(200, 30), wxBU_EXACTFIT);
wxGetApp().UpdateDarkUI(sync_btn, true);
sync_btn->SetToolTip(_L("Click the sync button to synchronize the Box information to the filament column."));
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 7501745..953d772 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -498,6 +498,7 @@ static const FileWildcards file_wildcards_by_type[FT_SIZE] = {
/* FT_SL1 (deprecated, overriden by sla_wildcards) */ { "Masked SLA files"sv, { ".sl1"sv, ".sl1s"sv, ".pwmx"sv } },
/* FT_ZIP */ { "Zip files"sv, { ".zip"sv } },
+ /* FT_GCODE_3MF*/ {"G-code 3MF files"sv, { ".gcode.3mf"sv } }, //y29
};
// This function produces a Win32 file dialog file template mask to be consumed by wxWidgets on all platforms.
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 3464bbd..066de90 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -83,6 +83,7 @@ enum FileType
FT_SL1,
FT_ZIP,
+ FT_GCODE_3MF, //y29
FT_SIZE,
};
diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp
index 746feb5..023d849 100644
--- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp
+++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp
@@ -907,7 +907,8 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
}
for(auto exit_host : m_exit_host)
{
- if(exit_host.find(now_host) != std::string::npos)
+ //y29
+ if(exit_host == now_host)
{
MessageDialog msg_wingow(nullptr, _L("A device with the same host (IP or URL) already exists, please re-enter."), "",
wxICON_WARNING | wxOK);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 303e00b..cbeaf15 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -148,7 +148,8 @@ using Slic3r::Preset;
using Slic3r::PrintHostJob;
using Slic3r::GUI::format_wxstr;
-static const std::pair THUMBNAIL_SIZE_3MF = { 256, 256 };
+//y29
+static const std::pair THUMBNAIL_SIZE_3MF = { 512, 512 };
//B64
static const std::pair THUMBNAIL_SIZE_SEND = {128, 160};
@@ -1831,7 +1832,9 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type)
case FT_GCODE:
case FT_OBJ:
case FT_OBJECT:
- wildcard = file_wildcards(file_type);
+ //y29
+ case FT_GCODE_3MF:
+ wildcard = file_wildcards(file_type);
break;
default:
wildcard = file_wildcards(FT_MODEL);
@@ -1867,6 +1870,13 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type)
dlg_title = _L("Export OBJ file:");
break;
}
+ //y29
+ case FT_GCODE_3MF:
+ {
+ output_file.replace_extension(".gcode.3mf");
+ dlg_title = _L("Export GCODE.3MF file:");
+ break;
+ }
default: break;
}
@@ -3505,6 +3515,10 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false);
}
exporting_status = ExportingStatus::NOT_EXPORTING;
+
+ ////y29
+ //if(wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_bool("is_support_3mf"))
+ // q->export_3mf(fs::path(this->background_process.temp_3mf_output_path()));
}
void Plater::priv::on_layer_editing_toggled(bool enable)
@@ -4091,31 +4105,53 @@ void Plater::priv::show_action_buttons(const bool ready_to_slice_) const
# endif
// when a background processing is ON, export_btn and/or send_btn are showing
+ //y29
if (get_config_bool("background_processing"))
{
RemovableDriveManager::RemovableDrivesStatus removable_media_status = wxGetApp().removable_drive_manager()->status();
- if (sidebar->show_reslice(false) |
- sidebar->show_export(true) |
- //y18
- sidebar->show_send(send_gcode_shown | link_has_machine | local_has_devices) |
- //y15
- // sidebar->show_connect(connect_gcode_shown) |
- sidebar->show_export_removable(removable_media_status.has_removable_drives))
- sidebar->Layout();
+ if(wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_bool("is_support_3mf")){
+ if (sidebar->show_reslice(false) |
+ sidebar->show_export(false) |
+ sidebar->show_send(send_gcode_shown | link_has_machine | local_has_devices) |
+ sidebar->show_export_removable(removable_media_status.has_removable_drives) |
+ sidebar->show_gcode_3mf_export(true))
+ ;
+ }
+ else {
+ if (sidebar->show_reslice(false) |
+ sidebar->show_export(true) |
+ sidebar->show_send(send_gcode_shown | link_has_machine | local_has_devices) |
+ sidebar->show_export_removable(removable_media_status.has_removable_drives) |
+ sidebar->show_gcode_3mf_export(false))
+ ;
+ }
+ sidebar->Layout();
}
else
{
RemovableDriveManager::RemovableDrivesStatus removable_media_status;
if (! ready_to_slice)
removable_media_status = wxGetApp().removable_drive_manager()->status();
- if (sidebar->show_reslice(ready_to_slice) |
- sidebar->show_export(!ready_to_slice) |
- //y18
- sidebar->show_send((send_gcode_shown | link_has_machine | local_has_devices) && !ready_to_slice) |
- //y15
- // sidebar->show_connect(connect_gcode_shown && !ready_to_slice) |
- sidebar->show_export_removable(!ready_to_slice && removable_media_status.has_removable_drives))
- sidebar->Layout();
+ bool is_support_3mf = wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_bool("is_support_3mf");
+ if (is_support_3mf) {
+ if (sidebar->show_reslice(ready_to_slice) |
+ sidebar->show_export(false) |
+ sidebar->show_send((send_gcode_shown | link_has_machine | local_has_devices) && !ready_to_slice) |
+ sidebar->show_export_removable(!ready_to_slice && removable_media_status.has_removable_drives) |
+ sidebar->show_gcode_3mf_export(!ready_to_slice)) {
+ ;
+ }
+ }
+ else {
+ if (sidebar->show_reslice(ready_to_slice) |
+ sidebar->show_export(!ready_to_slice) |
+ sidebar->show_send((send_gcode_shown | link_has_machine | local_has_devices) && !ready_to_slice) |
+ sidebar->show_export_removable(!ready_to_slice && removable_media_status.has_removable_drives) |
+ sidebar->show_gcode_3mf_export(false)) {
+ ;
+ }
+ }
+ sidebar->Layout();
}
}
@@ -4130,7 +4166,8 @@ void Plater::priv::show_autoslicing_action_buttons() const {
RemovableDriveManager::RemovableDrivesStatus removable_media_status = wxGetApp().removable_drive_manager()->status();
- bool updated{sidebar->show_export_all(true)};
+ //y29
+ bool updated{wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_bool("is_support_3mf") ? sidebar->show_export_all_3mf(true) : sidebar->show_export_all(true)};
updated = sidebar->show_connect_all(connect_gcode_shown) || updated;
updated = sidebar->show_export_removable_all(removable_media_status.has_removable_drives) || updated;
if (updated) {
@@ -6961,13 +6998,18 @@ bool Plater::export_3mf(const boost::filesystem::path& output_path)
const std::string path_u8 = into_u8(path);
wxBusyCursor wait;
bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames");
- ThumbnailData thumbnail_data;
- ThumbnailsParams thumbnail_params = { {}, false, true, true, true };
- p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho);
+
+ //y29
+ //ThumbnailsParams thumbnail_params = { {}, false, true, true, true };
+ //ThumbnailsList thumbnail_datas = p->generate_thumbnails(thumbnail_params, Camera::EType::Ortho);
+ //p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho);
+
+ std::vector thumbnail_datas = p->thumbnails;
+
bool ret = false;
try
{
- ret = Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data);
+ ret = Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_datas);
}
catch (boost::filesystem::filesystem_error& e)
{
@@ -6988,6 +7030,162 @@ bool Plater::export_3mf(const boost::filesystem::path& output_path)
return ret;
}
+//y29
+void Plater::export_gcode_3mf(bool prefer_removable, bool all_gcodes)
+{
+ if (p->model.objects.empty())
+ return;
+
+ if (canvas3D()->get_gizmos_manager().is_in_editing_mode(true))
+ return;
+
+ if (!is_sliceable(s_print_statuses[s_multiple_beds.get_active_bed()]))
+ return;
+
+ fs::path default_output_file;
+ AppConfig& appconfig = *wxGetApp().app_config;
+
+ wxString path = p->get_export_file(FT_GCODE_3MF);
+ if (path.empty()) { return; }
+ fs::path output_path(path);
+
+ bool is_success_ful = export_gcode_3mf(output_path, all_gcodes);
+ if (is_success_ful) {
+ // update last output dir
+ AppConfig& appconfig{ *wxGetApp().app_config };
+ appconfig.update_last_output_dir(output_path.parent_path().string(), false);
+ p->notification_manager->push_exporting_finished_notification(output_path.string(), p->last_output_dir_path, false);
+ }
+ else {
+ // Failure
+ const wxString what = GUI::format_wxstr("%1%: %2%", _L("Unable to save file"), path);
+ show_error(this, what);
+ }
+}
+
+//y29
+bool Plater::export_gcode_3mf(const boost::filesystem::path& output_path, bool all_gcodes){
+ if (p->model.objects.empty())
+ return false;
+
+ if (!output_path.empty()) {
+ if (p->model.objects.empty()) {
+ MessageDialog dialog(nullptr, _L("The plater is empty.\nDo you want to save the project?"), _L("Save project"), wxYES_NO);
+ if (dialog.ShowModal() != wxID_YES)
+ return false;
+ }
+
+ wxString path;
+ bool export_config = true;
+ if (output_path.empty()) {
+ path = p->get_export_file(FT_3MF);
+ if (path.empty()) { return false; }
+ }
+ else
+ path = from_path(output_path);
+
+ if (!path.Lower().EndsWith(".gcode.3mf"))
+ return false;
+
+ // take care about private data stored into .3mf
+ // modify model
+ publish(p->model);
+
+ DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure();
+ const std::string path_u8 = into_u8(path);
+ wxBusyCursor wait;
+ bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames");
+
+ //y29
+ //ThumbnailsParams thumbnail_params = { {}, false, true, true, true };
+ //ThumbnailsList thumbnail_datas = p->generate_thumbnails(thumbnail_params, Camera::EType::Ortho);
+ //p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho);
+
+ std::vector thumbnail_datas;
+ if (!p->thumbnails.empty())
+ thumbnail_datas = p->thumbnails;
+ else {
+ ThumbnailData thumbnail_data;
+ ThumbnailsParams thumbnail_params = { {}, false, true, true, true };
+ p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho);
+ thumbnail_datas.push_back(thumbnail_data);
+ }
+
+ std::vector filament_msg;
+ std::vector plate_datas;
+ for(int i = 0; i < s_multiple_beds.get_number_of_beds(); i++){
+ filament_msg.clear();
+ PlateData pdata;
+ pdata.plate_index = i + 1;
+ pdata.gcode_filename = (boost::format("plat_%1%.gcode") % (i + 1)).str();
+ pdata.printer_model = cfg.opt_string("printer_model");
+ pdata.nozzle_diameters = cfg.opt_float("nozzle_diameter", 0);
+
+ PrintStatistics print_statistic = wxGetApp().plater()->get_fff_prints()[s_multiple_beds.get_active_bed()].get()->print_statistics();
+ pdata.gcode_prediction = print_statistic.normal_print_time_seconds;
+ pdata.gcode_weight = print_statistic.total_weight;
+
+ std::vector pdata_extruders = print_statistic.printing_extruders;
+ pdata.used_extruders = pdata_extruders;
+
+ const auto& extruders_filaments = wxGetApp().preset_bundle->extruders_filaments;
+
+ unsigned int j = 0;
+ std::vector filament_colors;
+ for (const auto& [filament_id, filament_vol] : print_statistic.filament_stats) {
+ assert(filament_id < extruders_filaments.size());
+ if (const Preset* preset = extruders_filaments[filament_id].get_selected_preset()) {
+ double filament_weight;
+ if (print_statistic.filament_stats.size() == 1)
+ filament_weight = print_statistic.total_weight;
+ else {
+ double filament_density = preset->config.opt_float("filament_density", 0);
+ filament_weight = filament_vol * filament_density/* *2.4052f*/ * 0.001; // assumes 1.75mm filament diameter;
+ }
+
+ float t_filament_diameter = preset->config.opt_float("filament_diameter", 0u);
+ double t_filament_length = filament_vol / (M_PI * t_filament_diameter * t_filament_diameter / 4.0) / 1000.0;
+ std::string t_filament_type = preset->config.opt_string("filament_type", 0u);
+ std::string t_filament_id = preset->config.opt_string("filament_id", 0u);
+ std::string t_filament_color = cfg.opt_string("extruder_colour", j);
+ if (t_filament_color.empty())
+ t_filament_color = preset->config.opt_string("filament_colour", 0u);
+ filament_colors.push_back(t_filament_color);
+
+ std::string msg = (boost::format(" ")
+ % (pdata_extruders[j] + 1)
+ % t_filament_id
+ % t_filament_type
+ % t_filament_color
+ % t_filament_length
+ % filament_weight).str();
+ filament_msg.push_back(msg);
+ }
+ j++;
+ }
+ pdata.filament_colors = filament_colors;
+ pdata.filament_msg = filament_msg;
+ plate_datas.push_back(pdata);
+ }
+
+ std::string gcode_temp_path = p->background_process.temp_gcode_output_path();
+ bool ret = false;
+ try
+ {
+ ret = Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_datas, true, true, gcode_temp_path, all_gcodes, plate_datas);
+ return ret;
+ }
+ catch (boost::filesystem::filesystem_error& e)
+ {
+ const wxString what = _("Unable to save file") + ": " + path_u8 + "\n" + e.code().message();
+ MessageDialog dlg(this, what, _("Error saving gcode.3mf file"), wxOK | wxICON_ERROR);
+ dlg.ShowModal();
+ return false;
+ }
+ }
+ return false;
+}
+
void Plater::reload_from_disk()
{
p->reload_from_disk();
@@ -7396,50 +7594,9 @@ void Plater::send_gcode()
}
max_send_number = std::stoi(wxGetApp().app_config->get("max_send"));
- std::string selected_printer_host = "";
- bool has_select_printer = wxGetApp().preset_bundle->physical_printers.has_selection();
- if (has_select_printer) {
- PhysicalPrinter& ph_printer = wxGetApp().preset_bundle->physical_printers.get_selected_printer();
- selected_printer_host = ph_printer.config.opt_string("print_host");
- }
-
- std::string sync_ip = box_msg.box_list_printer_ip;
- //y28
- std::string sync_api_key = box_msg.box_list_printer_api_key;
-
- bool has_diff = false;
-
- if(sync_ip.empty()){
- ;
- }
- else if (selected_printer_host != sync_ip && !selected_printer_host.empty()){
- WarningDialog(this, _L("Please note that the printer of the synchronous BOX does not match the currently selected printer.")).ShowModal();
- }
-#if QDT_RELEASE_TO_PUBLIC
- else{
- QIDINetwork qidi;
- wxString msg = "";
- GUI::Box_info filament_info;
- //y28
- filament_info = qidi.get_box_info(msg, sync_ip, sync_api_key);
- GUI::Box_info cur_box_info;
- cur_box_info = get_cur_box_info();
-
- if (filament_info.filament_index != cur_box_info.filament_index
- || filament_info.filament_vendor != cur_box_info.filament_vendor
- || filament_info.filament_color_index != cur_box_info.filament_color_index
- || filament_info.slot_state != cur_box_info.slot_state
- || filament_info.slot_id != cur_box_info.slot_id
- || filament_info.box_count != cur_box_info.box_count
- || filament_info.auto_reload_detect != cur_box_info.auto_reload_detect) {
- has_diff = true;
- }
-#endif
- }
-
- if(has_diff){
- WarningDialog(this, _L("The BOX information has been updated. Please resynchronize.")).ShowModal();
- }
+ bool qidi_3mf = wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_bool("is_support_3mf");
+ if (qidi_3mf)
+ default_output_file.replace_extension(".gcode.3mf");
//B61 //y20
PrintHostSendDialog dlg(default_output_file, PrintHostPostUploadAction::StartPrint, groups, storage_paths, storage_names, this, only_link);
@@ -7482,6 +7639,24 @@ void Plater::send_gcode()
std::chrono::system_clock::time_point curr_time = std::chrono::system_clock::now();
//auto diff = std::chrono::duration_cast(curr_time - m_time_p);
+
+
+ fs::path output_path(wxStandardPaths::Get().GetTempDir().utf8_str().data());
+ fs::path temp_path;
+ bool temp_file_is_ready = true;
+ if(qidi_3mf){
+ temp_path = output_path/(boost::format(".%1%.gcode.3mf") % get_current_pid()).str();
+ temp_file_is_ready = export_gcode_3mf(temp_path);
+ } else {
+ temp_path = output_path/(boost::format(".%1%_%2%.gcode") % get_current_pid() % s_multiple_beds.get_active_bed()).str();
+ temp_file_is_ready = fs::exists(temp_path);
+ }
+
+ if(!temp_file_is_ready){
+ show_error(this, _L("Temporary file could not be created."));
+ return;
+ }
+
for (int i = 0; i < pppd.size(); i++) {
if (checkbox_status[i]) {
auto preset_data = pppd[i];
@@ -7491,6 +7666,9 @@ void Plater::send_gcode()
return;
upload_job.upload_data.upload_path = dlg.filename();
+ upload_job.upload_data.source_path = temp_path;
+ upload_job.upload_data.is_3mf = qidi_3mf;
+ upload_job.upload_data.plate_index = s_multiple_beds.get_active_bed() + 1;
upload_job.upload_data.post_action = dlg.post_action();
upload_job.upload_data.group = dlg.group();
upload_job.upload_data.storage = dlg.storage();
@@ -7552,10 +7730,13 @@ void Plater::send_gcode()
if (upload_job.empty())
return;
upload_job.upload_data.upload_path = dlg.filename();
+ upload_job.upload_data.source_path = temp_path;
+ upload_job.upload_data.is_3mf = qidi_3mf;
+ upload_job.upload_data.plate_index = s_multiple_beds.get_active_bed() + 1;
upload_job.upload_data.post_action = dlg.post_action();
upload_job.upload_data.group = dlg.group();
upload_job.upload_data.storage = dlg.storage();
- upload_job.create_time = std::chrono::system_clock::now();
+ upload_job.create_time = std::chrono::system_clock::now();
if (UploadCount != 0 && UploadCount % std::stoi(wxGetApp().app_config->get("max_send")) == 0) {
m_sending_interval += std::stoi(wxGetApp().app_config->get("sending_interval")) * 60;
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 7b1afb0..29304f9 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -502,6 +502,10 @@ public:
GUI::Box_info get_cur_box_info() { return current_box_info; };
#endif
+ //y29
+ void export_gcode_3mf(bool prefer_removable = false, bool all_gcodes = false);
+ bool export_gcode_3mf(const boost::filesystem::path& output_path, bool all_gcodes = false);
+
private:
std::optional get_default_output_file();
std::optional check_output_path_has_error(const boost::filesystem::path& path) const;
diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp
index aca1bf6..08fa3b4 100644
--- a/src/slic3r/GUI/PrintHostDialogs.cpp
+++ b/src/slic3r/GUI/PrintHostDialogs.cpp
@@ -418,7 +418,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
txt_filename->SetValue(recent_path);
- if (size_t extension_start = recent_path.find_last_of('.'); extension_start != std::string::npos)
+ if (size_t extension_start = recent_path.find_first_of('.'); extension_start != std::string::npos)
m_valid_suffix = recent_path.substr(extension_start);
// .gcode suffix control
auto validate_path = [this](const wxString &path) -> bool {
diff --git a/src/slic3r/GUI/PrinterWebView.cpp b/src/slic3r/GUI/PrinterWebView.cpp
index e61835d..9f3ebe7 100644
--- a/src/slic3r/GUI/PrinterWebView.cpp
+++ b/src/slic3r/GUI/PrinterWebView.cpp
@@ -411,20 +411,30 @@ void PrinterWebView::SetPresetChanged(bool status) {
ShowNetPrinterButton();
else
ShowLocalPrinterButton();
- //y3
+ //y3 //y29
if (webisNetMode == isNetWeb) {
for (DeviceButton* button : m_net_buttons) {
- if (button->getIPLabel().find(m_ip) != std::string::npos) {
- button->SetIsSelected(true);
- break;
- }
+ wxString button_ip = button->getIPLabel();
+ if (button_ip.Lower().starts_with("http"))
+ button_ip.Remove(0, 7);
+ if (button_ip.Lower().ends_with("10088"))
+ button_ip.Remove(button_ip.length() - 6);
+ if (button_ip == m_ip) {
+ button->SetIsSelected(true);
+ break;
+ }
}
}
else if (webisNetMode == isLocalWeb)
{
for (DeviceButton* button : m_buttons)
{
- if (button->getIPLabel().find(m_ip) != std::string::npos)
+ wxString button_ip = button->getIPLabel();
+ if (button_ip.Lower().starts_with("http"))
+ button_ip.Remove(0, 7);
+ if (button_ip.Lower().ends_with("10088"))
+ button_ip.Remove(button_ip.length() - 6);
+ if (button_ip == m_ip)
{
button->SetIsSelected(true);
break;
@@ -1026,8 +1036,14 @@ void PrinterWebView::load_url(wxString &url)
button->SetIsSelected(false);
}
+ //y29
for (DeviceButton *button : m_buttons) {
- if ((button->getIPLabel()).find(m_ip) != std::string::npos)
+ wxString button_ip = button->getIPLabel();
+ if (button_ip.Lower().starts_with("http"))
+ button_ip.Remove(0, 7);
+ if (button_ip.Lower().ends_with("10088"))
+ button_ip.Remove(button_ip.length() - 6);
+ if (button_ip == m_ip)
button->SetIsSelected(true);
else
button->SetIsSelected(false);
diff --git a/src/slic3r/GUI/Sidebar.cpp b/src/slic3r/GUI/Sidebar.cpp
index 243c906..3a08045 100644
--- a/src/slic3r/GUI/Sidebar.cpp
+++ b/src/slic3r/GUI/Sidebar.cpp
@@ -482,13 +482,17 @@ Sidebar::Sidebar(Plater *parent)
init_btn(&m_btn_reslice , _L("Slice now") , scaled_height);
init_btn(&m_btn_connect_gcode, _L("Send to Connect"), scaled_height);
+ //y29
+ init_btn(&m_btn_export_gcode_3mf, _L("Export File"), scaled_height);
+
enable_buttons(false);
m_btns_sizer = new wxBoxSizer(wxVERTICAL);
auto *complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL);
complect_btns_sizer->Add(m_btn_export_gcode, 1, wxEXPAND);
-
+ //y29
+ complect_btns_sizer->Add(m_btn_export_gcode_3mf, 1, wxEXPAND);
//B
m_btn_connect_gcode->Hide();
@@ -517,9 +521,11 @@ Sidebar::Sidebar(Plater *parent)
init_scalable_btn(&m_btn_export_all_gcode_removable, "export_to_sd", _L("Export all to SD card / Flash drive") + " " + GUI::shortkey_ctrl_prefix() + "U");
init_btn(&m_btn_export_all_gcode, _L("Export all G-codes") + dots, scaled_height);
+ init_btn(&m_btn_export_all_gcode_3mf, _L("Export all gcode.3mf"), scaled_height); //y29
init_btn(&m_btn_connect_gcode_all, _L("Send all to Connect"), scaled_height);
m_autoslicing_btns_sizer->Add(m_btn_export_all_gcode, 1, wxEXPAND);
+ m_autoslicing_btns_sizer->Add(m_btn_export_all_gcode_3mf, 1, wxEXPAND); //y29
m_autoslicing_btns_sizer->Add(m_btn_connect_gcode_all, 1, wxEXPAND | wxLEFT, margin_5);
m_autoslicing_btns_sizer->Add(m_btn_export_all_gcode_removable, 0, wxLEFT, margin_5);
@@ -530,6 +536,8 @@ Sidebar::Sidebar(Plater *parent)
// Events
m_btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { m_plater->export_gcode(false); });
+ //y29
+ m_btn_export_gcode_3mf->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { m_plater->export_gcode_3mf(false); });
m_btn_reslice->Bind(wxEVT_BUTTON, [this](wxCommandEvent&)
{
if (m_plater->canvas3D()->get_gizmos_manager().is_in_editing_mode(true))
@@ -564,6 +572,11 @@ Sidebar::Sidebar(Plater *parent)
this->m_plater->export_all_gcodes(false);
});
+ //y29
+ m_btn_export_all_gcode_3mf->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
+ this->m_plater->export_gcode_3mf(false, true);
+ });
+
m_btn_export_all_gcode_removable->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
this->m_plater->export_all_gcodes(true);
});
@@ -797,6 +810,7 @@ void Sidebar::msw_rescale()
#endif
m_btn_export_gcode->SetMinSize(wxSize(-1, scaled_height));
m_btn_reslice ->SetMinSize(wxSize(-1, scaled_height));
+ m_btn_export_gcode_3mf->SetMinSize(wxSize(-1, scaled_height));
m_scrolled_panel->Layout();
}
@@ -806,11 +820,11 @@ void Sidebar::sys_color_changed()
#ifdef _WIN32
wxWindowUpdateLocker noUpdates(this);
- for (wxWindow* win : std::vector{ this, m_sliced_info->GetStaticBox(), m_object_info->GetStaticBox(), m_btn_reslice, m_btn_export_gcode })
+ for (wxWindow* win : std::vector{ this, m_sliced_info->GetStaticBox(), m_object_info->GetStaticBox(), m_btn_reslice, m_btn_export_gcode, m_btn_export_gcode_3mf })
wxGetApp().UpdateDarkUI(win);
for (wxWindow* win : std::vector{ m_scrolled_panel, m_presets_panel })
wxGetApp().UpdateAllStaticTextDarkUI(win);
- for (wxWindow* btn : std::vector{ m_btn_reslice, m_btn_export_gcode, m_btn_connect_gcode })
+ for (wxWindow* btn : std::vector{ m_btn_reslice, m_btn_export_gcode, m_btn_connect_gcode, m_btn_export_gcode_3mf })
wxGetApp().UpdateDarkUI(btn, true);
m_frequently_changed_parameters->sys_color_changed();
@@ -1142,6 +1156,7 @@ void Sidebar::enable_buttons(bool enable)
m_btn_send_gcode->Enable(enable);
m_btn_export_gcode_removable->Enable(enable);
m_btn_connect_gcode->Enable(enable);
+ m_btn_export_gcode_3mf->Enable(enable);
}
//Y5
@@ -1151,6 +1166,7 @@ void Sidebar::enable_export_buttons(bool enable)
m_btn_send_gcode->Enable(enable);
// p->btn_eject_device->Enable(enable);
m_btn_export_gcode_removable->Enable(enable);
+ m_btn_export_gcode_3mf->Enable(enable);
}
void Sidebar::enable_bulk_buttons(bool enable)
@@ -1158,6 +1174,8 @@ void Sidebar::enable_bulk_buttons(bool enable)
m_btn_export_all_gcode->Enable(enable);
m_btn_export_all_gcode_removable->Enable(enable);
m_btn_connect_gcode_all->Enable(enable);
+ //y29
+ m_btn_export_all_gcode_3mf->Enable(enable);
}
bool Sidebar::show_reslice(bool show) const {
@@ -1184,6 +1202,15 @@ bool Sidebar::show_export_removable(bool show) const {
}
return m_btn_export_gcode_removable->Show(show);
}
+
+//y29
+bool Sidebar::show_gcode_3mf_export(bool show) const {
+ if (this->m_autoslicing_mode) {
+ return false;
+ }
+ return m_btn_export_gcode_3mf->Show(show);
+}
+
bool Sidebar::show_connect(bool show) const {
if (this->m_autoslicing_mode) {
return false;
@@ -1194,6 +1221,12 @@ bool Sidebar::show_connect(bool show) const {
bool Sidebar::show_export_all(bool show) const {
return m_btn_export_all_gcode->Show(show);
};
+
+//y29
+bool Sidebar::show_export_all_3mf(bool show) const {
+ return m_btn_export_all_gcode_3mf->Show(show);
+};
+
bool Sidebar::show_export_removable_all(bool show) const {
return m_btn_export_all_gcode_removable->Show(show);
};
@@ -1243,6 +1276,7 @@ void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& lab
case ActionButtonType::Export: m_btn_export_gcode->SetLabelText(label); break;
case ActionButtonType::SendGCode: /*m_btn_send_gcode->SetLabelText(label);*/ break;
case ActionButtonType::Connect: /*m_btn_connect_gcode->SetLabelText(label);*/ break;
+ case ActionButtonType::ExportGCode3MF: m_btn_export_gcode_3mf->SetLabelText(label); break;
}
}
diff --git a/src/slic3r/GUI/Sidebar.hpp b/src/slic3r/GUI/Sidebar.hpp
index cb8eef2..c425677 100644
--- a/src/slic3r/GUI/Sidebar.hpp
+++ b/src/slic3r/GUI/Sidebar.hpp
@@ -35,7 +35,8 @@ enum class ActionButtonType : int {
Reslice,
Export,
SendGCode,
- Connect
+ Connect,
+ ExportGCode3MF
};
class Sidebar : public wxPanel
@@ -66,10 +67,14 @@ class Sidebar : public wxPanel
wxButton* m_btn_export_gcode { nullptr };
wxButton* m_btn_reslice { nullptr };
wxButton* m_btn_connect_gcode { nullptr };
+ //y29
+ wxButton* m_btn_export_gcode_3mf {nullptr};
+
ScalableButton* m_btn_send_gcode { nullptr };
ScalableButton* m_btn_export_gcode_removable{ nullptr }; //exports to removable drives (appears only if removable drive is connected)
//
wxButton* m_btn_export_all_gcode { nullptr };
+ wxButton* m_btn_export_all_gcode_3mf { nullptr }; //y29
wxButton* m_btn_connect_gcode_all { nullptr };
ScalableButton* m_btn_export_all_gcode_removable{ nullptr };
@@ -130,6 +135,7 @@ public:
bool show_export_all(bool show) const;
bool show_export_removable_all(bool show) const;
bool show_connect_all(bool show) const;
+ bool show_export_all_3mf(bool show) const; //y29
void switch_to_autoslicing_mode();
void switch_from_autoslicing_mode();
@@ -148,6 +154,9 @@ public:
void sys_color_changed();
bool is_collapsed{ false };
+
+ //y29
+ bool show_gcode_3mf_export(bool show) const;
};
} // namespace GUI
diff --git a/src/slic3r/GUI/SyncBoxInfoDialog.cpp b/src/slic3r/GUI/SyncBoxInfoDialog.cpp
index 76d31f4..0d8513f 100644
--- a/src/slic3r/GUI/SyncBoxInfoDialog.cpp
+++ b/src/slic3r/GUI/SyncBoxInfoDialog.cpp
@@ -113,7 +113,7 @@ namespace Slic3r { namespace GUI {
m_button_sync = static_cast(this->FindWindowById(wxID_OK, this));
m_button_cancel = static_cast(this->FindWindowById(wxID_CANCEL, this));
m_button_sync->Bind(wxEVT_BUTTON, &GetBoxInfoDialog::synchronization, this);
- m_button_sync->Bind(wxEVT_BUTTON, &GetBoxInfoDialog::cancel, this);
+ m_button_cancel->Bind(wxEVT_BUTTON, &GetBoxInfoDialog::cancel, this);
#ifdef _WIN32
wxGetApp().UpdateDarkUI(m_button_sync);
wxGetApp().UpdateDarkUI(m_button_cancel);
diff --git a/src/slic3r/Utils/Moonraker.cpp b/src/slic3r/Utils/Moonraker.cpp
index e4d4b72..e6f89a8 100644
--- a/src/slic3r/Utils/Moonraker.cpp
+++ b/src/slic3r/Utils/Moonraker.cpp
@@ -437,6 +437,12 @@ bool Moonraker::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro
http.form_add("path", upload_parent_path.string());
if (upload_data.post_action == PrintHostPostUploadAction::StartPrint)
http.form_add("print", "true");
+
+ //y29
+ if(upload_data.is_3mf){
+ http.form_add("plateindex", std::to_string(upload_data.plate_index));
+ }
+
progress_percentage = 0;
http.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
.on_complete([&](std::string body, unsigned status) {
diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp
index 66a33c9..f75edb3 100644
--- a/src/slic3r/Utils/PrintHost.hpp
+++ b/src/slic3r/Utils/PrintHost.hpp
@@ -41,6 +41,10 @@ struct PrintHostUpload
PrintHostPostUploadAction post_action { PrintHostPostUploadAction::None };
std::string data_json;
+
+ //y29
+ bool is_3mf = false;
+ int plate_index = 1;
};
class PrintHost