diff --git a/.github/workflows/check_profiles.yml b/.github/workflows/check_profiles.yml index 35592ec5a4..d24e27ac89 100644 --- a/.github/workflows/check_profiles.yml +++ b/.github/workflows/check_profiles.yml @@ -34,6 +34,46 @@ jobs: python3 ./scripts/orca_extra_profile_check.py 2>&1 | tee ${{ runner.temp }}/extra_json_check.log exit ${PIPESTATUS[0]} + - name: Check profile indentation + id: indentation_check + continue-on-error: true + run: | + set +e + python3 - <<'PY' 2>&1 | tee ${{ runner.temp }}/indentation_check.log + import re + from pathlib import Path + import sys + + profiles_root = Path("resources/profiles") + invalid_files = [] + + for file_path in sorted(profiles_root.rglob("*.json")): + try: + for line_number, line in enumerate(file_path.read_text(encoding="utf-8").splitlines(), start=1): + if not line.strip(): + continue + leading_ws = re.match(r"^[ \t]*", line).group(0) + if " " in leading_ws: + invalid_files.append((file_path, line_number)) + break + except Exception as exc: + print(f"[ERROR] Unable to read {file_path}: {exc}") + invalid_files.append((file_path, 0)) + + if invalid_files: + for path, line in invalid_files: + if line > 0: + print(f"[ERROR] Space indentation found in {path}:{line}") + else: + print(f"[ERROR] Could not validate indentation in {path}") + print("Use tab indentation in profile JSON files (1 tab per indentation level).") + print("Tip: run python3 ./scripts/orca_filament_lib.py --fix --force to normalize formatting.") + sys.exit(1) + + print("All profile JSON files use tab-only indentation.") + PY + exit ${PIPESTATUS[0]} + # download - name: Download working-directory: ${{ github.workspace }} @@ -62,7 +102,7 @@ jobs: exit ${PIPESTATUS[0]} - name: Prepare comment artifact - if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} + if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.indentation_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} run: | mkdir -p ${{ runner.temp }}/profile-check-results @@ -79,6 +119,15 @@ jobs: echo "" fi + if [ "${{ steps.indentation_check.outcome }}" = "failure" ]; then + echo "### Indentation Check Failed" + echo "" + echo '```' + head -c 30000 ${{ runner.temp }}/indentation_check.log || echo "No output captured" + echo '```' + echo "" + fi + if [ "${{ steps.validate_system.outcome }}" = "failure" ]; then echo "### System Profile Validation Failed" echo "" @@ -104,7 +153,7 @@ jobs: echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt - name: Upload comment artifact - if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} + if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.indentation_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} uses: actions/upload-artifact@v7 with: name: profile-check-results @@ -112,7 +161,7 @@ jobs: retention-days: 1 - name: Fail if any check failed - if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} + if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.indentation_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} run: | echo "One or more profile checks failed. See above for details." exit 1 diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index 05728b977d..33d9dbb407 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -13121,6 +13121,9 @@ msgstr "" msgid "Contour" msgstr "" +msgid "Hole" +msgstr "" + msgid "Contour and hole" msgstr "" diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po index 7960f651a6..768d46bd79 100644 --- a/localization/i18n/ca/OrcaSlicer_ca.po +++ b/localization/i18n/ca/OrcaSlicer_ca.po @@ -15232,6 +15232,9 @@ msgstr "Només pintat" msgid "Contour" msgstr "Contorn" +msgid "Hole" +msgstr "Forat" + msgid "Contour and hole" msgstr "Contorn i forat" diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po index 2ce84a0cde..6755d2502f 100644 --- a/localization/i18n/cs/OrcaSlicer_cs.po +++ b/localization/i18n/cs/OrcaSlicer_cs.po @@ -11072,7 +11072,7 @@ msgid "Gizmo assemble" msgstr "Gizmo sestavit" msgid "Gizmo brim ears" -msgstr "Gizmo přídavky okraje (uši)" +msgstr "Gizmo ouška lemu" msgid "Zoom in" msgstr "Přiblížit" @@ -12583,13 +12583,13 @@ msgstr "" "průtokovým poměrem filamentu a případně průtokovým poměrem objektu." msgid "Set other flow ratios" -msgstr "Set other flow ratios" +msgstr "Nastavit další poměry průtoku" msgid "Change flow ratios for other extrusion path types." -msgstr "Change flow ratios for other extrusion path types." +msgstr "Změnit poměry průtoku pro další typy extruzních drah." msgid "First layer flow ratio" -msgstr "First layer flow ratio" +msgstr "Poměr průtoku první vrstvy" msgid "" "This factor affects the amount of material on the first layer for the " @@ -12598,14 +12598,14 @@ msgid "" "For the first layer, the actual flow ratio for each path role (does not " "affect brims and skirts) will be multiplied by this value." msgstr "" -"This factor affects the amount of material on the first layer for the " -"extrusion path roles listed in this section.\n" +"Tento faktor ovlivňuje množství materiálu na první vrstvě pro role extruzních " +"drah uvedené v této sekci.\n" "\n" -"For the first layer, the actual flow ratio for each path role (does not " -"affect brims and skirts) will be multiplied by this value." +"Pro první vrstvu bude skutečný poměr průtoku pro každou roli dráhy (neovlivňuje " +"lem a sukni) vynásoben touto hodnotou." msgid "Outer wall flow ratio" -msgstr "Outer wall flow ratio" +msgstr "Poměr průtoku vnější stěny" msgid "" "This factor affects the amount of material for outer walls.\n" @@ -12613,13 +12613,13 @@ msgid "" "The actual outer wall flow used is calculated by multiplying this value by " "the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for outer walls.\n" +"Tento faktor ovlivňuje množství materiálu pro vnější stěny.\n" "\n" -"The actual outer wall flow used is calculated by multiplying this value by " -"the filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro vnější stěny se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Inner wall flow ratio" -msgstr "Inner wall flow ratio" +msgstr "Poměr průtoku vnitřní stěny" msgid "" "This factor affects the amount of material for inner walls.\n" @@ -12627,13 +12627,13 @@ msgid "" "The actual inner wall flow used is calculated by multiplying this value by " "the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for inner walls.\n" +"Tento faktor ovlivňuje množství materiálu pro vnitřní stěny.\n" "\n" -"The actual inner wall flow used is calculated by multiplying this value by " -"the filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro vnitřní stěny se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Overhang flow ratio" -msgstr "Overhang flow ratio" +msgstr "Poměr průtoku převisů" msgid "" "This factor affects the amount of material for overhangs.\n" @@ -12641,13 +12641,13 @@ msgid "" "The actual overhang flow used is calculated by multiplying this value by the " "filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for overhangs.\n" +"Tento faktor ovlivňuje množství materiálu pro převisy.\n" "\n" -"The actual overhang flow used is calculated by multiplying this value by the " -"filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro převisy se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Sparse infill flow ratio" -msgstr "Sparse infill flow ratio" +msgstr "Poměr průtoku řídké výplně" msgid "" "This factor affects the amount of material for sparse infill.\n" @@ -12655,13 +12655,13 @@ msgid "" "The actual sparse infill flow used is calculated by multiplying this value " "by the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for sparse infill.\n" +"Tento faktor ovlivňuje množství materiálu pro řídkou výplň.\n" "\n" -"The actual sparse infill flow used is calculated by multiplying this value " -"by the filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro řídkou výplň se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Internal solid infill flow ratio" -msgstr "Internal solid infill flow ratio" +msgstr "Poměr průtoku vnitřní plné výplně" msgid "" "This factor affects the amount of material for internal solid infill.\n" @@ -12669,13 +12669,13 @@ msgid "" "The actual internal solid infill flow used is calculated by multiplying this " "value by the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for internal solid infill.\n" +"Tento faktor ovlivňuje množství materiálu pro vnitřní plnou výplň.\n" "\n" -"The actual internal solid infill flow used is calculated by multiplying this " -"value by the filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro vnitřní plnou výplň se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Gap fill flow ratio" -msgstr "Gap fill flow ratio" +msgstr "Poměr průtoku vyplnění mezer" msgid "" "This factor affects the amount of material for filling the gaps.\n" @@ -12683,13 +12683,13 @@ msgid "" "The actual gap filling flow used is calculated by multiplying this value by " "the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for filling the gaps.\n" +"Tento faktor ovlivňuje množství materiálu pro vyplnění mezer.\n" "\n" -"The actual gap filling flow used is calculated by multiplying this value by " -"the filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro vyplnění mezer se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Support flow ratio" -msgstr "Support flow ratio" +msgstr "Poměr průtoku podpěr" msgid "" "This factor affects the amount of material for support.\n" @@ -12697,13 +12697,13 @@ msgid "" "The actual support flow used is calculated by multiplying this value by the " "filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for support.\n" +"Tento faktor ovlivňuje množství materiálu pro podpěry.\n" "\n" -"The actual support flow used is calculated by multiplying this value by the " -"filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro podpěry se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Support interface flow ratio" -msgstr "Support interface flow ratio" +msgstr "Poměr průtoku rozhraní podpěr" msgid "" "This factor affects the amount of material for the support interface.\n" @@ -12711,10 +12711,10 @@ msgid "" "The actual support interface flow used is calculated by multiplying this " "value by the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"This factor affects the amount of material for the support interface.\n" +"Tento faktor ovlivňuje množství materiálu pro rozhraní podpěr.\n" "\n" -"The actual support interface flow used is calculated by multiplying this " -"value by the filament flow ratio, and if set, the object's flow ratio." +"Skutečný průtok pro rozhraní podpěr se vypočítá vynásobením této hodnoty " +"poměrem průtoku filamentu a případně také poměrem průtoku objektu." msgid "Precise wall" msgstr "Přesná stěna" @@ -14821,6 +14821,9 @@ msgstr "Painted only" msgid "Contour" msgstr "Obrys" +msgid "Hole" +msgstr "Otvor" + msgid "Contour and hole" msgstr "Obrys a otvor" diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po index 8614a865d5..26a85806e3 100644 --- a/localization/i18n/de/OrcaSlicer_de.po +++ b/localization/i18n/de/OrcaSlicer_de.po @@ -15357,6 +15357,9 @@ msgstr "Nur lackiert" msgid "Contour" msgstr "Kontur" +msgid "Hole" +msgstr "Loch" + msgid "Contour and hole" msgstr "Kontur und Loch" diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po index 96d1f5c588..1103146ce0 100644 --- a/localization/i18n/en/OrcaSlicer_en.po +++ b/localization/i18n/en/OrcaSlicer_en.po @@ -13403,6 +13403,9 @@ msgstr "" msgid "Contour" msgstr "" +msgid "Hole" +msgstr "" + msgid "Contour and hole" msgstr "" diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po index 142ada0d46..c52a64f72a 100644 --- a/localization/i18n/es/OrcaSlicer_es.po +++ b/localization/i18n/es/OrcaSlicer_es.po @@ -15294,6 +15294,9 @@ msgstr "Solo pintado" msgid "Contour" msgstr "Contorno" +msgid "Hole" +msgstr "Orificio" + msgid "Contour and hole" msgstr "Contorno y orificio" diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po index 3e285b8c4a..c7e9d3f354 100644 --- a/localization/i18n/fr/OrcaSlicer_fr.po +++ b/localization/i18n/fr/OrcaSlicer_fr.po @@ -15433,6 +15433,9 @@ msgstr "Peint uniquement" msgid "Contour" msgstr "Contour" +msgid "Hole" +msgstr "Trou" + msgid "Contour and hole" msgstr "Contour et trou" diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po index 80d440642e..d4660b0ec6 100644 --- a/localization/i18n/hu/OrcaSlicer_hu.po +++ b/localization/i18n/hu/OrcaSlicer_hu.po @@ -15122,6 +15122,9 @@ msgstr "Csak festett" msgid "Contour" msgstr "Kontúr" +msgid "Hole" +msgstr "Lyuk" + msgid "Contour and hole" msgstr "Kontúr és lyuk" diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index b33ae653af..f49ac5711a 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -15319,6 +15319,9 @@ msgstr "Solo verniciato" msgid "Contour" msgstr "Contorno" +msgid "Hole" +msgstr "Foro" + msgid "Contour and hole" msgstr "Contorno e foro" diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po index 7a3d446f82..0b1d6d4f4a 100644 --- a/localization/i18n/ja/OrcaSlicer_ja.po +++ b/localization/i18n/ja/OrcaSlicer_ja.po @@ -14093,6 +14093,9 @@ msgstr "塗装のみ" msgid "Contour" msgstr "輪郭" +msgid "Hole" +msgstr "穴" + msgid "Contour and hole" msgstr "輪郭と穴" diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po index ec0168dd4c..85d1925bf6 100644 --- a/localization/i18n/ko/OrcaSlicer_ko.po +++ b/localization/i18n/ko/OrcaSlicer_ko.po @@ -14240,6 +14240,9 @@ msgstr "도색만" msgid "Contour" msgstr "윤곽" +msgid "Hole" +msgstr "구멍" + msgid "Contour and hole" msgstr "윤곽 및 구멍" diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po index 877e0693c8..0245eb9b3d 100644 --- a/localization/i18n/lt/OrcaSlicer_lt.po +++ b/localization/i18n/lt/OrcaSlicer_lt.po @@ -15043,6 +15043,9 @@ msgstr "Tik dažytas" msgid "Contour" msgstr "Kontūras" +msgid "Hole" +msgstr "Skylė" + msgid "Contour and hole" msgstr "Kontūras ir skylė" diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po index 7266a862b7..1dec100c62 100644 --- a/localization/i18n/nl/OrcaSlicer_nl.po +++ b/localization/i18n/nl/OrcaSlicer_nl.po @@ -15043,6 +15043,9 @@ msgstr "Alleen geverfd" msgid "Contour" msgstr "Contour" +msgid "Hole" +msgstr "Gat" + msgid "Contour and hole" msgstr "Contour en gat" diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po index b991f18681..fefb91e288 100644 --- a/localization/i18n/pl/OrcaSlicer_pl.po +++ b/localization/i18n/pl/OrcaSlicer_pl.po @@ -14539,6 +14539,9 @@ msgstr "Tylko malowane" msgid "Contour" msgstr "Kontur" +msgid "Hole" +msgstr "Otwory" + msgid "Contour and hole" msgstr "Kontur i otwory" diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po index 4c2bc0d138..47c06c471c 100644 --- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po +++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po @@ -15186,6 +15186,9 @@ msgstr "Somente pintado" msgid "Contour" msgstr "Contorno" +msgid "Hole" +msgstr "Furo" + msgid "Contour and hole" msgstr "Contorno e furo" diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index c344999ab3..4998ad9034 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -15501,6 +15501,9 @@ msgstr "Вручную" msgid "Contour" msgstr "Контур" +msgid "Hole" +msgstr "Отверстия" + msgid "Contour and hole" msgstr "Контур и отверстия" diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po index 4a7e8b3acc..d3665b412b 100644 --- a/localization/i18n/sv/OrcaSlicer_sv.po +++ b/localization/i18n/sv/OrcaSlicer_sv.po @@ -14883,6 +14883,9 @@ msgstr "Endast målad" msgid "Contour" msgstr "Kontur" +msgid "Hole" +msgstr "Hål" + msgid "Contour and hole" msgstr "Kontur och hål" diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po index 84238e9b72..1739550e07 100644 --- a/localization/i18n/tr/OrcaSlicer_tr.po +++ b/localization/i18n/tr/OrcaSlicer_tr.po @@ -13339,6 +13339,9 @@ msgstr "Sadece boyalı" msgid "Contour" msgstr "Kontur" +msgid "Hole" +msgstr "Delik" + msgid "Contour and hole" msgstr "Kontur ve delik" diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po index 56737be7e8..99466c46dc 100644 --- a/localization/i18n/uk/OrcaSlicer_uk.po +++ b/localization/i18n/uk/OrcaSlicer_uk.po @@ -14536,6 +14536,9 @@ msgstr "Тільки пофарбовані" msgid "Contour" msgstr "Контур" +msgid "Hole" +msgstr "Отвір" + msgid "Contour and hole" msgstr "Контур та отвір" diff --git a/localization/i18n/vi/OrcaSlicer_vi.po b/localization/i18n/vi/OrcaSlicer_vi.po index 5ece6f7a7b..c48d08f9cb 100644 --- a/localization/i18n/vi/OrcaSlicer_vi.po +++ b/localization/i18n/vi/OrcaSlicer_vi.po @@ -14730,6 +14730,9 @@ msgstr "Chỉ được sơn" msgid "Contour" msgstr "Đường viền" +msgid "Hole" +msgstr "Lỗ" + msgid "Contour and hole" msgstr "Đường viền và lỗ" diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po index c1af59fa3c..85e2f49a05 100644 --- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po +++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po @@ -13894,6 +13894,9 @@ msgstr "仅涂漆" msgid "Contour" msgstr "轮廓" +msgid "Hole" +msgstr "孔" + msgid "Contour and hole" msgstr "轮廓和孔" diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po index 035ef1d0e2..12fc980c8f 100644 --- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po +++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po @@ -14006,6 +14006,9 @@ msgstr "僅塗漆" msgid "Contour" msgstr "輪廓" +msgid "Hole" +msgstr "孔洞" + msgid "Contour and hole" msgstr "輪廓和孔" diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index c9f0e6a73c..0def516b0c 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "02.01.00.10", + "version": "02.01.00.11", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle.json index a7fc83584b..96e9e51600 100644 --- a/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab P2S 0.4 nozzle.json @@ -161,6 +161,7 @@ ], "printable_height": "256", "auxiliary_fan": "0", + "support_air_filtration": "1", "printer_extruder_id": [ "1", "1" @@ -242,10 +243,10 @@ "Bambu Lab H2D 0.4 nozzle", "Bambu Lab H2D Pro 0.4 nozzle" ], - "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== P2S start gcode==========\n;===== Based on official 2026/02/26 start gcode =====\n \n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400 \n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M620 M ;enable remap\n G389\n\n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n G90\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M975 S1 ; turn on input shaping\n M982.2 S1 ; turn on cog noise reduction\n M983.4 S0\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n;==== if Chamber Cooling is necessary ====\n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S255 ; turn on filter fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\n{else}\n{if (min_vitrification_temperature <= 50)}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n{else}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S127 ; turn on 50% filter fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PLA/TPU exhaust chamber autocooling\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M104 S140 A \n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M972 S26 P0 C0\n M972 S42 P0 T5000\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G90\n G1 X128 Y128 F30000\n G28 Z P0 T400\n M400\n;===== first homing end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n M972 S19 P0 T5000 ;plate type detection\n \n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise temp in advance\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] E0\n M620.11 K0 I[initial_no_support_extruder] R0\n \n M620 S[initial_no_support_extruder]A ; switch material if AMS exist\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n M1030 S1800\n SYNC R0 T1800\n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n \n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n \n G91\n G1 Y-16 F12000 ; move away from the trash bin\n G90\n M400\n\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n \n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n;===== wipe left nozzle end =====\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M970.2 Q1 K1 W74 Z0.01\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M970.2 Q0 K1 W74 Z0.01\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\n M623\n\n M622 J0\n ;skip to homing\n M623\n G29.2 S1\n G28\n;===== bed leveling end ================================\n\n M985.1 U0 E2\n M985.1 U1 E2\n\n M104 S[nozzle_temperature_initial_layer] A\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if bed_temperature_initial_layer_single > 89}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.0}\n {endif}\n {else}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.03}\n {endif}\n {endif}\n\n M500\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\n G90\n M83\n G1 Z0.5\n M400\n;===== nozzle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\") || \n(filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu, pla and petg clog detect\n{else}\nM1015.3 S0;disable clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM1010 Q0 B0.023 S0.01\nM1010 Q1 B0.005 S0.01\nM1010.1 S1", - "machine_end_gcode": ";======== P2S end gcode ==========\n;===== Based on official 2026/03/13 end gcode =====\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\n\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.2\nM621 S65535\n\nG150.3\n\nM400 ; wait all motion done\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\n M991 S0 P-1 ;end smooth timelapse at safe pos\n M400 S5 ;wait for last picture to be taken\nM623 ;end of \"timelapse_record_flag\"\n\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\n\nM400 ; wait all motion done\nM17 S\nM17 Z0.4 ; lower z motor current to reduce impact if there is something in the bottom\n{if (80.0 - max_layer_z/2) > 0}\n {if (max_layer_z + 80.0 - max_layer_z/2) < 256}\n G1 Z{max_layer_z + 80.0 - max_layer_z/2} F600\n G1 Z{max_layer_z + 78.0 - max_layer_z/2}\n {else}\n G1 Z256 F600\n G1 Z256\n {endif}\n{else}\n {if (max_layer_z + 4.0) < 256}\n G1 Z{max_layer_z + 4.0} F600\n G1 Z{max_layer_z + 2.0}\n {else}\n G1 Z256 F600\n G1 Z256\n {endif}\n{endif}\nM400 P100\nM17 R ; restore z current\n\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0\n\nM1015.3 S0 ;disable clog detect\nM1015.4 S0 K0 ;disable air printing detect\n\n;=====printer finish air purification=========\nM622.1 S0\nM1002 judge_flag print_finish_air_filt_flag\n\n;if activate_air_filtration is enabled in filament settings, it will skip purification regardless of what is set on the printer.\nM622 J1\n{if !activate_air_filtration[current_extruder]}\nM1002 gcode_claim_action : 66\nM145 P1\nM106 P2 S255\nM400 S180\nM106 P2 S0\n{endif}\nM623\n\nM622 J2\n{if !activate_air_filtration[current_extruder]}\nM1002 gcode_claim_action : 66\nM145 P0\nM106 P3 S255\nM400 S180\nM106 P3 S0\n{endif}\nM623\n;=====printer finish air purification=========\n\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L50 C53 D10 M50 E53 F10 N50 \nM1006 A57 B10 L50 C57 D10 M50 E57 F10 N50 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L50 C53 D10 M50 E53 F10 N50 \nM1006 A57 B10 L50 C57 D10 M50 E57 F10 N50 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L50 C48 D10 M50 E48 F10 N50 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L50 C60 D10 M50 E60 F10 N50 \nM1006 W\n;=====printer finish sound=========\nM400\nM18", - "layer_change_gcode": ";======== P2S layer_change gcode ==========\n;===== 2026/01/08 ====\n\n{if (layer_num + 1 == 1)}\n{if (overall_chamber_temperature >= 40)}\n ;not reset filter fan in first layer\n ;not reset fan\n{else}\n{if (min_vitrification_temperature > 50)}\n ;not reset filter fan in first layer\n ;not reset fan\n{endif} \n{endif}\n{endif}\n\n{if (layer_num + 1 == close_fan_the_first_x_layers[current_extruder]+1)}\n{if (overall_chamber_temperature < 40)}\n ;updata chamber autocooling in Xth layer\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n ;not reset filter fan in Xth layer\n {endif}\n{else}\n ;not reset filter fan in Xth layer\n{endif}\n M622.1 S0\n M1002 judge_flag ventobox_replace_aux1_fan_flag\n M622 J0\n M106 P10 S{additional_cooling_fan_speed[current_extruder]*255.0/100.0}; set left aux fan \n M623\n;not reset fan\n{endif}\n\n\n; update layer progress\nM73 L{layer_num+1}\nM991 S0 P{layer_num} ;notify layer change", + "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== P2S start gcode==========\n;===== Based on official 2026/04/21 start gcode =====\n \n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M620 M ;enable remap\n G389\n\n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n G90\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M975 S1 ; turn on input shaping\n M982.2 S1 ; turn on cog noise reduction\n M983.4 S0\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n;==== if Chamber Cooling is necessary ====\n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S255 ; turn on filter fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\n{else}\n{if (min_vitrification_temperature <= 50)}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\nM106 P10 S0 ; turn off left aux fan\nM623\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n{else}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S127 ; turn on 50% filter fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PLA/TPU exhaust chamber autocooling\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M104 S140 A \n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M972 S26 P0 C0\n M972 S42 P0 T5000\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G90\n G1 X128 Y128 F30000\n G28 Z P0 T400\n M400\n;===== first homing end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n M972 S19 P0 T5000 ;plate type detection\n \n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise temp in advance\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] E0\n M620.11 K0 I[initial_no_support_extruder] R0\n \n M620 S[initial_no_support_extruder]A ; switch material if AMS exist\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n M1030 S1800 \n SYNC R0 T1800\n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n \n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n\n ; series of wipes to ensure the nozzle is as clean as possible to avoid potential z-drift issues.\n M104 S180\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n M106 P1 S255\n M109 S180 A\n G150.1 F8000 \n M109 S140 A\n M106 P1 S0\n G150.1 F8000\n G91\n G1 Y-16 F12000\n G1 X100 F6000\n G90\n M400\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n \n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n;===== wipe left nozzle end =====\n\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M970.2 Q1 K1 W74 Z0.01\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M970.2 Q0 K1 W74 Z0.01\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M623\n\n M622 J0\n ;skip to homing\n M623\n G29.2 S1\n G28\n;===== bed leveling end ================================\n\n M985.1 U0 E2\n M985.1 U1 E2\n\n M104 S[nozzle_temperature_initial_layer] A\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A\n M400\n T[initial_no_support_extruder]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if bed_temperature_initial_layer_single > 89}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.0}\n {endif}\n {else}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.03}\n {endif}\n {endif}\n\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\n G90\n M83\n G1 Z1\n M400\n;===== nozzle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\") || \n(filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu, pla and petg clog detect\n{else}\nM1015.3 S0;disable clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM1010 Q0 B0.023 S0.01\nM1010 Q1 B0.005 S0.01\nM1010.1 S1\n", + "machine_end_gcode": ";======== P2S end gcode ==========\n;===== Based on official 2026/04/01 end gcode =====\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\n\nG90\nG1 Z{max_layer_z + 0.4} F900 ; lower z a little\nM1002 judge_flag timelapse_record_flag\nM622 J1\n G150.3\n M400 ; wait all motion done\n M991 S0 P-1 ;end smooth timelapse at safe pos\n M400 S5 ;wait for last picture to be taken\nM623 ;end of \"timelapse_record_flag\n\nG90\nG1 Z{max_layer_z + 10} F900 ; lower z a little\n\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\n\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.1 F8000\nM621 S65535\n\nG150.3\nM104 S0 ; turn off hotend\nM400 ; wait all motion done\nM17 S\nM17 Z0.4 ; lower z motor current to reduce impact if there is something in the bottom\n{if (80.0 - max_layer_z/2) > 0}\n {if (max_layer_z + 80.0 - max_layer_z/2) < 256}\n G1 Z{max_layer_z + 80.0 - max_layer_z/2} F600\n G1 Z{max_layer_z + 78.0 - max_layer_z/2}\n {else}\n G1 Z256 F600\n G1 Z256\n {endif}\n{else}\n {if (max_layer_z + 4.0) < 256}\n G1 Z{max_layer_z + 4.0} F600\n G1 Z{max_layer_z + 2.0}\n {else}\n G1 Z256 F600\n G1 Z256\n {endif}\n{endif}\nM400 P100\nM17 R ; restore z current\n\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0\n\nM1015.3 S0 ;disable clog detect\nM1015.4 S0 K0 ;disable air printing detect\n\n;=====printer finish air purification=========\nM622.1 S0\nM1002 judge_flag print_finish_air_filt_flag\n\n;checks for activate_air_filtration_on_completion and parent flag. If enabled, the override fan speed will be used. Otherwise, the default air purification will kick in.\n\nM622 J1\n{if !activate_air_filtration[current_extruder] || (activate_air_filtration[current_extruder] && !activate_air_filtration_on_completion[current_extruder])}\nM1002 gcode_claim_action : 66\nM145 P1\nM106 P2 S255\nM400 S180\nM106 P2 S0\n{endif}\nM623\n\nM622 J2\n{if !activate_air_filtration[current_extruder] || (activate_air_filtration[current_extruder] && !activate_air_filtration_on_completion[current_extruder])}\nM1002 gcode_claim_action : 66\nM145 P0\nM106 P3 S255\nM400 S180\nM106 P3 S0\n{endif}\nM623\n;=====printer finish air purification=========\n\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L50 C53 D10 M50 E53 F10 N50 \nM1006 A57 B10 L50 C57 D10 M50 E57 F10 N50 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L50 C53 D10 M50 E53 F10 N50 \nM1006 A57 B10 L50 C57 D10 M50 E57 F10 N50 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L50 C48 D10 M50 E48 F10 N50 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L50 C60 D10 M50 E60 F10 N50 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n", + "layer_change_gcode": ";======== P2S layer_change gcode ==========\n;===== Based on official 2026/04/08 layer change gcode =====\n\n{if (layer_num + 1 == 1)}\n{if (overall_chamber_temperature >= 40)}\n ;not reset filter fan in first layer\n ;not reset fan\n{else}\n{if (min_vitrification_temperature > 50)}\n ;not reset filter fan in first layer\n ;not reset fan\n{endif} \n{endif}\n{endif}\n\n{if (layer_num + 1 <= close_fan_the_first_x_layers[current_extruder])}\n{if (overall_chamber_temperature < 40)}\n {if (min_vitrification_temperature <= 50)}\n M106 P2 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}\n {endif}\n{endif}\n M622.1 S0\n M1002 judge_flag ventobox_replace_aux1_fan_flag\n M622 J0\n M106 P10 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}; set first x_layer left aux fan \n M623\n;not reset fan\n{elsif (layer_num + 1 < full_fan_speed_layer[current_extruder] && full_fan_speed_layer[current_extruder] > close_fan_the_first_x_layers[current_extruder])}\n{if (overall_chamber_temperature < 40)}\n {if (min_vitrification_temperature <= 50)}\n M106 P2 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_fan_the_first_x_layers[current_extruder]) / (full_fan_speed_layer[current_extruder] - close_fan_the_first_x_layers[current_extruder])) * 255.0/100.0}\n {endif}\n{endif}\n M622.1 S0\n M1002 judge_flag ventobox_replace_aux1_fan_flag\n M622 J0\n M106 P10 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_fan_the_first_x_layers[current_extruder]) / (full_fan_speed_layer[current_extruder] - close_fan_the_first_x_layers[current_extruder])) * 255.0/100.0}\n M623\n;not reset fan\n{elsif (layer_num + 1 == max(close_fan_the_first_x_layers[current_extruder] + 1, full_fan_speed_layer[current_extruder]))}\n{if (overall_chamber_temperature < 40)}\n ;updata chamber autocooling in Xth layer\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n ;not reset filter fan in Xth layer\n {endif}\n{else}\n ;not reset filter fan in Xth layer\n{endif}\n M622.1 S0\n M1002 judge_flag ventobox_replace_aux1_fan_flag\n M622 J0\n M106 P10 S{additional_cooling_fan_speed[current_extruder]*255.0/100.0}; set left aux fan \n M623\n;not reset fan\n{endif}\n\n; update layer progress\nM73 L{layer_num+1}\nM991 S0 P{layer_num} ;notify layer change\n\n", "time_lapse_gcode": ";======== P2S timeslape gcode ==========\n;===== 2025/06/16 ====\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firware, default turned on\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\n{if timelapse_type == 0} ; timelapse without wipe tower\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n{elsif timelapse_type == 1} ; timelapse with wipe tower\n G150.3 ; move to garbage can\n M400\n M1004 S5 P1 ; external shutter\n M400 P300\n M971 S11 C10 O0\n M400 P350\n \n G90\n G1 Z{max_layer_z + 3.0} F1200\n G0 Y210 F18000\n{endif}\nM623\n; SKIPPABLE_END\n", "wrapping_detection_gcode": ";======== P2S 20250822 clumping ========\n{if !spiral_mode}\n M622.1 S0 ; for previous firmware, default turn off\n M1002 set_flag g39_forced_detection_flag=1\n M1002 judge_flag g39_forced_detection_flag\n M622 J1\n {if layer_num == 3 || layer_num == 10 || layer_num == 19}\n M993 A2 B2 C2 ; nozzle cam detection allow status save.\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n M400 P100\n\n G39\n\n G90\n G1 Y240 F30000\n G1 Y210 F15000\n \n M993 A3 B3 C3 ; nozzle cam detection allow status restore.\n {endif}\n M623\n{endif}", - "change_filament_gcode": ";======== P2S filament_change gcode ==========\n;===== Based on official 2026/02/27 filament change gcode =====\n\nM620 S[next_extruder]A\nM204 S9000\n{if toolchange_count > 1 && (z_hop_types[current_extruder] == 0 || z_hop_types[current_extruder] == 3)}\nG17\nG2 Z{z_after_toolchange + 0.4} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift\n{endif}\n\n;nozzle_change_gcode\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if ((filament_type[current_extruder] == \"PLA\") || (filament_type[current_extruder] == \"PLA-CF\") || (filament_type[current_extruder] == \"PETG\")) && (nozzle_diameter[current_extruder] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P{nozzle_temperature[current_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P{nozzle_temperature[current_extruder]} S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P{nozzle_temperature[next_extruder]} S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P{nozzle_temperature[next_extruder]} S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 L0 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 L0 I[current_extruder] E0\n{endif}\n\nM620.11 K0 I[current_extruder] R0\n\nT[next_extruder]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if filament_type[next_extruder] == \"PA\"}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\nSYNC T{ceil(flush_length / 80) * 5}\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\nM620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM400\n\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[travel_acceleration]\n{endif}\n\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\n\nM621 S[next_extruder]A\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\n\nG1 Y256 F18000\n\n{if (overall_chamber_temperature < 40)}\n{if (layer_num + 1 < close_fan_the_first_x_layers[next_extruder] + 1)}\n{if (min_vitrification_temperature <= 50)}\n M106 P2 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer aux fan\n {endif}\n{else}\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {endif}\n{endif}\n{endif}\n\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\n{if (layer_num + 1 < close_fan_the_first_x_layers[next_extruder] + 1)}\n M106 P10 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer left aux fan \n{else}\n M106 P10 S{additional_cooling_fan_speed[next_extruder]*255.0/100.0};set left aux fan\n{endif}\nM623\n\n;not set fan changing filament" + "change_filament_gcode": ";======== P2S filament_change gcode ==========\n;===== Based on official 2026/04/08 filament change gcode =====\n\nM620 S[next_extruder]A\nM204 S9000\n{if toolchange_count > 1 && (z_hop_types[current_extruder] == 0 || z_hop_types[current_extruder] == 3)}\nG17\nG2 Z{z_after_toolchange + 0.4} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift\n{endif}\n\n;nozzle_change_gcode\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if ((filament_type[current_extruder] == \"PLA\") || (filament_type[current_extruder] == \"PLA-CF\") || (filament_type[current_extruder] == \"PETG\")) && (nozzle_diameter[current_extruder] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P{nozzle_temperature[current_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P{nozzle_temperature[current_extruder]} S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P{nozzle_temperature[next_extruder]} S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P{nozzle_temperature[next_extruder]} S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 L0 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 L0 I[current_extruder] E0\n{endif}\n\nM620.11 K0 I[current_extruder] R0\n\n \nT[next_extruder]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if filament_type[next_extruder] == \"PA\"}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\nSYNC T{ceil(flush_length / 80) * 5}\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\nM620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\n\nM629\nM400\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM400\n\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[travel_acceleration]\n{endif}\n\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\n\nM621 S[next_extruder]A\n\nM622.1 S0 ;for prev version, default skip\nM1002 judge_flag powerloss_resume_flag\nM622 J1\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM400\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[travel_acceleration]\n{endif}\nM1002 set_flag powerloss_resume_flag=0\nM623\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\n\nG1 Y256 F18000\n\n{if (overall_chamber_temperature < 40)}\n{if (layer_num + 1 <= close_fan_the_first_x_layers[next_extruder])}\n {if (min_vitrification_temperature <= 50)}\n M106 P2 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer aux fan\n {endif}\n{elsif (layer_num + 1 < full_fan_speed_layer[next_extruder] && full_fan_speed_layer[next_extruder] > close_fan_the_first_x_layers[next_extruder])}\n {if (min_vitrification_temperature <= 50)}\n M106 P2 S{(first_x_layer_fan_speed[next_extruder] + (additional_cooling_fan_speed[next_extruder] - first_x_layer_fan_speed[next_extruder]) * (layer_num + 1 - close_fan_the_first_x_layers[next_extruder]) / (full_fan_speed_layer[next_extruder] - close_fan_the_first_x_layers[next_extruder])) * 255.0/100.0}\n {endif}\n{else}\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {endif}\n{endif}\n{endif}\n\nM622.1 S0\nM1002 judge_flag ventobox_replace_aux1_fan_flag\nM622 J0\n{if (layer_num + 1 <= close_fan_the_first_x_layers[next_extruder])}\n M106 P10 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer left aux fan \n{elsif (layer_num + 1 < full_fan_speed_layer[next_extruder] && full_fan_speed_layer[next_extruder] > close_fan_the_first_x_layers[next_extruder])}\n M106 P10 S{(first_x_layer_fan_speed[next_extruder] + (additional_cooling_fan_speed[next_extruder] - first_x_layer_fan_speed[next_extruder]) * (layer_num + 1 - close_fan_the_first_x_layers[next_extruder]) / (full_fan_speed_layer[next_extruder] - close_fan_the_first_x_layers[next_extruder])) * 255.0/100.0}\n{else}\n M106 P10 S{additional_cooling_fan_speed[next_extruder]*255.0/100.0};set left aux fan\n{endif}\nM623\n\n;not set fan changing filament" } diff --git a/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S 0.2 nozzle.json index d918d41bea..ef8582cf08 100644 --- a/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S 0.2 nozzle.json @@ -11,6 +11,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S.json b/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S.json index c6731a7178..33bcdcb417 100644 --- a/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S.json +++ b/resources/profiles/BBL/process/0.08mm High Quality @BBL P2S.json @@ -10,6 +10,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.10mm Standard @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/process/0.10mm Standard @BBL P2S 0.2 nozzle.json index 12c99abbeb..8d545a01f4 100644 --- a/resources/profiles/BBL/process/0.10mm Standard @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/process/0.10mm Standard @BBL P2S 0.2 nozzle.json @@ -10,6 +10,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL P2S 0.2 nozzle.json index caeefe5f36..e1b48ac5b8 100644 --- a/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL P2S 0.2 nozzle.json @@ -10,6 +10,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.12mm High Quality @BBL P2S.json b/resources/profiles/BBL/process/0.12mm High Quality @BBL P2S.json index 547fe83248..d1464e4305 100644 --- a/resources/profiles/BBL/process/0.12mm High Quality @BBL P2S.json +++ b/resources/profiles/BBL/process/0.12mm High Quality @BBL P2S.json @@ -10,6 +10,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.16mm High Quality @BBL P2S.json b/resources/profiles/BBL/process/0.16mm High Quality @BBL P2S.json index 3c76d25250..e8c99baf95 100644 --- a/resources/profiles/BBL/process/0.16mm High Quality @BBL P2S.json +++ b/resources/profiles/BBL/process/0.16mm High Quality @BBL P2S.json @@ -11,6 +11,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.16mm Standard @BBL P2S.json b/resources/profiles/BBL/process/0.16mm Standard @BBL P2S.json index 840c7fc2fe..3936f388e6 100644 --- a/resources/profiles/BBL/process/0.16mm Standard @BBL P2S.json +++ b/resources/profiles/BBL/process/0.16mm Standard @BBL P2S.json @@ -11,6 +11,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL P2S 0.6 nozzle.json index f5839097a1..1357450ea1 100644 --- a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL P2S 0.6 nozzle.json @@ -11,6 +11,7 @@ "30", "30" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.20mm High Quality @BBL P2S.json b/resources/profiles/BBL/process/0.20mm High Quality @BBL P2S.json index 952481c1cd..fc29792372 100644 --- a/resources/profiles/BBL/process/0.20mm High Quality @BBL P2S.json +++ b/resources/profiles/BBL/process/0.20mm High Quality @BBL P2S.json @@ -11,6 +11,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "4000", "4000" diff --git a/resources/profiles/BBL/process/0.20mm Standard @BBL P2S.json b/resources/profiles/BBL/process/0.20mm Standard @BBL P2S.json index e2509d6a9f..2c4de0d7bc 100644 --- a/resources/profiles/BBL/process/0.20mm Standard @BBL P2S.json +++ b/resources/profiles/BBL/process/0.20mm Standard @BBL P2S.json @@ -11,6 +11,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.6 nozzle.json index 07970aba83..7b7f633040 100644 --- a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.6 nozzle.json @@ -11,6 +11,7 @@ "30", "30" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.8 nozzle.json index 5cad977499..4a303b27d9 100644 --- a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL P2S 0.8 nozzle.json @@ -11,6 +11,7 @@ "30", "30" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.24mm Standard @BBL P2S.json b/resources/profiles/BBL/process/0.24mm Standard @BBL P2S.json index db7ea35de0..a6dae0a6dd 100644 --- a/resources/profiles/BBL/process/0.24mm Standard @BBL P2S.json +++ b/resources/profiles/BBL/process/0.24mm Standard @BBL P2S.json @@ -10,6 +10,7 @@ "50", "50" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.30mm Standard @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/process/0.30mm Standard @BBL P2S 0.6 nozzle.json index c3b576306a..9f4c86e17a 100644 --- a/resources/profiles/BBL/process/0.30mm Standard @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.30mm Standard @BBL P2S 0.6 nozzle.json @@ -11,6 +11,7 @@ "30", "30" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL P2S 0.8 nozzle.json index bb8ac922c0..ffa69df36b 100644 --- a/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL P2S 0.8 nozzle.json @@ -11,6 +11,7 @@ "30", "30" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/BBL/process/0.40mm Standard @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/process/0.40mm Standard @BBL P2S 0.8 nozzle.json index 22c58ba46e..e1fe009797 100644 --- a/resources/profiles/BBL/process/0.40mm Standard @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/process/0.40mm Standard @BBL P2S 0.8 nozzle.json @@ -11,6 +11,7 @@ "30", "30" ], + "enable_arc_fitting": "0", "default_acceleration": [ "10000", "10000" diff --git a/resources/profiles/Creality.json b/resources/profiles/Creality.json index 2616d6696c..b95688e15d 100644 --- a/resources/profiles/Creality.json +++ b/resources/profiles/Creality.json @@ -1,6 +1,6 @@ { "name": "Creality", - "version": "02.03.02.70", + "version": "02.03.02.71", "force_update": "0", "description": "Creality configurations", "machine_model_list": [ diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.2 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.2 nozzle.json index 2d55ee3dcf..44754ead86 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.2 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.2 nozzle.json @@ -5,6 +5,7 @@ "from": "system", "setting_id": "GM001", "instantiation": "true", + "printer_variant": "0.2", "printer_settings_id": "Creality", "printer_model": "Creality Ender-3 V3 KE", "gcode_flavor": "klipper", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.4 nozzle.json index 5052015ad0..8d1269dc4a 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.4 nozzle.json @@ -5,6 +5,7 @@ "from": "system", "setting_id": "GM001", "instantiation": "true", + "printer_variant": "0.4", "printer_settings_id": "Creality", "printer_model": "Creality Ender-3 V3 KE", "gcode_flavor": "klipper", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.6 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.6 nozzle.json index 5a26353c84..36e61d6229 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.6 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.6 nozzle.json @@ -5,6 +5,7 @@ "from": "system", "setting_id": "GM001", "instantiation": "true", + "printer_variant": "0.6", "printer_settings_id": "Creality", "printer_model": "Creality Ender-3 V3 KE", "gcode_flavor": "klipper", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.8 nozzle.json index 4f1ca62247..863d20c3fb 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 KE 0.8 nozzle.json @@ -5,6 +5,7 @@ "from": "system", "setting_id": "GM001", "instantiation": "true", + "printer_variant": "0.8", "printer_settings_id": "Creality", "printer_model": "Creality Ender-3 V3 KE", "gcode_flavor": "klipper", diff --git a/resources/profiles/LH.json b/resources/profiles/LH.json new file mode 100644 index 0000000000..32df35a0cf --- /dev/null +++ b/resources/profiles/LH.json @@ -0,0 +1,159 @@ +{ + "name": "LH", + "url": "https://github.com/lhndo/LH-Stinger", + "version": "01.00.00.00", + "force_update": "0", + "description": "LH 3D Printer Configuration", + "machine_model_list": [ + { + "name": "LH Stinger", + "sub_path": "machine/LH Stinger.json" + }, + { + "name": "LH Stinger MMU", + "sub_path": "machine/LH Stinger MMU.json" + } + ], + "process_list": [ + { + "name": "fdm_process_common", + "sub_path": "process/fdm_process_common.json" + }, + { + "name": "fdm_process_lh_common", + "sub_path": "process/fdm_process_lh_common.json" + }, + { + "name": "0.20mm Daily @LH Stinger", + "sub_path": "process/0.20mm Daily @LH Stinger.json" + }, + { + "name": "0.25mm Vase Mode @LH Stinger", + "sub_path": "process/0.25mm Vase Mode @LH Stinger.json" + }, + { + "name": "0.20mm TPU @LH Stinger", + "sub_path": "process/0.20mm TPU @LH Stinger.json" + }, + { + "name": "0.20mm Strength @LH Stinger", + "sub_path": "process/0.20mm Strength @LH Stinger.json" + }, + { + "name": "0.20mm Speed @LH Stinger", + "sub_path": "process/0.20mm Speed @LH Stinger.json" + }, + { + "name": "0.20mm Solid @LH Stinger", + "sub_path": "process/0.20mm Solid @LH Stinger.json" + }, + { + "name": "0.20mm Quiet @LH Stinger", + "sub_path": "process/0.20mm Quiet @LH Stinger.json" + }, + { + "name": "0.20mm PETG @LH Stinger", + "sub_path": "process/0.20mm PETG @LH Stinger.json" + }, + { + "name": "0.20mm MMU @LH Stinger", + "sub_path": "process/0.20mm MMU @LH Stinger.json" + }, + { + "name": "0.10mm HueForge @LH Stinger", + "sub_path": "process/0.10mm HueForge @LH Stinger.json" + }, + { + "name": "0.14mm Detail Strength @LH Stinger", + "sub_path": "process/0.14mm Detail Strength @LH Stinger.json" + }, + { + "name": "0.14mm Detail @LH Stinger", + "sub_path": "process/0.14mm Detail @LH Stinger.json" + } + ], + "filament_list": [ + { + "name": "fdm_filament_common", + "sub_path": "filament/fdm_filament_common.json" + }, + { + "name": "fdm_filament_abs", + "sub_path": "filament/fdm_filament_abs.json" + }, + { + "name": "fdm_filament_asa", + "sub_path": "filament/fdm_filament_asa.json" + }, + { + "name": "fdm_filament_pc", + "sub_path": "filament/fdm_filament_pc.json" + }, + { + "name": "fdm_filament_pet", + "sub_path": "filament/fdm_filament_pet.json" + }, + { + "name": "fdm_filament_pla", + "sub_path": "filament/fdm_filament_pla.json" + }, + { + "name": "fdm_filament_tpu", + "sub_path": "filament/fdm_filament_tpu.json" + }, + { + "name": "LHS ASA", + "sub_path": "filament/LHS ASA.json" + }, + { + "name": "LHS ABS", + "sub_path": "filament/LHS ABS.json" + }, + { + "name": "LHS TPU", + "sub_path": "filament/LHS TPU.json" + }, + { + "name": "LHS PLA", + "sub_path": "filament/LHS PLA.json" + }, + { + "name": "LHS TPU Foamy 78A", + "sub_path": "filament/LHS TPU Foamy 78A.json" + }, + { + "name": "LHS PETG", + "sub_path": "filament/LHS PETG.json" + }, + { + "name": "LHS PCTG", + "sub_path": "filament/LHS PCTG.json" + }, + { + "name": "LHS PC CF", + "sub_path": "filament/LHS PC CF.json" + } + ], + "machine_list": [ + { + "name": "fdm_machine_common", + "sub_path": "machine/fdm_machine_common.json" + }, + { + "name": "fdm_lh_common", + "sub_path": "machine/fdm_lh_common.json" + }, + { + "name": "fdm_lh_mmu_common", + "sub_path": "machine/fdm_lh_mmu_common.json" + }, + { + "name": "LH Stinger 0.4 nozzle", + "sub_path": "machine/LH Stinger 0.4 nozzle.json" + }, + { + "name": "LH Stinger MMU 0.4 nozzle", + "sub_path": "machine/LH Stinger MMU 0.4 nozzle.json" + } + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/LH Stinger MMU_cover.png b/resources/profiles/LH/LH Stinger MMU_cover.png new file mode 100644 index 0000000000..ef0ed9c9e4 Binary files /dev/null and b/resources/profiles/LH/LH Stinger MMU_cover.png differ diff --git a/resources/profiles/LH/LH Stinger_cover.png b/resources/profiles/LH/LH Stinger_cover.png new file mode 100644 index 0000000000..09070257b9 Binary files /dev/null and b/resources/profiles/LH/LH Stinger_cover.png differ diff --git a/resources/profiles/LH/LH_Stinger_MMU_buildplate_texture.png b/resources/profiles/LH/LH_Stinger_MMU_buildplate_texture.png new file mode 100644 index 0000000000..d21afe069e Binary files /dev/null and b/resources/profiles/LH/LH_Stinger_MMU_buildplate_texture.png differ diff --git a/resources/profiles/LH/LH_Stinger_buildplate_model.stl b/resources/profiles/LH/LH_Stinger_buildplate_model.stl new file mode 100644 index 0000000000..37fd514014 Binary files /dev/null and b/resources/profiles/LH/LH_Stinger_buildplate_model.stl differ diff --git a/resources/profiles/LH/LH_Stinger_buildplate_texture.png b/resources/profiles/LH/LH_Stinger_buildplate_texture.png new file mode 100644 index 0000000000..e03843bd23 Binary files /dev/null and b/resources/profiles/LH/LH_Stinger_buildplate_texture.png differ diff --git a/resources/profiles/LH/filament/LHS ABS.json b/resources/profiles/LH/filament/LHS ABS.json new file mode 100644 index 0000000000..95cd7ccd73 --- /dev/null +++ b/resources/profiles/LH/filament/LHS ABS.json @@ -0,0 +1,355 @@ +{ + "name": "LHS ABS", + "type": "filament", + "filament_id": "LHF_abs", + "setting_id": "LHF_S_abs", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_asa", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "2" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "100" + ], + "eng_plate_temp_initial_layer": [ + "105" + ], + "fan_cooling_layer_time": [ + "25" + ], + "fan_max_speed": [ + "25" + ], + "fan_min_speed": [ + "25" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.04" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.926" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "45" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_settings_id": [ + "LHS - ASA" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.07 FILAMENT_HEAT_CAPACITY=2.1\nMAX_FAN LINK_AUX=0" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "ASA" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "4" + ], + "hot_plate_temp": [ + "105" + ], + "hot_plate_temp_initial_layer": [ + "105" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "-1" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "260" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "overhang_fan_speed": [ + "50" + ], + "overhang_fan_threshold": [ + "50%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.019" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "15" + ], + "slow_down_min_speed": [ + "10" + ], + "supertack_plate_temp": [ + "0" + ], + "supertack_plate_temp_initial_layer": [ + "0" + ], + "support_material_interface_fan_speed": [ + "-1" + ], + "temperature_vitrification": [ + "110" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "100" + ], + "textured_plate_temp_initial_layer": [ + "105" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS ASA.json b/resources/profiles/LH/filament/LHS ASA.json new file mode 100644 index 0000000000..9c8ed46093 --- /dev/null +++ b/resources/profiles/LH/filament/LHS ASA.json @@ -0,0 +1,352 @@ +{ + "name": "LHS ASA", + "filament_id": "LHF_asa", + "setting_id": "LHF_S_asa", + "type": "filament", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_asa", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "2" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "100" + ], + "eng_plate_temp_initial_layer": [ + "105" + ], + "fan_cooling_layer_time": [ + "25" + ], + "fan_max_speed": [ + "25" + ], + "fan_min_speed": [ + "25" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.04" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.926" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "45" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.07 FILAMENT_HEAT_CAPACITY=2.1\nMAX_FAN LINK_AUX=0" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "ASA" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "4" + ], + "hot_plate_temp": [ + "105" + ], + "hot_plate_temp_initial_layer": [ + "105" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "-1" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "260" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "overhang_fan_speed": [ + "50" + ], + "overhang_fan_threshold": [ + "50%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.019" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "15" + ], + "slow_down_min_speed": [ + "10" + ], + "supertack_plate_temp": [ + "0" + ], + "supertack_plate_temp_initial_layer": [ + "0" + ], + "support_material_interface_fan_speed": [ + "-1" + ], + "temperature_vitrification": [ + "110" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "100" + ], + "textured_plate_temp_initial_layer": [ + "105" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS PC CF.json b/resources/profiles/LH/filament/LHS PC CF.json new file mode 100644 index 0000000000..ec749abf64 --- /dev/null +++ b/resources/profiles/LH/filament/LHS PC CF.json @@ -0,0 +1,122 @@ +{ + "name": "LHS PC CF", + "type": "filament", + "filament_id": "LHF_pccf", + "setting_id": "LHF_S_pccf", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_pla", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "additional_cooling_fan_speed": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "4" + ], + "enable_pressure_advance": [ + "1" + ], + "fan_cooling_layer_time": [ + "11" + ], + "fan_max_speed": [ + "5" + ], + "fan_min_speed": [ + "5" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_density": [ + "1.18" + ], + "filament_flow_ratio": [ + "0.945" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_max_volumetric_speed": [ + "35" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "Extrusion Override set to a higher value\nAux disabled\nZ-Offset increased to 0.025 due to nozzle expansion at 300C" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_shrink": [ + "99.8%" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.36 FILAMENT_HEAT_CAPACITY=2.6\nMAX_FAN LINK_AUX=0" + ], + "filament_type": [ + "PC" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "hot_plate_temp": [ + "105" + ], + "hot_plate_temp_initial_layer": [ + "105" + ], + "is_custom_defined": "0", + "nozzle_temperature": [ + "300" + ], + "nozzle_temperature_initial_layer": [ + "300" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "270" + ], + "overhang_fan_speed": [ + "35" + ], + "pressure_advance": [ + "0.025" + ], + "slow_down_layer_time": [ + "7" + ], + "slow_down_min_speed": [ + "12" + ], + "filament_vendor": [ + "LH Stinger" + ], + "temperature_vitrification": [ + "140" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS PCTG.json b/resources/profiles/LH/filament/LHS PCTG.json new file mode 100644 index 0000000000..7508a1fbd3 --- /dev/null +++ b/resources/profiles/LH/filament/LHS PCTG.json @@ -0,0 +1,352 @@ +{ + "name": "LHS PCTG", + "type": "filament", + "filament_id": "LHF_pctg", + "setting_id": "LHF_S_pctg", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_pla", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "35" + ], + "cool_plate_temp_initial_layer": [ + "35" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "0" + ], + "fan_cooling_layer_time": [ + "13" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.24" + ], + "filament_deretraction_speed": [ + "25" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.953" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "25" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "10" + ], + "filament_multitool_ramming_volume": [ + "10" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "0.6" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "30" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.25 FILAMENT_HEAT_CAPACITY=5.5\nMAX_FAN LINK_AUX=0" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "PCTG" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "0" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "3" + ], + "hot_plate_temp": [ + "90" + ], + "hot_plate_temp_initial_layer": [ + "85" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "30" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "280" + ], + "nozzle_temperature_initial_layer": [ + "270" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "50" + ], + "overhang_fan_threshold": [ + "50%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.038" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "15" + ], + "supertack_plate_temp": [ + "45" + ], + "supertack_plate_temp_initial_layer": [ + "45" + ], + "support_material_interface_fan_speed": [ + "50" + ], + "temperature_vitrification": [ + "80" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "55" + ], + "textured_plate_temp_initial_layer": [ + "55" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS PETG.json b/resources/profiles/LH/filament/LHS PETG.json new file mode 100644 index 0000000000..4c50c13b4c --- /dev/null +++ b/resources/profiles/LH/filament/LHS PETG.json @@ -0,0 +1,352 @@ +{ + "name": "LHS PETG", + "type": "filament", + "filament_id": "LHF_petg", + "setting_id": "LHF_S_petg", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_pla", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "35" + ], + "cool_plate_temp_initial_layer": [ + "35" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "0" + ], + "fan_cooling_layer_time": [ + "15" + ], + "fan_max_speed": [ + "65" + ], + "fan_min_speed": [ + "35" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.24" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.923" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "27" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "0.6" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.27 FILAMENT_HEAT_CAPACITY=5.5\nMAX_FAN LINK_AUX=0" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "PETG" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "3" + ], + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "50" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "260" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "50%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.047" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "14" + ], + "slow_down_min_speed": [ + "15" + ], + "supertack_plate_temp": [ + "45" + ], + "supertack_plate_temp_initial_layer": [ + "45" + ], + "support_material_interface_fan_speed": [ + "80" + ], + "temperature_vitrification": [ + "80" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "55" + ], + "textured_plate_temp_initial_layer": [ + "55" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS PLA.json b/resources/profiles/LH/filament/LHS PLA.json new file mode 100644 index 0000000000..6e927484a8 --- /dev/null +++ b/resources/profiles/LH/filament/LHS PLA.json @@ -0,0 +1,352 @@ +{ + "name": "LHS PLA", + "type": "filament", + "filament_id": "LHF_pla", + "setting_id": "LHF_S_pla", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_pla", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "70" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "35" + ], + "cool_plate_temp_initial_layer": [ + "35" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "0" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "65" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.24" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "45" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.24 FILAMENT_HEAT_CAPACITY=3.2\n; MAX_FAN LINK_AUX=0" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "PLA" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "0" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "-1" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "235" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "nozzle_temperature_range_low": [ + "190" + ], + "overhang_fan_speed": [ + "100" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.02" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "8" + ], + "slow_down_min_speed": [ + "15" + ], + "supertack_plate_temp": [ + "45" + ], + "supertack_plate_temp_initial_layer": [ + "45" + ], + "support_material_interface_fan_speed": [ + "100" + ], + "temperature_vitrification": [ + "45" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "55" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS TPU Foamy 78A.json b/resources/profiles/LH/filament/LHS TPU Foamy 78A.json new file mode 100644 index 0000000000..cb706c46de --- /dev/null +++ b/resources/profiles/LH/filament/LHS TPU Foamy 78A.json @@ -0,0 +1,352 @@ +{ + "name": "LHS TPU Foamy 78A", + "type": "filament", + "filament_id": "LHF_ftpuf", + "setting_id": "LHF_S_ftpuf", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_tpu", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "55" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "30" + ], + "cool_plate_temp_initial_layer": [ + "30" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "30" + ], + "eng_plate_temp_initial_layer": [ + "30" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "60" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.02" + ], + "filament_deretraction_speed": [ + "20" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.85" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "4" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_retraction_minimum_travel": [ + "1" + ], + "filament_retraction_speed": [ + "30" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.02 FILAMENT_HEAT_CAPACITY=2\n; MAX_FAN LINK_AUX=0 \nSET_PRESSURE_ADVANCE EXTRUDER=extruder SMOOTH_TIME=0.04" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "TPU" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "0" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "0" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "0" + ], + "hot_plate_temp": [ + "25" + ], + "hot_plate_temp_initial_layer": [ + "25" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "-1" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "265" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "overhang_fan_speed": [ + "70" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.06" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "5" + ], + "slow_down_min_speed": [ + "20" + ], + "supertack_plate_temp": [ + "0" + ], + "supertack_plate_temp_initial_layer": [ + "0" + ], + "support_material_interface_fan_speed": [ + "100" + ], + "temperature_vitrification": [ + "30" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "35" + ], + "textured_plate_temp_initial_layer": [ + "35" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/LHS TPU.json b/resources/profiles/LH/filament/LHS TPU.json new file mode 100644 index 0000000000..463cd29b2b --- /dev/null +++ b/resources/profiles/LH/filament/LHS TPU.json @@ -0,0 +1,352 @@ +{ + "name": "LHS TPU", + "type": "filament", + "filament_id": "LHF_ptpu_pl", + "setting_id": "LHF_S_ptpu_pl", + "from": "system", + "instantiation": "true", + "inherits": "fdm_filament_tpu", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "adaptive_pressure_advance": [ + "0" + ], + "adaptive_pressure_advance_bridges": [ + "0" + ], + "adaptive_pressure_advance_model": [ + "0,0,0\n0,0,0" + ], + "adaptive_pressure_advance_overhangs": [ + "0" + ], + "additional_cooling_fan_speed": [ + "55" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "30" + ], + "cool_plate_temp_initial_layer": [ + "30" + ], + "default_filament_colour": [ + "" + ], + "dont_slow_down_outer_wall": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "1" + ], + "eng_plate_temp": [ + "30" + ], + "eng_plate_temp_initial_layer": [ + "30" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "60" + ], + "filament_adaptive_volumetric_speed": [ + "0" + ], + "filament_adhesiveness_category": [ + "0" + ], + "filament_change_length": [ + "10" + ], + "filament_cooling_final_speed": [ + "0" + ], + "filament_cooling_initial_speed": [ + "0" + ], + "filament_cooling_moves": [ + "0" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "20" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode\n" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_flow_ratio": [ + "0.965" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0" + ], + "filament_ironing_flow": [ + "nil" + ], + "filament_ironing_inset": [ + "nil" + ], + "filament_ironing_spacing": [ + "nil" + ], + "filament_ironing_speed": [ + "nil" + ], + "filament_is_support": [ + "0" + ], + "filament_loading_speed": [ + "0" + ], + "filament_loading_speed_start": [ + "0" + ], + "filament_long_retractions_when_cut": [ + "nil" + ], + "filament_max_volumetric_speed": [ + "20" + ], + "filament_minimal_purge_on_wipe_tower": [ + "0" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "0" + ], + "filament_multitool_ramming_volume": [ + "0" + ], + "filament_notes": [ + "" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "Bottom Only" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil" + ], + "filament_retraction_length": [ + "0.9" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "35" + ], + "filament_shrink": [ + "100%" + ], + "filament_shrinkage_compensation_z": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_stamping_distance": [ + "0" + ], + "filament_stamping_loading_speed": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n; MPC_SET HEATER=extruder FILAMENT_DENSITY=1.22 FILAMENT_HEAT_CAPACITY=2\n; MAX_FAN LINK_AUX=0\nSET_PRESSURE_ADVANCE EXTRUDER=extruder SMOOTH_TIME=0.04" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_type": [ + "TPU" + ], + "filament_unloading_speed": [ + "0" + ], + "filament_unloading_speed_start": [ + "0" + ], + "filament_wipe": [ + "0" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "0" + ], + "hot_plate_temp": [ + "30" + ], + "hot_plate_temp_initial_layer": [ + "30" + ], + "idle_temperature": [ + "0" + ], + "internal_bridge_fan_speed": [ + "-1" + ], + "ironing_fan_speed": [ + "-1" + ], + "long_retractions_when_ec": [ + "0" + ], + "nozzle_temperature": [ + "245" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "overhang_fan_speed": [ + "100" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pellet_flow_coefficient": [ + "0.4157" + ], + "pressure_advance": [ + "0.08" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "12" + ], + "supertack_plate_temp": [ + "0" + ], + "supertack_plate_temp_initial_layer": [ + "0" + ], + "support_material_interface_fan_speed": [ + "100" + ], + "temperature_vitrification": [ + "30" + ], + "textured_cool_plate_temp": [ + "40" + ], + "textured_cool_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "35" + ], + "textured_plate_temp_initial_layer": [ + "35" + ], + "filament_vendor": [ + "LH Stinger" + ], + "volumetric_speed_coefficients": [ + "" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_abs.json b/resources/profiles/LH/filament/fdm_filament_abs.json new file mode 100644 index 0000000000..8be5c8c2f2 --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_abs.json @@ -0,0 +1,88 @@ +{ + "type": "filament", + "name": "fdm_filament_abs", + "inherits": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "105" + ], + "eng_plate_temp": [ + "105" + ], + "hot_plate_temp": [ + "105" + ], + "textured_plate_temp": [ + "105" + ], + "cool_plate_temp_initial_layer": [ + "105" + ], + "eng_plate_temp_initial_layer": [ + "105" + ], + "hot_plate_temp_initial_layer": [ + "105" + ], + "textured_plate_temp_initial_layer": [ + "105" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "filament_max_volumetric_speed": [ + "28.6" + ], + "filament_type": [ + "ABS" + ], + "filament_density": [ + "1.04" + ], + "filament_cost": [ + "20" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "10" + ], + "overhang_fan_threshold": [ + "25%" + ], + "overhang_fan_speed": [ + "80" + ], + "nozzle_temperature": [ + "260" + ], + "temperature_vitrification": [ + "110" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "3" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_asa.json b/resources/profiles/LH/filament/fdm_filament_asa.json new file mode 100644 index 0000000000..19cfa6b520 --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_asa.json @@ -0,0 +1,88 @@ +{ + "type": "filament", + "name": "fdm_filament_asa", + "inherits": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "105" + ], + "eng_plate_temp": [ + "105" + ], + "hot_plate_temp": [ + "105" + ], + "textured_plate_temp": [ + "105" + ], + "cool_plate_temp_initial_layer": [ + "105" + ], + "eng_plate_temp_initial_layer": [ + "105" + ], + "hot_plate_temp_initial_layer": [ + "105" + ], + "textured_plate_temp_initial_layer": [ + "105" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "35" + ], + "filament_max_volumetric_speed": [ + "28.6" + ], + "filament_type": [ + "ASA" + ], + "filament_density": [ + "1.04" + ], + "filament_cost": [ + "20" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "10" + ], + "overhang_fan_threshold": [ + "25%" + ], + "overhang_fan_speed": [ + "80" + ], + "nozzle_temperature": [ + "260" + ], + "temperature_vitrification": [ + "110" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "3" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_common.json b/resources/profiles/LH/filament/fdm_filament_common.json new file mode 100644 index 0000000000..788382bc9e --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_common.json @@ -0,0 +1,141 @@ +{ + "type": "filament", + "name": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "60" + ], + "eng_plate_temp": [ + "60" + ], + "hot_plate_temp": [ + "60" + ], + "textured_plate_temp": [ + "60" + ], + "cool_plate_temp_initial_layer": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "overhang_fan_threshold": [ + "95%" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "1" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "fan_cooling_layer_time": [ + "60" + ], + "filament_cost": [ + "0" + ], + "filament_density": [ + "0" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_max_volumetric_speed": [ + "0" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_settings_id": [ + "" + ], + "filament_soluble": [ + "0" + ], + "filament_type": [ + "PLA" + ], + "filament_vendor": [ + "Generic" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "bed_type": [ + "Cool Plate" + ], + "nozzle_temperature_initial_layer": [ + "200" + ], + "full_fan_speed_layer": [ + "0" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "35" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "8" + ], + "filament_start_gcode": [ + "; Filament gcode\n" + ], + "nozzle_temperature": [ + "200" + ], + "temperature_vitrification": [ + "100" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_pc.json b/resources/profiles/LH/filament/fdm_filament_pc.json new file mode 100644 index 0000000000..25d83913f7 --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_pc.json @@ -0,0 +1,88 @@ +{ + "type": "filament", + "name": "fdm_filament_pc", + "inherits": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "0" + ], + "eng_plate_temp": [ + "110" + ], + "hot_plate_temp": [ + "110" + ], + "textured_plate_temp": [ + "110" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "textured_plate_temp_initial_layer": [ + "110" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "filament_max_volumetric_speed": [ + "23.2" + ], + "filament_type": [ + "PC" + ], + "filament_density": [ + "1.04" + ], + "filament_cost": [ + "20" + ], + "nozzle_temperature_initial_layer": [ + "270" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "10" + ], + "overhang_fan_threshold": [ + "25%" + ], + "overhang_fan_speed": [ + "60" + ], + "nozzle_temperature": [ + "280" + ], + "temperature_vitrification": [ + "140" + ], + "nozzle_temperature_range_low": [ + "260" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "2" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_pet.json b/resources/profiles/LH/filament/fdm_filament_pet.json new file mode 100644 index 0000000000..75210fc454 --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_pet.json @@ -0,0 +1,82 @@ +{ + "type": "filament", + "name": "fdm_filament_pet", + "inherits": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "60" + ], + "eng_plate_temp": [ + "0" + ], + "hot_plate_temp": [ + "80" + ], + "textured_plate_temp": [ + "80" + ], + "cool_plate_temp_initial_layer": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "0" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "textured_plate_temp_initial_layer": [ + "80" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "20" + ], + "filament_max_volumetric_speed": [ + "25" + ], + "filament_type": [ + "PETG" + ], + "filament_density": [ + "1.27" + ], + "filament_cost": [ + "30" + ], + "nozzle_temperature_initial_layer": [ + "255" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "20" + ], + "overhang_fan_speed": [ + "100" + ], + "nozzle_temperature": [ + "255" + ], + "temperature_vitrification": [ + "80" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "nozzle_temperature_range_high": [ + "260" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_pla.json b/resources/profiles/LH/filament/fdm_filament_pla.json new file mode 100644 index 0000000000..562adb381a --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_pla.json @@ -0,0 +1,94 @@ +{ + "type": "filament", + "name": "fdm_filament_pla", + "inherits": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "fan_cooling_layer_time": [ + "100" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_type": [ + "PLA" + ], + "filament_density": [ + "1.24" + ], + "filament_cost": [ + "20" + ], + "cool_plate_temp": [ + "60" + ], + "eng_plate_temp": [ + "60" + ], + "hot_plate_temp": [ + "60" + ], + "textured_plate_temp": [ + "60" + ], + "cool_plate_temp_initial_layer": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "overhang_fan_speed": [ + "100" + ], + "overhang_fan_threshold": [ + "50%" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "nozzle_temperature": [ + "220" + ], + "temperature_vitrification": [ + "60" + ], + "nozzle_temperature_range_low": [ + "190" + ], + "nozzle_temperature_range_high": [ + "230" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "4" + ], + "additional_cooling_fan_speed": [ + "70" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/filament/fdm_filament_tpu.json b/resources/profiles/LH/filament/fdm_filament_tpu.json new file mode 100644 index 0000000000..fdd29ca2a0 --- /dev/null +++ b/resources/profiles/LH/filament/fdm_filament_tpu.json @@ -0,0 +1,88 @@ +{ + "type": "filament", + "name": "fdm_filament_tpu", + "inherits": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "30" + ], + "eng_plate_temp": [ + "30" + ], + "hot_plate_temp": [ + "35" + ], + "textured_plate_temp": [ + "35" + ], + "cool_plate_temp_initial_layer": [ + "30" + ], + "eng_plate_temp_initial_layer": [ + "30" + ], + "hot_plate_temp_initial_layer": [ + "35" + ], + "textured_plate_temp_initial_layer": [ + "35" + ], + "fan_cooling_layer_time": [ + "100" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_type": [ + "TPU" + ], + "filament_density": [ + "1.24" + ], + "filament_cost": [ + "20" + ], + "filament_retraction_length": [ + "0.4" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "overhang_fan_speed": [ + "100" + ], + "additional_cooling_fan_speed": [ + "70" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "nozzle_temperature": [ + "240" + ], + "temperature_vitrification": [ + "60" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/LH Stinger 0.4 nozzle.json b/resources/profiles/LH/machine/LH Stinger 0.4 nozzle.json new file mode 100644 index 0000000000..974b81d5fe --- /dev/null +++ b/resources/profiles/LH/machine/LH Stinger 0.4 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "machine", + "name": "LH Stinger 0.4 nozzle", + "inherits": "fdm_lh_common", + "from": "system", + "setting_id": "LHS_m01_04", + "instantiation": "true", + "printer_model": "LH Stinger", + "nozzle_diameter": [ + "0.4" + ], + "default_filament_profile": [ + "LHS PLA" + ], + "printer_variant": "0.4" +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/LH Stinger MMU 0.4 nozzle.json b/resources/profiles/LH/machine/LH Stinger MMU 0.4 nozzle.json new file mode 100644 index 0000000000..3c8b400b87 --- /dev/null +++ b/resources/profiles/LH/machine/LH Stinger MMU 0.4 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "machine", + "name": "LH Stinger MMU 0.4 nozzle", + "inherits": "fdm_lh_mmu_common", + "from": "system", + "setting_id": "LHS_m01_mmu_04", + "instantiation": "true", + "printer_model": "LH Stinger MMU", + "nozzle_diameter": [ + "0.4" + ], + "default_filament_profile": [ + "LHS PLA" + ], + "printer_variant": "0.4" +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/LH Stinger MMU.json b/resources/profiles/LH/machine/LH Stinger MMU.json new file mode 100644 index 0000000000..dd0a1201c6 --- /dev/null +++ b/resources/profiles/LH/machine/LH Stinger MMU.json @@ -0,0 +1,12 @@ +{ + "type": "machine_model", + "name": "LH Stinger MMU", + "model_id": "LHS_M_mmu", + "nozzle_diameter": "0.4", + "machine_tech": "FFF", + "family": "LH", + "bed_model": "LH_Stinger_buildplate_model.STL", + "bed_texture": "LH_Stinger_MMU_buildplate_texture.png", + "hotend_model": "", + "default_materials": "LHS PLA;LHS PETG;LHS PCTG;LHS ASA;LHS ABS;LHS PC CF;LHS TPU Foamy 78A;LHS TPU;" +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/LH Stinger.json b/resources/profiles/LH/machine/LH Stinger.json new file mode 100644 index 0000000000..1e29493210 --- /dev/null +++ b/resources/profiles/LH/machine/LH Stinger.json @@ -0,0 +1,12 @@ +{ + "type": "machine_model", + "name": "LH Stinger", + "model_id": "LHS_M_base", + "nozzle_diameter": "0.4", + "machine_tech": "FFF", + "family": "LH", + "bed_model": "LH_Stinger_buildplate_model.STL", + "bed_texture": "LH_Stinger_buildplate_texture.png", + "hotend_model": "", + "default_materials": "LHS PLA;LHS PETG;LHS PCTG;LHS ASA;LHS ABS;LHS PC CF;LHS TPU Foamy 78A;LHS TPU;" +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/fdm_lh_common.json b/resources/profiles/LH/machine/fdm_lh_common.json new file mode 100644 index 0000000000..277e0762eb --- /dev/null +++ b/resources/profiles/LH/machine/fdm_lh_common.json @@ -0,0 +1,157 @@ +{ + "type": "machine", + "name": "fdm_lh_common", + "inherits": "fdm_machine_common", + "from": "system", + "instantiation": "false", + "gcode_flavor": "klipper", + "machine_max_acceleration_e": [ + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "200000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "200000", + "5000" + ], + "machine_max_acceleration_travel": [ + "20000", + "20000" + ], + "machine_max_acceleration_x": [ + "200000", + "20000" + ], + "machine_max_acceleration_y": [ + "200000", + "20000" + ], + "machine_max_acceleration_z": [ + "2000", + "200" + ], + "machine_max_speed_e": [ + "200", + "25" + ], + "machine_max_speed_x": [ + "1000", + "200" + ], + "machine_max_speed_y": [ + "1000", + "200" + ], + "machine_max_speed_z": [ + "100", + "12" + ], + "machine_max_jerk_e": [ + "15", + "2.5" + ], + "machine_max_jerk_x": [ + "15", + "9" + ], + "machine_max_jerk_y": [ + "15", + "9" + ], + "machine_max_jerk_z": [ + "15", + "0.4" + ], + "machine_min_extruding_rate": [ + "0", + "0" + ], + "machine_min_travel_rate": [ + "0", + "0" + ], + "max_layer_height": [ + "0.32" + ], + "min_layer_height": [ + "0.08" + ], + "printable_area": [ + "18x38", + "218x38", + "218x238", + "18x238" + ], + "printable_height": "180", + "extruder_clearance_radius": "65", + "extruder_clearance_height_to_rod": "36", + "extruder_clearance_height_to_lid": "140", + "printer_settings_id": "", + "printer_technology": "FFF", + "printer_variant": "0.4", + "retraction_minimum_travel": [ + "1" + ], + "retract_before_wipe": [ + "70%" + ], + "retract_when_changing_layer": [ + "1" + ], + "retraction_length": [ + "0.3" + ], + "retract_length_toolchange": [ + "0" + ], + "z_hop": [ + "0.2" + ], + "retract_restart_extra": [ + "0" + ], + "retract_restart_extra_toolchange": [ + "0" + ], + "retraction_speed": [ + "40" + ], + "deretraction_speed": [ + "30" + ], + "retract_lift_enforce": [ + "Top and Bottom" + ], + "z_hop_types": [ + "Auto Lift" + ], + "silent_mode": "0", + "single_extruder_multi_material": "1", + "change_filament_gcode": "", + "manual_filament_change": "1", + "wipe": [ + "1" + ], + "default_filament_profile": [ + "LH Generic PLA" + ], + "enable_filament_ramming": "0", + "default_print_profile": "0.20mm Daily @LH Stinger", + "bed_exclude_area": [ + "0x0" + ], + "machine_start_gcode": "PRINT_START_LHS BED=[bed_temperature_initial_layer_single] HOTEND=[nozzle_temperature_initial_layer] AUTOMESH=1 AUTOPURGE=1 QUIETMODE={if print_preset =~ /.*Quiet.*/ }1{else}0{endif}\n", + "machine_end_gcode": "PRINT_END", + "layer_change_gcode": ";AFTER_LAYER_CHANGES\n;[layer_z]", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", + "machine_pause_gcode": "PAUSE", + "scan_first_layer": "0", + "nozzle_type": [ + "brass" + ], + "bed_temperature_formula": "by_first_filament", + "auxiliary_fan": "1" +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/fdm_lh_mmu_common.json b/resources/profiles/LH/machine/fdm_lh_mmu_common.json new file mode 100644 index 0000000000..4390b0d3fd --- /dev/null +++ b/resources/profiles/LH/machine/fdm_lh_mmu_common.json @@ -0,0 +1,21 @@ +{ + "type": "machine", + "name": "fdm_lh_mmu_common", + "inherits": "fdm_lh_common", + "from": "system", + "instantiation": "false", + "cooling_tube_length": "0", + "cooling_tube_retraction": "0", + "enable_filament_ramming": "0", + "extra_loading_move": "0", + "machine_start_gcode": " _SP_PRINT_START LANE=[initial_tool] TEMP=[nozzle_temperature_initial_layer]\n\nPRINT_START_LHS BED=[bed_temperature_initial_layer_single] HOTEND=[nozzle_temperature_initial_layer] AUTOMESH=1 AUTOPURGE=1 QUIETMODE={if print_preset =~ /.*Quiet.*/ }1{else}0{endif}\n\n", + "change_filament_gcode": " _SP_SET_PURGE PURGE=[first_flush_volume] ", + "layer_change_gcode": ";AFTER_LAYER_CHANGES\n;[layer_z]", + "machine_end_gcode": "PRINT_END\n\n_SP_PRINT_END", + "machine_tool_change_time": "20", + "parking_pos_retraction": "0", + "manual_filament_change": "0", + "retract_length_toolchange": [ + "0" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/machine/fdm_machine_common.json b/resources/profiles/LH/machine/fdm_machine_common.json new file mode 100644 index 0000000000..a46315dc8c --- /dev/null +++ b/resources/profiles/LH/machine/fdm_machine_common.json @@ -0,0 +1,119 @@ +{ + "type": "machine", + "name": "fdm_machine_common", + "from": "system", + "instantiation": "false", + "printer_technology": "FFF", + "deretraction_speed": [ + "40" + ], + "extruder_colour": [ + "#FCE94F" + ], + "extruder_offset": [ + "0x0" + ], + "gcode_flavor": "marlin", + "silent_mode": "0", + "machine_max_acceleration_e": [ + "5000" + ], + "machine_max_acceleration_extruding": [ + "10000" + ], + "machine_max_acceleration_retracting": [ + "1000" + ], + "machine_max_acceleration_x": [ + "10000" + ], + "machine_max_acceleration_y": [ + "10000" + ], + "machine_max_acceleration_z": [ + "500" + ], + "machine_max_speed_e": [ + "60" + ], + "machine_max_speed_x": [ + "500" + ], + "machine_max_speed_y": [ + "500" + ], + "machine_max_speed_z": [ + "10" + ], + "machine_max_jerk_e": [ + "5" + ], + "machine_max_jerk_x": [ + "8" + ], + "machine_max_jerk_y": [ + "8" + ], + "machine_max_jerk_z": [ + "0.4" + ], + "machine_min_extruding_rate": [ + "0" + ], + "machine_min_travel_rate": [ + "0" + ], + "max_layer_height": [ + "0.32" + ], + "min_layer_height": [ + "0.08" + ], + "printable_height": "250", + "extruder_clearance_radius": "65", + "extruder_clearance_height_to_rod": "36", + "extruder_clearance_height_to_lid": "140", + "nozzle_diameter": [ + "0.4" + ], + "printer_settings_id": "", + "printer_variant": "0.4", + "retraction_minimum_travel": [ + "2" + ], + "retract_before_wipe": [ + "70%" + ], + "retract_when_changing_layer": [ + "1" + ], + "retraction_length": [ + "1" + ], + "retract_length_toolchange": [ + "1" + ], + "z_hop": [ + "0" + ], + "retract_restart_extra": [ + "0" + ], + "retract_restart_extra_toolchange": [ + "0" + ], + "retraction_speed": [ + "60" + ], + "single_extruder_multi_material": "1", + "change_filament_gcode": "", + "wipe": [ + "1" + ], + "default_print_profile": "", + "machine_start_gcode": "G0 Z20 F9000\nG92 E0; G1 E-10 F1200\nG28\nM970 Q1 A10 B10 C130 K0\nM970 Q1 A10 B131 C250 K1\nM974 Q1 S1 P0\nM970 Q0 A10 B10 C130 H20 K0\nM970 Q0 A10 B131 C250 K1\nM974 Q0 S1 P0\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nG29 ;Home\nG90;\nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S205;\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder \nG1 X110 Y110 Z2.0 F3000 ;Move Z Axis up", + "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-4.0 F3600; retract \nG91\nG1 Z3;\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nG90 \nG0 X110 Y200 F3600 \nprint_end", + "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", + "machine_pause_gcode": "M601" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.10mm HueForge @LH Stinger.json b/resources/profiles/LH/process/0.10mm HueForge @LH Stinger.json new file mode 100644 index 0000000000..c3a7924bff --- /dev/null +++ b/resources/profiles/LH/process/0.10mm HueForge @LH Stinger.json @@ -0,0 +1,42 @@ +{ + "type": "process", + "name": "0.10mm HueForge @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_hueforge", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "bottom_shell_layers": "999", + "bottom_solid_infill_flow_ratio": "0.98", + "detect_narrow_internal_solid_infill": "0", + "ensure_vertical_shell_thickness": "none", + "initial_layer_acceleration": "1000", + "initial_layer_infill_speed": "150", + "initial_layer_print_height": "0.16", + "initial_layer_speed": "80", + "layer_height": "0.1", + "max_travel_detour_distance": "60", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "reduce_crossing_wall": "1", + "skirt_loops": "1", + "slice_closing_radius": "0.042", + "sparse_infill_density": "0%", + "top_bottom_infill_wall_overlap": "15%", + "top_shell_layers": "0", + "top_solid_infill_flow_ratio": "0.98", + "brim_type": "no_brim", + "wall_generator": "arachne", + "wall_sequence": "inner wall/outer wall", + "reduce_infill_retraction": "1", + "gap_fill_target": "nowhere", + "filter_out_gap_fill": "0.5", + "wall_loops": "1" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.14mm Detail @LH Stinger.json b/resources/profiles/LH/process/0.14mm Detail @LH Stinger.json new file mode 100644 index 0000000000..cad9a16e51 --- /dev/null +++ b/resources/profiles/LH/process/0.14mm Detail @LH Stinger.json @@ -0,0 +1,54 @@ +{ + "type": "process", + "name": "0.14mm Detail @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_detail", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "bottom_shell_layers": "5", + "bridge_flow": "1.2", + "default_jerk": "10", + "enable_support": "1", + "ensure_vertical_shell_thickness": "ensure_moderate", + "filter_out_gap_fill": "10", + "infill_jerk": "10", + "infill_wall_overlap": "10%", + "initial_layer_infill_speed": "90", + "initial_layer_jerk": "10", + "initial_layer_travel_speed": "250", + "inner_wall_jerk": "10", + "internal_bridge_flow": "1.2", + "layer_height": "0.14", + "max_travel_detour_distance": "50", + "outer_wall_jerk": "10", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "reduce_crossing_wall": "1", + "skirt_loops": "2", + "slow_down_layers": "2", + "small_perimeter_speed": "75%", + "small_perimeter_threshold": "3", + "sparse_infill_pattern": "rectilinear", + "sparse_infill_density": "15%", + "support_angle": "45", + "support_base_pattern": "rectilinear", + "support_base_pattern_spacing": "1.5", + "support_bottom_z_distance": "0.15", + "support_style": "organic", + "support_type": "tree(auto)", + "top_shell_layers": "6", + "top_surface_jerk": "10", + "wall_generator": "arachne", + "min_length_factor": "0.5", + "gap_fill_target": "nowhere", + "wall_loops": "3", + "travel_jerk": "10" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.14mm Detail Strength @LH Stinger.json b/resources/profiles/LH/process/0.14mm Detail Strength @LH Stinger.json new file mode 100644 index 0000000000..e473db7707 --- /dev/null +++ b/resources/profiles/LH/process/0.14mm Detail Strength @LH Stinger.json @@ -0,0 +1,67 @@ +{ + "type": "process", + "name": "0.14mm Detail Strength @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_detail_strength", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "bottom_shell_layers": "6", + "bottom_shell_thickness": "0.8", + "bridge_acceleration": "7500", + "bridge_flow": "1.2", + "brim_width": "3", + "default_acceleration": "15000", + "default_jerk": "10", + "gap_infill_speed": "200", + "infill_anchor": "1000", + "infill_anchor_max": "1000", + "infill_jerk": "10", + "initial_layer_infill_speed": "90", + "initial_layer_jerk": "10", + "initial_layer_travel_speed": "250", + "inner_wall_acceleration": "10000", + "inner_wall_speed": "200", + "inner_wall_jerk": "10", + "internal_solid_infill_acceleration": "15000", + "internal_solid_infill_speed": "200", + "layer_height": "0.14", + "max_travel_detour_distance": "50", + "outer_wall_acceleration": "7500", + "outer_wall_jerk": "10", + "outer_wall_speed": "200", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "reduce_crossing_wall": "1", + "skirt_loops": "2", + "slow_down_layers": "2", + "small_perimeter_speed": "75%", + "small_perimeter_threshold": "3", + "sparse_infill_acceleration": "15000", + "sparse_infill_speed": "200", + "sparse_infill_density": "40%", + "sparse_infill_pattern": "gyroid", + "support_base_pattern_spacing": "1.5", + "support_bottom_interface_spacing": "0.3", + "support_bottom_z_distance": "0.15", + "support_interface_speed": "300", + "support_speed": "200", + "support_type": "normal(manual)", + "top_shell_layers": "7", + "top_shell_thickness": "1", + "top_surface_acceleration": "7500", + "top_surface_jerk": "10", + "top_surface_speed": "200", + "travel_jerk": "10", + "wall_generator": "arachne", + "wall_sequence": "inner wall/outer wall", + "top_bottom_infill_wall_overlap": "25%", + "wall_loops": "4" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm Daily @LH Stinger.json b/resources/profiles/LH/process/0.20mm Daily @LH Stinger.json new file mode 100644 index 0000000000..78f152a487 --- /dev/null +++ b/resources/profiles/LH/process/0.20mm Daily @LH Stinger.json @@ -0,0 +1,12 @@ +{ + "type": "process", + "name": "0.20mm Daily @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_daily", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm MMU @LH Stinger.json b/resources/profiles/LH/process/0.20mm MMU @LH Stinger.json new file mode 100644 index 0000000000..e4a2616d10 --- /dev/null +++ b/resources/profiles/LH/process/0.20mm MMU @LH Stinger.json @@ -0,0 +1,48 @@ +{ + "type": "process", + "name": "0.20mm MMU @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_mmu", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger MMU 0.4 nozzle" + ], + "bottom_surface_pattern": "monotonicline", + "bridge_acceleration": "7000", + "default_jerk": "10", + "detect_narrow_internal_solid_infill": "0", + "filter_out_gap_fill": "1", + "gap_infill_speed": "220", + "infill_jerk": "10", + "infill_wall_overlap": "8%", + "initial_layer_infill_speed": "120", + "initial_layer_jerk": "10", + "initial_layer_line_width": "0.4", + "inner_wall_acceleration": "15000", + "inner_wall_jerk": "10", + "inner_wall_speed": "220", + "internal_solid_infill_acceleration": "15000", + "internal_solid_infill_speed": "220", + "only_one_wall_first_layer": "1", + "outer_wall_jerk": "10", + "outer_wall_speed": "220", + "prime_tower_width": "80", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "raft_first_layer_density": "50%", + "small_perimeter_threshold": "2", + "sparse_infill_acceleration": "15000", + "sparse_infill_pattern": "rectilinear", + "sparse_infill_speed": "220", + "top_bottom_infill_wall_overlap": "8%", + "top_surface_jerk": "10", + "top_surface_speed": "150", + "wall_generator": "arachne", + "sparse_infill_density": "15%", + "travel_jerk": "10" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm PETG @LH Stinger.json b/resources/profiles/LH/process/0.20mm PETG @LH Stinger.json new file mode 100644 index 0000000000..8582a7f0ac --- /dev/null +++ b/resources/profiles/LH/process/0.20mm PETG @LH Stinger.json @@ -0,0 +1,74 @@ +{ + "type": "process", + "name": "0.20mm PETG @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_petg", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "accel_to_decel_factor": "90%", + "bottom_shell_layers": "5", + "bridge_acceleration": "3000", + "bridge_density": "95%", + "bridge_flow": "1.1", + "bridge_speed": "30", + "brim_ears_max_angle": "180", + "brim_object_gap": "0.04", + "default_acceleration": "15000", + "default_jerk": "10", + "filter_out_gap_fill": "1", + "gap_infill_speed": "200", + "infill_jerk": "10", + "infill_wall_overlap": "10%", + "initial_layer_infill_speed": "100", + "initial_layer_jerk": "10", + "initial_layer_print_height": "0.25", + "initial_layer_travel_speed": "250", + "inner_wall_acceleration": "15000", + "inner_wall_speed": "200", + "inner_wall_jerk": "10", + "inner_wall_line_width": "0.44", + "internal_bridge_speed": "50", + "internal_solid_infill_acceleration": "15000", + "internal_solid_infill_speed": "200", + "internal_solid_infill_line_width": "0.44", + "line_width": "0.44", + "max_travel_detour_distance": "50", + "outer_wall_jerk": "10", + "outer_wall_line_width": "0.44", + "outer_wall_speed": "200", + "overhang_1_4_speed": "60%", + "overhang_2_4_speed": "40", + "overhang_3_4_speed": "20", + "overhang_reverse_internal_only": "1", + "overhang_reverse_threshold": "0%", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "raft_first_layer_density": "60%", + "reduce_crossing_wall": "1", + "skirt_loops": "2", + "slow_down_layers": "2", + "small_perimeter_threshold": "10", + "sparse_infill_acceleration": "15000", + "sparse_infill_speed": "200", + "sparse_infill_line_width": "0.44", + "support_interface_speed": "200", + "support_line_width": "0.42", + "support_speed": "200", + "top_bottom_infill_wall_overlap": "18%", + "top_shell_layers": "6", + "top_surface_acceleration": "5000", + "top_surface_jerk": "10", + "top_surface_speed": "130", + "travel_jerk": "10", + "wall_loops": "3", + "gap_fill_target": "nowhere", + "wipe_tower_max_purge_speed": "150" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm Quiet @LH Stinger.json b/resources/profiles/LH/process/0.20mm Quiet @LH Stinger.json new file mode 100644 index 0000000000..d26b9efef8 --- /dev/null +++ b/resources/profiles/LH/process/0.20mm Quiet @LH Stinger.json @@ -0,0 +1,53 @@ +{ + "type": "process", + "name": "0.20mm Quiet @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_quiet", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "accel_to_decel_factor": "75%", + "bridge_acceleration": "5000", + "bridge_speed": "40", + "default_acceleration": "10000", + "default_jerk": "5", + "filter_out_gap_fill": "10", + "gap_infill_speed": "200", + "infill_jerk": "5", + "infill_wall_overlap": "10%", + "initial_layer_infill_speed": "100", + "initial_layer_jerk": "5", + "initial_layer_travel_speed": "180", + "inner_wall_acceleration": "10000", + "inner_wall_jerk": "5", + "internal_bridge_speed": "60", + "internal_solid_infill_acceleration": "10000", + "outer_wall_acceleration": "5000", + "outer_wall_jerk": "5", + "outer_wall_speed": "200", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "raft_first_layer_density": "60%", + "sparse_infill_acceleration": "10000", + "sparse_infill_pattern": "rectilinear", + "support_interface_speed": "170", + "support_speed": "170", + "top_surface_jerk": "5", + "top_surface_speed": "200", + "inner_wall_speed": "200", + "sparse_infill_speed": "200", + "internal_solid_infill_speed": "200", + "travel_acceleration": "10000", + "travel_jerk": "5", + "sparse_infill_density": "15%", + "accel_to_decel_enable": "1", + "gap_fill_target": "nowhere", + "travel_speed": "200" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm Solid @LH Stinger.json b/resources/profiles/LH/process/0.20mm Solid @LH Stinger.json new file mode 100644 index 0000000000..4d1218db8b --- /dev/null +++ b/resources/profiles/LH/process/0.20mm Solid @LH Stinger.json @@ -0,0 +1,64 @@ +{ + "type": "process", + "name": "0.20mm Solid @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_solid", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "accel_to_decel_factor": "90%", + "bottom_shell_layers": "2", + "bridge_acceleration": "5000", + "bridge_density": "97%", + "brim_object_gap": "0.04", + "default_acceleration": "15000", + "default_jerk": "10", + "detect_narrow_internal_solid_infill": "0", + "enable_support": "1", + "ensure_vertical_shell_thickness": "none", + "filter_out_gap_fill": "2", + "gap_infill_speed": "200", + "infill_jerk": "10", + "infill_wall_overlap": "18%", + "initial_layer_jerk": "10", + "initial_layer_line_width": "0.45", + "initial_layer_print_height": "0.25", + "inner_wall_acceleration": "15000", + "inner_wall_jerk": "10", + "internal_solid_infill_acceleration": "15000", + "outer_wall_jerk": "10", + "outer_wall_speed": "200", + "overhang_1_4_speed": "60%", + "overhang_2_4_speed": "40", + "overhang_3_4_speed": "20", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "raft_first_layer_density": "60%", + "small_perimeter_threshold": "7", + "sparse_infill_acceleration": "15000", + "sparse_infill_density": "98%", + "sparse_infill_pattern": "rectilinear", + "support_interface_speed": "200", + "support_speed": "200", + "top_shell_layers": "2", + "top_shell_thickness": "0.6", + "top_solid_infill_flow_ratio": "0.96", + "top_surface_acceleration": "5000", + "top_surface_jerk": "10", + "top_surface_speed": "150", + "inner_wall_speed": "200", + "sparse_infill_speed": "200", + "internal_solid_infill_speed": "200", + "internal_bridge_density": "95%", + "internal_bridge_speed": "150", + "gap_fill_target": "nowhere", + "wall_loops": "3", + "travel_jerk": "10" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm Speed @LH Stinger.json b/resources/profiles/LH/process/0.20mm Speed @LH Stinger.json new file mode 100644 index 0000000000..a56bf33a87 --- /dev/null +++ b/resources/profiles/LH/process/0.20mm Speed @LH Stinger.json @@ -0,0 +1,43 @@ +{ + "type": "process", + "name": "0.20mm Speed @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_speed", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "bridge_acceleration": "15000", + "default_acceleration": "30000", + "filter_out_gap_fill": "10", + "infill_wall_overlap": "10%", + "initial_layer_speed": "90", + "inner_wall_acceleration": "30000", + "inner_wall_speed": "600", + "internal_solid_infill_acceleration": "30000", + "internal_solid_infill_speed": "600", + "outer_wall_acceleration": "15000", + "outer_wall_speed": "600", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "raft_first_layer_density": "80%", + "sparse_infill_acceleration": "30000", + "sparse_infill_pattern": "rectilinear", + "sparse_infill_speed": "600", + "support_bottom_z_distance": "0.15", + "support_expansion": "2", + "support_interface_top_layers": "3", + "support_object_xy_distance": "0.25", + "top_surface_acceleration": "15000", + "top_surface_speed": "300", + "travel_acceleration": "30000", + "sparse_infill_density": "15%", + "gap_fill_target": "nowhere", + "travel_speed": "600" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm Strength @LH Stinger.json b/resources/profiles/LH/process/0.20mm Strength @LH Stinger.json new file mode 100644 index 0000000000..8d1929bb60 --- /dev/null +++ b/resources/profiles/LH/process/0.20mm Strength @LH Stinger.json @@ -0,0 +1,66 @@ +{ + "type": "process", + "name": "0.20mm Strength @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_strength", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "accel_to_decel_factor": "90%", + "bottom_shell_layers": "5", + "bridge_acceleration": "5000", + "bridge_flow": "1.4", + "brim_object_gap": "0.04", + "default_acceleration": "15000", + "default_jerk": "10", + "filter_out_gap_fill": "1", + "gap_infill_speed": "200", + "infill_anchor": "1000", + "infill_anchor_max": "1000", + "infill_jerk": "10", + "initial_layer_infill_speed": "120", + "initial_layer_jerk": "10", + "initial_layer_speed": "90", + "initial_layer_travel_speed": "250", + "inner_wall_acceleration": "15000", + "inner_wall_jerk": "10", + "inner_wall_line_width": "0.46", + "internal_solid_infill_acceleration": "15000", + "internal_solid_infill_line_width": "0.46", + "line_width": "0.46", + "outer_wall_jerk": "10", + "outer_wall_line_width": "0.46", + "outer_wall_speed": "200", + "overhang_1_4_speed": "60%", + "overhang_2_4_speed": "40", + "overhang_3_4_speed": "20", + "precise_outer_wall": "0", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "sparse_infill_acceleration": "15000", + "sparse_infill_density": "40%", + "sparse_infill_line_width": "0.46", + "sparse_infill_pattern": "gyroid", + "support_bottom_z_distance": "0.15", + "support_interface_speed": "200", + "support_line_width": "0.42", + "support_speed": "200", + "top_shell_layers": "6", + "top_shell_thickness": "1", + "top_surface_acceleration": "5000", + "top_surface_jerk": "10", + "top_surface_speed": "200", + "inner_wall_speed": "200", + "sparse_infill_speed": "200", + "internal_solid_infill_speed": "200", + "travel_jerk": "10", + "wall_sequence": "inner wall/outer wall", + "wall_loops": "4" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.20mm TPU @LH Stinger.json b/resources/profiles/LH/process/0.20mm TPU @LH Stinger.json new file mode 100644 index 0000000000..6893ec1e05 --- /dev/null +++ b/resources/profiles/LH/process/0.20mm TPU @LH Stinger.json @@ -0,0 +1,82 @@ +{ + "type": "process", + "name": "0.20mm TPU @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_tpu", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "accel_to_decel_factor": "90%", + "bridge_acceleration": "5000", + "bridge_density": "95%", + "bridge_flow": "1.4", + "bridge_speed": "40", + "brim_ears_max_angle": "180", + "brim_object_gap": "0.02", + "default_acceleration": "15000", + "default_jerk": "5", + "elefant_foot_compensation": "0.15", + "filter_out_gap_fill": "40", + "gap_infill_speed": "200", + "infill_jerk": "5", + "initial_layer_infill_speed": "70", + "initial_layer_jerk": "5", + "initial_layer_print_height": "0.25", + "initial_layer_speed": "40", + "initial_layer_travel_speed": "200", + "inner_wall_acceleration": "15000", + "inner_wall_jerk": "5", + "inner_wall_line_width": "0.46", + "internal_bridge_flow": "1.2", + "internal_bridge_speed": "50", + "internal_solid_infill_acceleration": "15000", + "internal_solid_infill_line_width": "0.46", + "internal_solid_infill_speed": "180", + "line_width": "0.46", + "max_travel_detour_distance": "50", + "outer_wall_jerk": "5", + "outer_wall_line_width": "0.46", + "outer_wall_speed": "150", + "overhang_1_4_speed": "60%", + "overhang_2_4_speed": "40", + "overhang_3_4_speed": "20", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "raft_first_layer_density": "80%", + "reduce_crossing_wall": "1", + "skirt_loops": "2", + "slow_down_layers": "2", + "small_perimeter_speed": "60%", + "small_perimeter_threshold": "10", + "sparse_infill_acceleration": "15000", + "sparse_infill_line_width": "0.46", + "sparse_infill_speed": "150", + "sparse_infill_density": "15%", + "staggered_inner_seams": "1", + "support_expansion": "2", + "support_interface_speed": "200", + "support_line_width": "0.42", + "support_speed": "200", + "top_bottom_infill_wall_overlap": "18%", + "top_surface_acceleration": "5000", + "top_surface_jerk": "5", + "top_surface_line_width": "0.42", + "top_surface_speed": "150", + "travel_jerk": "10", + "wipe_speed": "80", + "inner_wall_speed": "200", + "ensure_vertical_shell_thickness": "ensure_moderate", + "wall_sequence": "inner wall/outer wall", + "wall_loops": "3", + "gap_fill_target": "nowhere", + "reduce_infill_retraction": "1", + "infill_wall_overlap": "22%", + "wipe_tower_max_purge_speed": "80" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/0.25mm Vase Mode @LH Stinger.json b/resources/profiles/LH/process/0.25mm Vase Mode @LH Stinger.json new file mode 100644 index 0000000000..bc612fc5e9 --- /dev/null +++ b/resources/profiles/LH/process/0.25mm Vase Mode @LH Stinger.json @@ -0,0 +1,70 @@ +{ + "type": "process", + "name": "0.25mm Vase Mode @LH Stinger", + "inherits": "fdm_process_lh_common", + "from": "system", + "setting_id": "LHS_P_vase_mode", + "instantiation": "true", + "compatible_printers": [ + "LH Stinger 0.4 nozzle", + "LH Stinger MMU 0.4 nozzle" + ], + "accel_to_decel_factor": "90%", + "bottom_shell_layers": "5", + "bridge_acceleration": "5000", + "bridge_flow": "1.4", + "brim_object_gap": "0.04", + "default_acceleration": "15000", + "default_jerk": "10", + "filter_out_gap_fill": "1", + "gap_infill_speed": "200", + "infill_jerk": "10", + "infill_wall_overlap": "10%", + "initial_layer_jerk": "10", + "initial_layer_line_width": "0.65", + "initial_layer_print_height": "0.25", + "initial_layer_speed": "80", + "initial_layer_travel_speed": "250", + "inner_wall_acceleration": "15000", + "inner_wall_jerk": "10", + "inner_wall_line_width": "0.46", + "internal_solid_infill_acceleration": "15000", + "internal_solid_infill_line_width": "0.46", + "layer_height": "0.25", + "line_width": "0.46", + "notes": "Decrease your Filament - Minimum layer time to ~2 seconds and set your fan speeds to be constant", + "outer_wall_jerk": "10", + "outer_wall_line_width": "0.65", + "outer_wall_speed": "200", + "overhang_1_4_speed": "60%", + "overhang_2_4_speed": "40", + "overhang_3_4_speed": "20", + "print_extruder_id": [ + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard" + ], + "sparse_infill_acceleration": "15000", + "sparse_infill_density": "0%", + "sparse_infill_line_width": "0.46", + "sparse_infill_pattern": "3dhoneycomb", + "spiral_mode": "1", + "spiral_mode_smooth": "1", + "support_interface_speed": "200", + "support_line_width": "0.42", + "support_speed": "200", + "top_bottom_infill_wall_overlap": "10%", + "top_shell_layers": "0", + "top_shell_thickness": "1", + "top_surface_acceleration": "5000", + "top_surface_jerk": "10", + "top_surface_speed": "200", + "inner_wall_speed": "200", + "sparse_infill_speed": "200", + "internal_solid_infill_speed": "200", + "wall_sequence": "inner wall/outer wall", + "travel_jerk": "10", + "skirt_loops": "1", + "wall_loops": "1" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/fdm_process_common.json b/resources/profiles/LH/process/fdm_process_common.json new file mode 100644 index 0000000000..df8283904a --- /dev/null +++ b/resources/profiles/LH/process/fdm_process_common.json @@ -0,0 +1,108 @@ +{ + "type": "process", + "name": "fdm_process_common", + "from": "system", + "instantiation": "false", + "adaptive_layer_height": "0", + "reduce_crossing_wall": "0", + "max_travel_detour_distance": "0", + "bottom_surface_pattern": "monotonic", + "bottom_shell_thickness": "0", + "bridge_speed": "50", + "brim_width": "5", + "brim_object_gap": "0.1", + "compatible_printers": [], + "compatible_printers_condition": "", + "print_sequence": "by layer", + "default_acceleration": "1000", + "initial_layer_acceleration": "500", + "top_surface_acceleration": "1000", + "travel_acceleration": "1000", + "inner_wall_acceleration": "1000", + "outer_wall_acceleration": "700", + "bridge_no_support": "0", + "draft_shield": "disabled", + "elefant_foot_compensation": "0", + "enable_arc_fitting": "0", + "wall_infill_order": "inner wall/outer wall/infill", + "infill_direction": "45", + "sparse_infill_density": "15%", + "sparse_infill_pattern": "crosshatch", + "initial_layer_print_height": "0.2", + "infill_combination": "0", + "infill_wall_overlap": "25%", + "interface_shells": "0", + "ironing_flow": "10%", + "ironing_spacing": "0.15", + "ironing_speed": "30", + "ironing_type": "no ironing", + "reduce_infill_retraction": "1", + "filename_format": "{input_filename_base}_{layer_height}mm_{filament_type[initial_tool]}_{printer_model}_{print_time}.gcode", + "detect_overhang_wall": "1", + "slowdown_for_curled_perimeters": "1", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "30", + "overhang_4_4_speed": "10", + "line_width": "110%", + "inner_wall_line_width": "110%", + "outer_wall_line_width": "100%", + "top_surface_line_width": "93.75%", + "sparse_infill_line_width": "110%", + "initial_layer_line_width": "120%", + "internal_solid_infill_line_width": "120%", + "support_line_width": "96%", + "wall_loops": "3", + "print_settings_id": "", + "raft_layers": "0", + "seam_position": "aligned", + "skirt_distance": "2", + "skirt_height": "3", + "min_skirt_length": "4", + "skirt_loops": "0", + "minimum_sparse_infill_area": "15", + "spiral_mode": "0", + "standby_temperature_delta": "-5", + "enable_support": "0", + "resolution": "0.012", + "support_type": "normal(auto)", + "support_on_build_plate_only": "0", + "support_top_z_distance": "0.2", + "support_bottom_z_distance": "0.2", + "support_filament": "0", + "support_interface_loop_pattern": "0", + "support_interface_filament": "0", + "support_interface_top_layers": "2", + "support_interface_bottom_layers": "2", + "support_interface_spacing": "0.5", + "support_interface_speed": "80", + "support_base_pattern": "default", + "support_base_pattern_spacing": "2.5", + "support_speed": "150", + "support_threshold_angle": "30", + "support_object_xy_distance": "0.35", + "tree_support_branch_angle": "30", + "tree_support_wall_count": "0", + "tree_support_with_infill": "0", + "detect_thin_wall": "0", + "top_surface_pattern": "monotonicline", + "top_shell_thickness": "0.8", + "enable_prime_tower": "0", + "wipe_tower_no_sparse_layers": "0", + "prime_tower_width": "60", + "xy_hole_compensation": "0", + "xy_contour_compensation": "0", + "layer_height": "0.2", + "bottom_shell_layers": "3", + "top_shell_layers": "4", + "bridge_flow": "1", + "initial_layer_speed": "45", + "initial_layer_infill_speed": "45", + "outer_wall_speed": "45", + "inner_wall_speed": "80", + "sparse_infill_speed": "150", + "internal_solid_infill_speed": "150", + "top_surface_speed": "50", + "gap_infill_speed": "30", + "travel_speed": "200" +} \ No newline at end of file diff --git a/resources/profiles/LH/process/fdm_process_lh_common.json b/resources/profiles/LH/process/fdm_process_lh_common.json new file mode 100644 index 0000000000..49ea02fee8 --- /dev/null +++ b/resources/profiles/LH/process/fdm_process_lh_common.json @@ -0,0 +1,109 @@ +{ + "type": "process", + "name": "fdm_process_lh_common", + "inherits": "fdm_process_common", + "from": "system", + "instantiation": "false", + "exclude_object": "1", + "accel_to_decel_enable": "0", + "bottom_shell_layers": "4", + "bridge_acceleration": "10000", + "bridge_density": "100%", + "brim_object_gap": "0.05", + "brim_width": "4", + "default_acceleration": "20000", + "dont_filter_internal_bridges": "limited", + "elefant_foot_compensation": "0.05", + "ensure_vertical_shell_thickness": "ensure_critical_only", + "filter_out_gap_fill": "1", + "gap_fill_target": "everywhere", + "gap_infill_speed": "400", + "independent_support_layer_height": "0", + "infill_jerk": "15", + "infill_wall_overlap": "15%", + "top_bottom_infill_wall_overlap": "22%", + "initial_layer_acceleration": "600", + "initial_layer_infill_speed": "140", + "initial_layer_jerk": "15", + "initial_layer_line_width": "0.5", + "initial_layer_speed": "60", + "initial_layer_travel_speed": "300", + "inner_wall_acceleration": "20000", + "inner_wall_jerk": "15", + "inner_wall_line_width": "0.4", + "inner_wall_speed": "400", + "internal_bridge_speed": "70", + "internal_solid_infill_acceleration": "20000", + "internal_solid_infill_line_width": "0.4", + "internal_solid_infill_speed": "400", + "ironing_flow": "19%", + "ironing_inset": "0.3", + "ironing_speed": "50", + "line_width": "0.4", + "min_bead_width": "75%", + "min_feature_size": "20%", + "min_length_factor": "1.5", + "min_width_top_surface": "200%", + "only_one_wall_top": "1", + "outer_wall_acceleration": "10000", + "outer_wall_jerk": "15", + "outer_wall_line_width": "0.4", + "outer_wall_speed": "400", + "overhang_1_4_speed": "70%", + "overhang_4_4_speed": "15", + "prime_tower_brim_width": "2", + "prime_tower_width": "80", + "prime_volume": "75", + "raft_first_layer_density": "70%", + "reduce_infill_retraction": "0", + "resolution": "0.01", + "role_based_wipe_speed": "0", + "seam_gap": "0", + "skirt_distance": "8", + "skirt_height": "1", + "skirt_speed": "100", + "skirt_start_angle": "-25", + "slice_closing_radius": "0.04", + "slowdown_for_curled_perimeters": "0", + "sparse_infill_acceleration": "20000", + "sparse_infill_density": "20%", + "sparse_infill_line_width": "0.4", + "sparse_infill_pattern": "3dhoneycomb", + "sparse_infill_speed": "400", + "support_angle": "135", + "support_base_pattern_spacing": "2", + "support_expansion": "1", + "support_interface_spacing": "0.3", + "support_interface_speed": "400", + "support_line_width": "0.4", + "support_object_xy_distance": "0.2", + "support_on_build_plate_only": "1", + "support_speed": "400", + "support_style": "snug", + "support_top_z_distance": "0.15", + "thick_internal_bridges": "0", + "top_shell_layers": "5", + "top_surface_acceleration": "10000", + "top_surface_jerk": "15", + "top_surface_line_width": "0.4", + "top_surface_speed": "250", + "travel_acceleration": "20000", + "travel_jerk": "15", + "travel_speed": "400", + "wall_generator": "classic", + "wall_loops": "2", + "wall_sequence": "outer wall/inner wall", + "wipe_speed": "150", + "wipe_tower_bridging": "15", + "wipe_tower_extra_flow": "120%", + "wipe_tower_max_purge_speed": "200", + "enable_prime_tower": "1", + "precise_outer_wall": "0", + "print_extruder_id": [ + "1" + ], + "brim_type": "auto_brim", + "print_extruder_variant": [ + "Direct Drive Standard" + ] +} \ No newline at end of file diff --git a/resources/profiles/re3D/filament/re3D rPP.json b/resources/profiles/re3D/filament/re3D rPP.json index 673dd9fffe..420b795366 100644 --- a/resources/profiles/re3D/filament/re3D rPP.json +++ b/resources/profiles/re3D/filament/re3D rPP.json @@ -6,7 +6,9 @@ "from": "system", "instantiation": "true", "inherits": "fdm_filament_pet", - "filament_type": "PP", + "filament_type": [ + "PP" + ], "nozzle_temperature_initial_layer": [ "185" ], diff --git a/resources/web/homepage/css/home.css b/resources/web/homepage/css/home.css index da12d73a3c..2bcc18451f 100644 --- a/resources/web/homepage/css/home.css +++ b/resources/web/homepage/css/home.css @@ -71,6 +71,7 @@ body #LeftBoard { + display: none; /* shown by cloud_providers_info from backend */ border-right-width: 1px; border-right-style: solid; width:262px; diff --git a/resources/web/homepage/js/home.js b/resources/web/homepage/js/home.js index 1a63290645..72789cc088 100644 --- a/resources/web/homepage/js/home.js +++ b/resources/web/homepage/js/home.js @@ -103,11 +103,20 @@ function HandleStudio( pVal ) GotoMenu(strName); } else if (strCmd == "cloud_providers_info") { - if (pVal["data"]["providers"] && pVal["data"]["providers"].indexOf("bbl") >= 0) { + var providers = (pVal["data"] && pVal["data"]["providers"]) || []; + + if (providers.indexOf("bbl") >= 0) { $("#BambuCloudSection").show(); } else { + SetBambuUserOffline(); $("#BambuCloudSection").hide(); } + + if (providers.indexOf("orca") >= 0) { + $("#LeftBoard").show(); + } else { + $("#LeftBoard").hide(); + } } else if (strCmd == "network_plugin_installtip") { let nShow = pVal["show"] * 1; diff --git a/scripts/orca_extra_profile_check.py b/scripts/orca_extra_profile_check.py index 00664d309d..7ccc5a1a7f 100644 --- a/scripts/orca_extra_profile_check.py +++ b/scripts/orca_extra_profile_check.py @@ -360,6 +360,50 @@ CONFLICT_KEYS = [ ['extruder_clearance_radius', 'extruder_clearance_max_radius'], ] +VECTOR_KEYS = { + "filament_type", +} + +def check_vector_type_keys(profiles_dir, vendor_name): + """ + Check that properties expected to be vectors (JSON arrays) are not stored as scalars. + For example, `filament_type` must be a list like ["PA-CF"], not a string "PA-CF". + + Parameters: + profiles_dir (Path): Base profiles directory + vendor_name (str): Vendor name + + Returns: + int: Number of errors found + """ + error_count = 0 + vendor_path = profiles_dir / vendor_name + + if not vendor_path.exists(): + return 0 + + for file_path in vendor_path.rglob("*.json"): + try: + with open(file_path, "r", encoding="UTF-8") as fp: + data = json.load(fp) + except Exception as e: + print_error(f"Error processing {file_path.relative_to(profiles_dir)}: {e}") + error_count += 1 + continue + + if not isinstance(data, dict): + continue + + for key in VECTOR_KEYS: + if key in data and not isinstance(data[key], list): + print_error( + f"'{key}' must be an array in {file_path.relative_to(profiles_dir)}, " + f"got {type(data[key]).__name__}: {data[key]!r}" + ) + error_count += 1 + + return error_count + def check_conflict_keys(profiles_dir, vendor_name): """ Check for keys that could not be specified at the same time, @@ -448,6 +492,8 @@ def main(): errors_found += new_errors warnings_found += new_warnings + errors_found += check_vector_type_keys(profiles_dir, vendor_name) + errors_found += check_filament_id(vendor_name, vendor_path / "filament") checked_vendor_count += 1 diff --git a/scripts/orca_filament_lib.py b/scripts/orca_filament_lib.py index 92f6d1dc55..65f037e3f3 100644 --- a/scripts/orca_filament_lib.py +++ b/scripts/orca_filament_lib.py @@ -132,6 +132,7 @@ def update_profile_library(vendor="",profile_type="filament"): library[profile_section] = sorted_profiles f.seek(0) json.dump(library, f, indent="\t", ensure_ascii=False) + f.write('\n') f.truncate() print(f"Profile library for {vendor} updated successfully!") @@ -230,6 +231,7 @@ def clean_up_profile(vendor="", profile_type="", force=False): f.seek(0) ordered_profile = create_ordered_profile(_profile, ['type', 'name', 'renamed_from', 'inherits', 'from', 'setting_id', 'filament_id', 'instantiation']) json.dump(ordered_profile, f, indent="\t", ensure_ascii=False) + f.write('\n') f.truncate() print(f"Updated profile: {full_path}") except Exception as e: @@ -274,6 +276,7 @@ def rename_filament_system(vendor="OrcaFilamentLibrary"): if modified: with open(full_path, 'w', encoding='utf-8') as f: json.dump(data, f, indent="\t", ensure_ascii=False) + f.write('\n') print(f"Updated {full_path}") except Exception as e: diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 6da825b090..49afa106be 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -299,7 +299,7 @@ void AppConfig::set_defaults() set_bool("enable_ssl_for_ftp", true); if (get("log_severity_level").empty()) - set("log_severity_level", "warning"); + set("log_severity_level", "info"); if (get("internal_developer_mode").empty()) set_bool("internal_developer_mode", false); diff --git a/src/libslic3r/ContourZ.cpp b/src/libslic3r/ContourZ.cpp index dc6cc08f46..f4a5fc049a 100644 --- a/src/libslic3r/ContourZ.cpp +++ b/src/libslic3r/ContourZ.cpp @@ -37,7 +37,7 @@ static bool contour_extrusion_path(LayerRegion *region, const sla::IndexedMesh & } Layer *layer = region->layer(); - coordf_t mesh_z = layer->print_z + mesh.ground_level(); + coordf_t mesh_slice_z = layer->slice_z + mesh.ground_level(); coordf_t min_z = region->region().config().zaa_min_z; const Points3 &points = path.polyline.points; @@ -50,7 +50,12 @@ static bool contour_extrusion_path(LayerRegion *region, const sla::IndexedMesh & Pointf3s contoured_points; bool was_contoured = false; - for (Points3::const_iterator it = points.begin(); it != points.end()-1; ++it) { + if (points.size() < 2) { + // Safety check. The loop below does not handle paths with less than two points correctly. + return false; + } + + for (Points3::const_iterator it = points.begin(); it != points.end()-1; ++it) { Vec2d p1d(unscale_(it->x()), unscale_(it->y())); Vec2d p2d(unscale_((it+1)->x()), unscale_((it+1)->y())); Linef line(p1d, p2d); @@ -69,14 +74,10 @@ static bool contour_extrusion_path(LayerRegion *region, const sla::IndexedMesh & coordf_t x = p.x(); coordf_t y = p.y(); - sla::IndexedMesh::hit_result hit_up = mesh.query_ray_hit({x, y, mesh_z}, {0.0, 0.0, 1.0}); - sla::IndexedMesh::hit_result hit_down = mesh.query_ray_hit({x, y, mesh_z}, {0.0, 0.0, -1.0}); + sla::IndexedMesh::hit_result hit_up = mesh.query_ray_hit({x, y, mesh_slice_z}, {0.0, 0.0, 1.0}); + + double d = hit_up.distance() - (layer->print_z - layer->slice_z); - double up = hit_up.distance(); - double down = hit_down.distance(); - double d = up < down ? up : -down; - const Vec3d &normal = (up < down ? hit_up : hit_down).normal(); - double max_up = min_z; double min_down = -(height - min_z); double half_width = path.width / 2.0; @@ -85,7 +86,8 @@ static bool contour_extrusion_path(LayerRegion *region, const sla::IndexedMesh & min_down = -(height + 0.1); } - if (is_perimeter(path.role())) { + if (is_perimeter(path.role()) && hit_up.is_hit()) { + const Vec3d &normal = hit_up.normal(); double slope_rad = slope_from_normal(normal); double slope_degrees = slope_rad * 180.0 / M_PI; @@ -123,7 +125,14 @@ static bool contour_extrusion_path(LayerRegion *region, const sla::IndexedMesh & Vec3d new_point = {p.x(), p.y(), d}; - if (contoured_points.size() >= 2) { + if (contoured_points.size() >= 2 && i != 0) { + // Normally, if the new point is collinear with the last two points, we do not add + // it to the list of contoured points. Instead we update the last point to be the + // new point. This is to avoid creating a large number of very short segments. + // + // However, if the new point corresponds to a point in the original path (i == 0), + // even if it is collinear, we add it anyway. This is to avoid creating a degenerate + // polygon with only two points, which may cause issues in downstream code. double dist = Linef3::distance_to_infinite_squared(new_point, contoured_points[contoured_points.size() - 2], contoured_points[contoured_points.size() - 1]); if (dist < EPSILON * EPSILON) { diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index ce74d93e9e..b8251bf3d0 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -491,7 +491,11 @@ public: { Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; } // Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm. double min_mm3_per_mm() const override; - Polyline as_polyline() const override { return this->polygon().split_at_first_point(); } + Polyline as_polyline() const override { + if (this->paths.empty() || this->length() <= 0.) + return Polyline(); + return this->polygon().split_at_first_point(); + } void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); } void collect_points(Points &dst) const override { size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); }); diff --git a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp index 812f9f9d14..11e2d081d2 100644 --- a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp +++ b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp @@ -66,9 +66,240 @@ static std::unique_ptr get_noise_module(const FuzzySkinCo } } +// --------------------------------------------------------------------------- +// Ripple noise — deterministic sine-wave displacement along the path arc length. +// +// Unlike the other noise types, the ripple pattern is driven by cumulative arc +// length along the print path rather than world-space (x, y, z) coordinates. +// This gives a uniform wave period regardless of the polygon's geometry. +// +// A consistent visual anchor is established by finding the leftmost Y=0 crossing +// of the polygon (the point where the sine wave always peaks when phase shift is +// zero), ensuring the pattern aligns across layers. +// +// Per-layer-group phase shifting works as follows: +// period_index = floor(layer_id / layers_between_ripple_offset) +// phase_shift = period_index * (ripple_offset / 100) * 2π [radians] +// +// Setting layers_between_ripple_offset = 1 shifts the phase on every layer; +// setting it to N makes N consecutive layers share the same pattern. +// --------------------------------------------------------------------------- + +// Compute the per-layer-group phase shift in radians. +static double ripple_phase_shift_rad(const FuzzySkinConfig& cfg) +{ + if (cfg.ripple_offset == 0.0 || cfg.layers_between_ripple_offset <= 0) + return 0.0; + + const int effective_layer = std::max(cfg.layer_id, 0); + const int period_index = effective_layer / std::max(cfg.layers_between_ripple_offset, 1); + const double raw_shift = period_index * (cfg.ripple_offset/100) * (2.0 * M_PI); + return fmod(raw_shift, 2.0 * M_PI); +} + +// Find the arc-length (in mm) of the visual anchor point along the polygon perimeter. +// The anchor is the leftmost Y=0 crossing, falling back to the vertex with the +// smallest |y| if no crossing exists. The anchor is where sin(phase) = 1 (a peak) +// when the phase shift is zero, giving a stable reference across layers. +static double ripple_anchor_arc_mm(const Points& poly) +{ + const size_t np = poly.size(); + + // Find anchor world position: leftmost Y=0 crossing. + Vec2d anchor_world(std::numeric_limits::max(), std::numeric_limits::max()); + bool found_crossing = false; + for (size_t i = 0; i < np; ++i) { + const double ya = unscale_(poly[i].y()); + const double yb = unscale_(poly[(i + 1) % np].y()); + if ((ya <= 0.0 && yb >= 0.0) || (ya >= 0.0 && yb <= 0.0)) { + const double t = (std::abs(yb - ya) < 1e-9) ? 0.0 : ya / (ya - yb); + const double x_cross = unscale_(poly[i].x()) + + std::max(0.0, std::min(1.0, t)) * (unscale_(poly[(i + 1) % np].x()) - unscale_(poly[i].x())); + if (!found_crossing || x_cross < anchor_world.x()) { + anchor_world = Vec2d(x_cross, 0.0); + found_crossing = true; + } + } + } + if (!found_crossing) { + double best_abs_y = std::numeric_limits::max(); + for (const Point& p : poly) { + const double ay = std::abs(unscale_(p.y())); + if (ay < best_abs_y) { + best_abs_y = ay; + anchor_world = Vec2d(unscale_(p.x()), unscale_(p.y())); + } + } + } + + // Find the arc-length of the closest point on the polyline to anchor_world. + double anchor_arc_mm = 0.0; + double best_dist_sq = std::numeric_limits::max(); + double accum_mm = 0.0; + for (size_t i = 0; i < np; ++i) { + const Vec2d pa_mm(unscale_(poly[i].x()), unscale_(poly[i].y())); + const Vec2d pb_mm(unscale_(poly[(i + 1) % np].x()), unscale_(poly[(i + 1) % np].y())); + const Vec2d seg = pb_mm - pa_mm; + const double seg_len = seg.norm(); + if (seg_len > 1e-9) { + const double t = std::max(0.0, std::min(1.0, (anchor_world - pa_mm).dot(seg) / (seg_len * seg_len))); + const double dist_sq = (pa_mm + seg * t - anchor_world).squaredNorm(); + if (dist_sq < best_dist_sq) { + best_dist_sq = dist_sq; + anchor_arc_mm = accum_mm + t * seg_len; + } + } + accum_mm += seg_len; + } + return anchor_arc_mm; +} + +// Apply a sine-wave ripple displacement to a closed polygon. +// Points are resampled at cfg.point_distance intervals along the perimeter. +static void fuzzy_polyline_ripple(Points& poly, const FuzzySkinConfig& cfg) +{ + const double amplitude = unscale_(cfg.thickness); + const double N = static_cast(cfg.ripples_per_layer); + const double fill_step_mm = unscale_(cfg.point_distance); + + if (N <= 0.0 || fill_step_mm < 1e-6) + return; + + // Compute total perimeter length in mm. + const size_t np = poly.size(); + double perimeter_mm = 0.0; + for (size_t i = 0; i < np; ++i) + perimeter_mm += unscale_((poly[(i + 1) % np] - poly[i]).cast().norm()); + + if (perimeter_mm < 1e-6) + return; + + const double anchor_arc_mm = ripple_anchor_arc_mm(poly); + const double phase_shift_rad = ripple_phase_shift_rad(cfg); + + // Phase function: φ(s) = N·2π·(s - anchor_arc) / perimeter + π/2 + phase_shift + // Adding π/2 ensures sin(φ) = 1 at the anchor when phase_shift = 0 (a peak). + const double phase_at_anchor = M_PI * 2.0 + phase_shift_rad; + auto arc_phase = [&](double arc_mm) -> double { return N * (2.0 * M_PI) * (arc_mm - anchor_arc_mm) / perimeter_mm + phase_at_anchor; }; + + Points out; + out.reserve(static_cast(perimeter_mm / fill_step_mm) + np * 2); + + double accum_mm = 0.0; + for (size_t i = 0; i < np; ++i) { + const Point& p0 = poly[i]; + const Point& p1 = poly[(i + 1) % np]; + const Vec2d seg = (p1 - p0).cast(); + const double seg_len = seg.norm(); + if (seg_len < EPSILON) + continue; + + const double seg_len_mm = unscale_(seg_len); + const Vec2d seg_unit = seg / seg_len; + const Vec2d seg_perp = perp(seg_unit); + const double seg_end_mm = accum_mm + seg_len_mm; + const double first_s = std::ceil(accum_mm / fill_step_mm) * fill_step_mm; + + for (double s = first_s; s < seg_end_mm; s += fill_step_mm) { + const double t = (s - accum_mm) / seg_len_mm; + const double disp = std::sin(arc_phase(s)) * amplitude; + const Point pt = p0 + (seg * t).cast(); + out.emplace_back(pt + (seg_perp * scale_(disp)).cast()); + } + + accum_mm = seg_end_mm; + } + + while (out.size() < 3) + out.emplace_back(poly[poly.size() - 2]); + + if (out.size() >= 3) + poly = std::move(out); +} + +// Apply a sine-wave ripple displacement to an Arachne extrusion line. +// Mirrors fuzzy_polyline_ripple but operates on ExtrusionJunction vectors so +// that per-point line width (j.w) is preserved correctly. +static void fuzzy_extrusion_line_ripple(Arachne::ExtrusionJunctions& ext_lines, const FuzzySkinConfig& cfg) +{ + const double amplitude = unscale_(cfg.thickness); + const double N = static_cast(cfg.ripples_per_layer); + const double fill_step_mm = unscale_(cfg.point_distance); + + if (N <= 0.0 || fill_step_mm < 1e-6) + return; + + // Build a Points vector for perimeter/anchor calculations. + Points poly; + poly.reserve(ext_lines.size()); + for (const auto& j : ext_lines) + poly.push_back(j.p); + + // Compute total length in mm. + const size_t np = poly.size(); + double perimeter_mm = 0.0; + for (size_t i = 0; i + 1 < np; ++i) + perimeter_mm += unscale_((poly[i + 1] - poly[i]).cast().norm()); + + if (perimeter_mm < 1e-6) + return; + + const double anchor_arc_mm = ripple_anchor_arc_mm(poly); + const double phase_shift_rad = ripple_phase_shift_rad(cfg); + const double phase_at_anchor = M_PI * 2.0 + phase_shift_rad; + + auto arc_phase = [&](double arc_mm) -> double { return N * (2.0 * M_PI) * (arc_mm - anchor_arc_mm) / perimeter_mm + phase_at_anchor; }; + + Arachne::ExtrusionJunctions out; + out.reserve(static_cast(perimeter_mm / fill_step_mm) + np * 2); + + double accum_mm = 0.0; + for (size_t i = 0; i + 1 < np; ++i) { + const Arachne::ExtrusionJunction& j0 = ext_lines[i]; + const Arachne::ExtrusionJunction& j1 = ext_lines[i + 1]; + const Vec2d seg = (j1.p - j0.p).cast(); + const double seg_len = seg.norm(); + if (seg_len < EPSILON) + continue; + + const double seg_len_mm = unscale_(seg_len); + const Vec2d seg_unit = seg / seg_len; + const Vec2d seg_perp = perp(seg_unit); + const double seg_end_mm = accum_mm + seg_len_mm; + const double first_s = std::ceil(accum_mm / fill_step_mm) * fill_step_mm; + + for (double s = first_s; s < seg_end_mm; s += fill_step_mm) { + const double t = (s - accum_mm) / seg_len_mm; + const double disp = std::sin(arc_phase(s)) * amplitude; + const Point pt = j0.p + (seg * t).cast(); + out.emplace_back(pt + (seg_perp * scale_(disp)).cast(), j1.w, j1.perimeter_index); + } + + accum_mm = seg_end_mm; + } + + while (out.size() < 3) { + size_t point_idx = ext_lines.size() - 2; + out.emplace_back(ext_lines[point_idx].p, ext_lines[point_idx].w, ext_lines[point_idx].perimeter_index); + if (point_idx == 0) + break; + --point_idx; + } + + if (out.size() >= 3) + ext_lines = std::move(out); +} + // Thanks Cura developers for this function. void fuzzy_polyline(Points& poly, bool closed, coordf_t slice_z, const FuzzySkinConfig& cfg) { + if (cfg.noise_type == NoiseType::Ripple) { + if (poly.size() < 3) + return; + fuzzy_polyline_ripple(poly, cfg); + return; + } + std::unique_ptr noise = get_noise_module(cfg); const double min_dist_between_points = cfg.point_distance * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value @@ -113,6 +344,14 @@ void fuzzy_polyline(Points& poly, bool closed, coordf_t slice_z, const FuzzySkin // Thanks Cura developers for this function. void fuzzy_extrusion_line(Arachne::ExtrusionJunctions& ext_lines, coordf_t slice_z, const FuzzySkinConfig& cfg, bool closed) { + + if (cfg.noise_type == NoiseType::Ripple) { + if (ext_lines.size() < 3) + return; + fuzzy_extrusion_line_ripple(ext_lines, cfg); + return; + } + std::unique_ptr noise = get_noise_module(cfg); const double min_dist_between_points = cfg.point_distance * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value @@ -179,7 +418,13 @@ void group_region_by_fuzzify(PerimeterGenerator& g) g.has_fuzzy_skin = false; g.has_fuzzy_hole = false; - std::unordered_map regions; + struct ConfigSurfaces { + FuzzySkinConfig config; + SurfacesPtr surfaces; + }; + + std::vector regions; + regions.reserve(g.compatible_regions->size()); for (auto region : *g.compatible_regions) { const auto& region_config = region->region().config(); const FuzzySkinConfig cfg{region_config.fuzzy_skin, @@ -190,27 +435,41 @@ void group_region_by_fuzzify(PerimeterGenerator& g) region_config.fuzzy_skin_scale, region_config.fuzzy_skin_octaves, region_config.fuzzy_skin_persistence, - region_config.fuzzy_skin_mode}; - auto& surfaces = regions[cfg]; + region_config.fuzzy_skin_mode, + region_config.fuzzy_skin_ripples_per_layer, + region_config.fuzzy_skin_ripple_offset, + region_config.fuzzy_skin_layers_between_ripple_offset, + g.layer_id}; + + auto it = std::find_if(regions.begin(), regions.end(), [&cfg](const ConfigSurfaces& item) { + return item.config == cfg; + }); + if (it == regions.end()) { + regions.push_back({cfg, {}}); + it = regions.end() - 1; + } + + auto& surfaces = it->surfaces; for (const auto& surface : region->slices.surfaces) { surfaces.push_back(&surface); } - if (cfg.type != FuzzySkinType::None && cfg.type != FuzzySkinType::Disabled_fuzzy) { + if (should_fuzzify(cfg, g.layer_id, 0, true)) { g.has_fuzzy_skin = true; - if (cfg.type != FuzzySkinType::External) { - g.has_fuzzy_hole = true; - } + } + if (should_fuzzify(cfg, g.layer_id, 0, false)) { + g.has_fuzzy_hole = true; } } if (regions.size() == 1) { // optimization - g.regions_by_fuzzify[regions.begin()->first] = {}; + g.regions_by_fuzzify.push_back({regions.front().config, {}}); return; } - for (auto& it : regions) { - g.regions_by_fuzzify[it.first] = offset_ex(it.second, ClipperSafetyOffset); + g.regions_by_fuzzify.reserve(regions.size()); + for (const auto& region : regions) { + g.regions_by_fuzzify.push_back({region.config, offset_ex(region.surfaces, ClipperSafetyOffset)}); } } @@ -226,12 +485,79 @@ bool should_fuzzify(const FuzzySkinConfig& config, const int layer_id, const siz return false; } - const bool fuzzify_contours = loop_idx == 0 || fuzziy_type == FuzzySkinType::AllWalls; - const bool fuzzify_holes = fuzzify_contours && (fuzziy_type == FuzzySkinType::All || fuzziy_type == FuzzySkinType::AllWalls); + const bool fuzzify_contours = (loop_idx == 0 && fuzziy_type != FuzzySkinType::Hole) || fuzziy_type == FuzzySkinType::AllWalls; + const bool fuzzify_holes = (fuzziy_type == FuzzySkinType::Hole || fuzziy_type == FuzzySkinType::All || fuzziy_type == FuzzySkinType::AllWalls) + && (loop_idx == 0 || fuzziy_type == FuzzySkinType::AllWalls); return is_contour ? fuzzify_contours : fuzzify_holes; } +struct MergedFuzzyRegion { + const FuzzySkinConfig *config; + ExPolygons expolygons; +}; + +// Compare whether two configs produce the same fuzzy effect (ignoring type/first_layer +// which only control which loops get fuzzified, not the noise itself). +static bool same_fuzzy_effect(const FuzzySkinConfig& a, const FuzzySkinConfig& b) +{ + return a.thickness == b.thickness + && a.point_distance == b.point_distance + && a.noise_type == b.noise_type + && a.noise_scale == b.noise_scale + && a.noise_octaves == b.noise_octaves + && a.noise_persistence == b.noise_persistence + && a.mode == b.mode + && a.ripples_per_layer == b.ripples_per_layer + && a.ripple_offset == b.ripple_offset + && a.layers_between_ripple_offset == b.layers_between_ripple_offset; +} + +static std::vector collect_merged_fuzzy_regions(const std::vector>& regions, + const int layer_id, + const size_t loop_idx, + const bool is_contour) +{ + // Merge regions that produce identical fuzzy effects (differ only in type). + // When the style (e.g. External) and a painted region (All) both fuzzify this loop + // with the same noise parameters, merging their ExPolygons avoids splitting the + // perimeter at the painted boundary — eliminating discontinuity artifacts. + std::vector merged_regions; + merged_regions.reserve(regions.size()); + for (const auto& region : regions) { + if (!should_fuzzify(region.first, layer_id, loop_idx, is_contour)) { + continue; + } + + bool merged = false; + for (auto& merged_region : merged_regions) { + if (same_fuzzy_effect(*merged_region.config, region.first)) { + if (merged_region.expolygons.empty()) { + // Already full coverage, nothing to add. + } else if (region.second.empty()) { + merged_region.expolygons.clear(); + } else { + append(merged_region.expolygons, region.second); + } + merged = true; + break; + } + } + + if (!merged) { + merged_regions.push_back({®ion.first, region.second}); + } + } + + for (auto& merged_region : merged_regions) { + if (!merged_region.expolygons.empty()) { + merged_region.expolygons = union_ex(merged_region.expolygons); + } + } + + return merged_regions; +} + Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perimeter_generator, const size_t loop_idx, const bool is_contour) { Polygon fuzzified; @@ -250,22 +576,30 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim return fuzzified; } - // Find all affective regions - std::vector> fuzzified_regions; - fuzzified_regions.reserve(regions.size()); - for (const auto& region : regions) { - if (should_fuzzify(region.first, perimeter_generator.layer_id, loop_idx, is_contour)) { - fuzzified_regions.emplace_back(region.first, region.second); - } - } - if (fuzzified_regions.empty()) { + // Merge regions that produce identical fuzzy effects (differ only in type). + // When the style (e.g. External) and a painted region (All) both fuzzify this loop + // with the same noise parameters, merging their ExPolygons avoids splitting the + // perimeter at the painted boundary — eliminating discontinuity artifacts. + auto merged_regions = collect_merged_fuzzy_regions(regions, perimeter_generator.layer_id, loop_idx, is_contour); + if (merged_regions.empty()) { return polygon; } + // Fast path: single merged region — apply directly without splitting + if (merged_regions.size() == 1) { + const auto& mr = merged_regions.front(); + if (mr.expolygons.empty()) { + fuzzified = polygon; + fuzzy_polyline(fuzzified.points, true, slice_z, *mr.config); + return fuzzified; + } + // Fall through to split_line with a single region below + } + #ifdef DEBUG_FUZZY { int i = 0; - for (const auto& r : fuzzified_regions) { + for (const auto& r : merged_regions) { BoundingBox bbox = get_extents(perimeter_generator.slices->surfaces); bbox.offset(scale_(1.)); ::Slic3r::SVG svg(debug_out_path("fuzzy_traverse_loops_%d_%d_%d_region_%d.svg", perimeter_generator.layer_id, @@ -274,18 +608,26 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim bbox); svg.draw_outline(perimeter_generator.slices->surfaces); svg.draw_outline(polygon, "green"); - svg.draw(r.second, "red", 0.5); - svg.draw_outline(r.second, "red"); + svg.draw(r.expolygons, "red", 0.5); + svg.draw_outline(r.expolygons, "red"); svg.Close(); i++; } } #endif + // Make each region's ExPolygons exclusive so overlapping regions don't double-fuzz + // the same perimeter section. Later regions in the list take priority over earlier ones + // in overlapping areas (matching modifier precedence order). + for (size_t i = 0; i < merged_regions.size(); ++i) + for (size_t j = i + 1; j < merged_regions.size(); ++j) + if (!merged_regions[i].expolygons.empty() && !merged_regions[j].expolygons.empty()) + merged_regions[i].expolygons = diff_ex(merged_regions[i].expolygons, merged_regions[j].expolygons); + // Split the loops into lines with different config, and fuzzy them separately fuzzified = polygon; - for (const auto& r : fuzzified_regions) { - auto splitted = Algorithm::split_line(fuzzified, r.second, true); + for (const auto& r : merged_regions) { + auto splitted = Algorithm::split_line(fuzzified, r.expolygons, true); if (splitted.empty()) { // No intersection, skip continue; @@ -294,7 +636,7 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim // Fuzzy splitted polygon if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) { // The entire polygon is fuzzified - fuzzy_polyline(fuzzified.points, true, slice_z, r.first); + fuzzy_polyline(fuzzified.points, true, slice_z, *r.config); } else { // Start from a non-clipped junction so wrapped clipped segments do // not need an artificial reconnection across the seam. @@ -311,7 +653,7 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim const auto fuzzy_current_segment = [&segment, &fuzzified, &r, slice_z]() { fuzzified.points.push_back(segment.front()); const auto back = segment.back(); - fuzzy_polyline(segment, false, slice_z, r.first); + fuzzy_polyline(segment, false, slice_z, *r.config); fuzzified.points.insert(fuzzified.points.end(), segment.begin(), segment.end()); fuzzified.points.push_back(back); segment.clear(); @@ -350,20 +692,23 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato if (fuzzify) fuzzy_extrusion_line(extrusion->junctions, slice_z, config); } else { - // Find all affective regions - std::vector> fuzzified_regions; - fuzzified_regions.reserve(regions.size()); - for (const auto& region : regions) { - if (should_fuzzify(region.first, perimeter_generator.layer_id, extrusion->inset_idx, is_contour)) { - fuzzified_regions.emplace_back(region.first, region.second); + // Merge regions that produce identical fuzzy effects (differ only in type). + // When the style (e.g. External) and a painted region (All) both fuzzify this loop + // with the same noise parameters, merging avoids splitting the perimeter at the + // painted boundary — eliminating discontinuity artifacts. + auto merged_regions = collect_merged_fuzzy_regions(regions, perimeter_generator.layer_id, extrusion->inset_idx, is_contour); + if (!merged_regions.empty()) { + + // Fast path: single merged region — apply directly without splitting + if (merged_regions.size() == 1 && merged_regions.front().expolygons.empty()) { + fuzzy_extrusion_line(extrusion->junctions, slice_z, *merged_regions.front().config); + return; } - } - if (!fuzzified_regions.empty()) { - + #ifdef DEBUG_FUZZY { int i = 0; - for (const auto& r : fuzzified_regions) { + for (const auto& r : merged_regions) { BoundingBox bbox = get_extents(perimeter_generator.slices->surfaces); bbox.offset(scale_(1.)); ::Slic3r::SVG svg(debug_out_path("fuzzy_traverse_loops_%d_%d_%d_region_%d.svg", perimeter_generator.layer_id, @@ -380,17 +725,25 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato svg.draw_outline(perimeter_generator.slices->surfaces); svg.draw_outline(extrusion_polygon, "green"); - svg.draw(r.second, "red", 0.5); - svg.draw_outline(r.second, "red"); + svg.draw(r.expolygons, "red", 0.5); + svg.draw_outline(r.expolygons, "red"); svg.Close(); i++; } } #endif + // Make each region's ExPolygons exclusive so overlapping regions don't double-fuzz + // the same perimeter section. Later regions in the list take priority over earlier ones + // in overlapping areas. + for (size_t i = 0; i < merged_regions.size(); ++i) + for (size_t j = i + 1; j < merged_regions.size(); ++j) + if (!merged_regions[i].expolygons.empty() && !merged_regions[j].expolygons.empty()) + merged_regions[i].expolygons = diff_ex(merged_regions[i].expolygons, merged_regions[j].expolygons); + // Split the loops into lines with different config, and fuzzy them separately - for (const auto& r : fuzzified_regions) { - const auto splitted = Algorithm::split_line(*extrusion, r.second, false); + for (const auto& r : merged_regions) { + const auto splitted = Algorithm::split_line(*extrusion, r.expolygons, false); if (splitted.empty()) { // No intersection, skip continue; @@ -399,7 +752,7 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato // Fuzzy splitted extrusion if (std::all_of(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) { return j.clipped; })) { // The entire polygon is fuzzified - fuzzy_extrusion_line(extrusion->junctions, slice_z, r.first); + fuzzy_extrusion_line(extrusion->junctions, slice_z, *r.config); continue; } else { const auto current_ext = extrusion->junctions; @@ -412,7 +765,7 @@ void apply_fuzzy_skin(Arachne::ExtrusionLine* extrusion, const PerimeterGenerato const auto front = segment.front(); const auto back = segment.back(); - fuzzy_extrusion_line(segment, slice_z, r.first, false); + fuzzy_extrusion_line(segment, slice_z, *r.config, false); // Orca: only add non fuzzy point if it's not in the extrusion closing point. if (!extrusion->junctions.empty() && extrusion->junctions.front().p != front.p) { extrusion->junctions.push_back(front); diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 2b1a5d86cf..74e6d14d14 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -1324,12 +1324,12 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: params.density = f->print_object_config->internal_bridge_density.get_abs_value(1.0); params.dont_adjust = true; } - // Orca: Elefant foot compensation for solid layers above bottommost by infill density manipulation. + // Orca: Elephant foot compensation for solid layers above bottommost by infill density manipulation. float elefant_density = f->print_object_config->elefant_foot_layers_density.get_abs_value(1.0); if (!is_approx(elefant_density, 1.0f) && surface_fill.surface.is_solid_infill()) { size_t elefant_layers = f->print_object_config->elefant_foot_compensation_layers.value; if (f->layer_id > 0 && f->layer_id <= elefant_layers) - params.density = elefant_density * (elefant_layers - (f->layer_id - 1)) / elefant_layers; + params.density = 1.0f - (1.0f - elefant_density) * (elefant_layers - (f->layer_id - 1)) / elefant_layers; // Reverse calculation - The higher layer number means the higher density. Counting starts from the second layer. } // make fill f->fill_surface_extrusion(&surface_fill.surface, diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index ee853eea96..228663fb42 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -3050,7 +3050,7 @@ bool FillRectilinear::fill_surface_trapezoidal( FillParams params, const std::initializer_list& sweep_params, Polylines& polylines_out, - int Pattern_type) // 0=grid, 1=triangular + int Pattern_type) // 0=grid, 1=triangular, 2=stars { assert(params.multiline > 1); @@ -3069,9 +3069,9 @@ bool FillRectilinear::fill_surface_trapezoidal( period = coord_t((2.0 * d1 / params.density) * std::sqrt(2.0)); base_angle = rotate_vector.first + M_PI_4; // 45 } else { - // Triangular pattern parameters - period = coord_t(( 2.0 * d1 / params.density) * std::sqrt(3.0)); - base_angle = rotate_vector.first + M_PI_2; //90 + // Triangular-family pattern parameters (triangles / stars) + period = coord_t((2.0 * d1 / params.density) * std::sqrt(3.0)); + base_angle = rotate_vector.first + M_PI_2; // 90 } // Obtain the expolygon and rotate to align with pattern base angle @@ -3257,6 +3257,85 @@ bool FillRectilinear::fill_surface_trapezoidal( break; } + case 2: // Tri-hexagon / FillStars + { + // Pattern parameters + const coord_t hex_height = coord_t(0.5 * std::sqrt(3.0) * period); + const coord_t tri_height = hex_height / 2; + const coord_t d1_half = d1 / 2; + const coord_t chamfer_height = std::sqrt(3.0) * d1_half; + const coord_t d1_half_base = d1_half / std::sqrt(3.0); + const coord_t half_period = period / 2; + const coord_t quarter_period = period / 4; + + bb.merge(align_to_grid(bb.center(), Point(period, tri_height))); + const size_t layer_mod = infill_layer_id % 3; + const double angle = layer_mod * 2.0 * M_PI / 3.0; + + const coord_t half_w = bb.size().x() / 2; + const coord_t half_h = bb.size().y() / 2; + + const coord_t num_periods_x = coord_t(std::ceil(half_w / double(period))); + coord_t num_periods_y = coord_t(std::ceil(half_h / double(hex_height))); + if ((num_periods_y % 2) != 0) + ++num_periods_y; + + const coord_t x_alignment_shift = half_period; + const coord_t y_alignment_shift = (2 * tri_height) / 3; + const coord_t x_min_aligned = -num_periods_x * period - x_alignment_shift; + const coord_t x_max_aligned = num_periods_x * period - x_alignment_shift; + const coord_t y_min_aligned = -num_periods_y * hex_height - y_alignment_shift; + const coord_t y_max_aligned = num_periods_y * hex_height - y_alignment_shift; + + const size_t estimated_rows = (y_max_aligned - y_min_aligned) / hex_height + 2; + const size_t estimated_polylines = (estimated_rows + 1) * 2; + polylines.reserve(estimated_polylines); + + Polyline star_row_normal; + star_row_normal.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 7); + Polyline star_row_mirrored; + star_row_mirrored.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 7); + + for (coord_t x = x_min_aligned; x < x_max_aligned; x += period) { + star_row_normal.points.emplace_back(Point(x, hex_height)); // P0 + star_row_normal.points.emplace_back(Point(x + quarter_period - d1, hex_height)); // P1 + star_row_normal.points.emplace_back(Point(x + quarter_period + d1_half, hex_height - chamfer_height)); // P2 + star_row_normal.points.emplace_back(Point(x + half_period - d1_half_base, tri_height + d1_half)); // P3 + star_row_normal.points.emplace_back(Point(x + half_period + d1_half_base, tri_height + d1_half)); // P4 + star_row_normal.points.emplace_back(Point(x + (period * 3) / 4 - d1_half, hex_height - chamfer_height)); // P5 + star_row_normal.points.emplace_back(Point(x + (period * 3) / 4 + d1, hex_height)); // P6 + } + + star_row_mirrored.points = star_row_normal.points; + for (auto& p : star_row_mirrored.points) + p.y() = hex_height - p.y(); + + size_t pair_idx = 0; + const coord_t global_x_shift = half_period; + const coord_t global_y_shift = tri_height; + auto append_row_with_shift = [&polylines](const Polyline& row_template, coord_t x_shift, coord_t y_shift) { + Polyline row = row_template; + for (Point& p : row.points) { + p.x() += x_shift; + p.y() += y_shift; + } + if (!row.points.empty()) + polylines.emplace_back(std::move(row)); + }; + + for (coord_t y = y_min_aligned; y < y_max_aligned; y += hex_height, ++pair_idx) { + const coord_t x_shift = (pair_idx % 2 == 0) ? 0 : half_period; + append_row_with_shift(star_row_normal, x_shift + global_x_shift, y + global_y_shift); + append_row_with_shift(star_row_mirrored, x_shift + global_x_shift, y + global_y_shift); + } + + if (layer_mod) + for (auto& pl : polylines) + pl.rotate(angle, Point(0, 0)); + + break; + } + default: // Handle unknown pattern type break; @@ -3408,11 +3487,19 @@ Polylines FillTriangles::fill_surface(const Surface *surface, const FillParams & Polylines FillStars::fill_surface(const Surface *surface, const FillParams ¶ms) { Polylines polylines_out; - if (! this->fill_surface_by_multilines( - surface, params, - { { 0.f, 0.f }, { float(M_PI / 3.), 0.f }, { float(2. * M_PI / 3.), float((3./2.) * this->spacing * params.multiline / params.density) } }, - polylines_out)) - BOOST_LOG_TRIVIAL(error) << "FillStars::fill_surface() failed to fill a region."; + if (params.multiline > 1) { + if (!this->fill_surface_trapezoidal( + surface, params, + {{0.f, 0.f}, {float(M_PI / 3.), 0.f}, {float(2. * M_PI / 3.), float((3. / 2.) * this->spacing * params.multiline / params.density)}}, + polylines_out, 2)) + BOOST_LOG_TRIVIAL(error) << "FillStars::fill_surface_trapezoidal() failed."; + } else { + if (! this->fill_surface_by_multilines( + surface, params, + { { 0.f, 0.f }, { float(M_PI / 3.), 0.f }, { float(2. * M_PI / 3.), float((3./2.) * this->spacing * params.multiline / params.density) } }, + polylines_out)) + BOOST_LOG_TRIVIAL(error) << "FillStars::fill_surface() failed to fill a region."; + } return polylines_out; } diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f6bb0ce8e3..9eca850e8d 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2456,6 +2456,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_max_layer_z = 0.f; m_last_width = 0.f; m_is_role_based_fan_on.fill(false); + m_role_based_fan_marker_layer.fill(-1); m_fan_mover.release(); @@ -6397,7 +6398,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += this->travel_to(first_point, path.role(), "move to first " + description + " point", z); - m_need_change_layer_lift_z = false; // Orca: ensure Z matches planned layer height if (!slope_need_z_travel && (_last_pos_undefined || m_need_change_layer_lift_z)) { const std::string z_sync_comment = _last_pos_undefined ? @@ -6912,11 +6912,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, assert(m_enable_cooling_markers); if (fan_on) { - if (!m_is_role_based_fan_on[role]) { + // Orca: CoolingBuffer consumes role fan markers per layer, so continuing + // role-based fan regions need a fresh START marker on each new layer. + if (!m_is_role_based_fan_on[role] || m_role_based_fan_marker_layer[role] != m_layer_index) { gcode += ";"; gcode += marker_prefix; gcode += "_FAN_START\n"; m_is_role_based_fan_on[role] = true; + m_role_based_fan_marker_layer[role] = m_layer_index; } } else { if (m_is_role_based_fan_on[role]) { @@ -6924,6 +6927,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += marker_prefix; gcode += "_FAN_END\n"; m_is_role_based_fan_on[role] = false; + m_role_based_fan_marker_layer[role] = -1; } } }; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index a86ee98af3..3e84e5e28b 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -559,6 +559,7 @@ private: std::string _encode_label_ids_to_base64(std::vector ids); // ORCA: Add support for role based fan speed control std::array m_is_role_based_fan_on; + std::array m_role_based_fan_marker_layer; // Markers for the Pressure Equalizer to recognize the extrusion type. // The Pressure Equalizer removes the markers from the final G-code. bool m_enable_extrusion_role_markers; diff --git a/src/libslic3r/GCode/SpiralVase.cpp b/src/libslic3r/GCode/SpiralVase.cpp index 6e7f37afc1..2c39bda4f7 100644 --- a/src/libslic3r/GCode/SpiralVase.cpp +++ b/src/libslic3r/GCode/SpiralVase.cpp @@ -124,14 +124,15 @@ std::string SpiralVase::process_layer(const std::string &gcode, bool last_layer) float starting_flowrate = float(m_config.spiral_starting_flow_ratio.value); float finishing_flowrate = float(m_config.spiral_finishing_flow_ratio.value); + const float min_segment_length = std::max(float(EPSILON), 2 * float(m_config.resolution.value)); float len = 0.f; SpiralVase::SpiralPoint last_point = previous_layer != NULL && previous_layer->size() >0? previous_layer->at(previous_layer->size()-1): SpiralVase::SpiralPoint(0,0); - m_reader.parse_buffer(gcode, [&new_gcode, &z, total_layer_length, layer_height, transition_in, &len, ¤t_layer, &previous_layer, &transition_gcode, transition_out, smooth_spiral, &max_xy_dist_for_smoothing, &last_point, starting_flowrate, finishing_flowrate] + m_reader.parse_buffer(gcode, [&new_gcode, &z, total_layer_length, layer_height, transition_in, &len, ¤t_layer, &previous_layer, &transition_gcode, transition_out, smooth_spiral, &max_xy_dist_for_smoothing, &last_point, starting_flowrate, finishing_flowrate, min_segment_length] (GCodeReader &reader, GCodeReader::GCodeLine line) { if (line.cmd_is("G1")) { // Orca: Filter out retractions at layer change - if (line.retracting(reader) || (line.extruding(reader) && line.dist_XY(reader) < EPSILON)) return; + if (line.retracting(reader) || (line.extruding(reader) && line.dist_XY(reader) < min_segment_length)) return; if (line.has_z() && !(line.has_x() || line.has_y())) { // If this is the initial Z move of the layer, replace it with a // (redundant) move to the last Z of previous layer. @@ -175,7 +176,7 @@ std::string SpiralVase::process_layer(const std::string &gcode, bool last_layer) // Remove tiny movement // We need to figure out the distance of this new line! float modified_dist_XY = SpiralVaseHelpers::distance(last_point, target); - if (modified_dist_XY < 0.001) + if (modified_dist_XY < min_segment_length) line.clear(); else { line.set(X, target.x); diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 20ca550606..993321af60 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -523,9 +523,20 @@ std::string GCodeWriter::update_progress(unsigned int num, unsigned int tot, boo std::string GCodeWriter::toolchange_prefix() const { - return config.manual_filament_change ? ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Manual_Tool_Change) + "T": - FLAVOR_IS(gcfMakerWare) ? "M135 T" : - FLAVOR_IS(gcfSailfish) ? "M108 T" : "T"; + std::string gcode = "T"; + if (config.manual_filament_change) + gcode = ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Manual_Tool_Change) + "T"; + else { + if (m_is_bbl_printers) + gcode = "M1020 S"; + else { + if (FLAVOR_IS(gcfMakerWare)) + gcode = "M135 T"; + else if (FLAVOR_IS(gcfSailfish)) + gcode = "M108 T"; + } + } + return gcode; } std::string GCodeWriter::toolchange(unsigned int filament_id) @@ -540,12 +551,8 @@ std::string GCodeWriter::toolchange(unsigned int filament_id) // if we are running a single-extruder setup, just set the extruder and return nothing std::ostringstream gcode; if (this->multiple_extruders || (this->config.filament_diameter.values.size() > 1 && !is_bbl_printers())) { - // BBS - if (this->m_is_bbl_printers) - gcode << "M1020 S" << filament_id; - else - gcode << this->toolchange_prefix() << filament_id; - //BBS + // Orca: call toolchange_prefix() to get the correct command prefix based on the configuration and flavor. + gcode << this->toolchange_prefix() << filament_id; if (GCodeWriter::full_gcode_comment) gcode << " ; change extruder"; gcode << "\n"; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 16a9efe812..67959a508a 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -250,6 +250,23 @@ void Layer::make_perimeters() //BBS: Separate fill_no_overlap (*l)->fill_no_overlap_expolygons = intersection_ex((*l)->slices.surfaces, fill_no_overlap); } + + // When counterbore hole bridging (chbFilled) is active, process_no_bridge may + // create fill surfaces that extend beyond all region slices (e.g. by clearing + // holes in the bridge expolygon). These "extra" fills are lost during the + // intersection-based splitting above. Recover them and assign to the first + // merged region so the sacrificial bridge layer is not broken. + if (layerm_config->region().config().counterbore_hole_bridging.value != chbNone) { + Polygons all_region_slices_p; + for (LayerRegion *l : layerms) + polygons_append(all_region_slices_p, to_polygons(l->slices.surfaces)); + ExPolygons extra_fill = diff_ex(fill_surfaces.surfaces, all_region_slices_p, ApplySafetyOffset::Yes); + if (!extra_fill.empty()) { + append(layerms.front()->fill_expolygons, extra_fill); + layerms.front()->fill_expolygons = union_ex(layerms.front()->fill_expolygons); + layerms.front()->fill_surfaces.append(std::move(extra_fill), fill_surfaces.surfaces.front()); + } + } } } } diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp index 74be04294e..9ccf8c4d8c 100644 --- a/src/libslic3r/PerimeterGenerator.hpp +++ b/src/libslic3r/PerimeterGenerator.hpp @@ -21,6 +21,10 @@ struct FuzzySkinConfig int noise_octaves; double noise_persistence; FuzzySkinMode mode; + int ripples_per_layer; + double ripple_offset; + int layers_between_ripple_offset; + int layer_id; bool operator==(const FuzzySkinConfig& r) const { @@ -32,7 +36,10 @@ struct FuzzySkinConfig && noise_scale == r.noise_scale && noise_octaves == r.noise_octaves && noise_persistence == r.noise_persistence - && mode == r.mode; + && mode == r.mode + && ripples_per_layer == r.ripples_per_layer + && ripple_offset == r.ripple_offset + && layers_between_ripple_offset == r.layers_between_ripple_offset; } bool operator!=(const FuzzySkinConfig& r) const { return !(*this == r); } @@ -52,6 +59,10 @@ template<> struct hash boost::hash_combine(seed, std::hash{}(c.noise_scale)); boost::hash_combine(seed, std::hash{}(c.noise_octaves)); boost::hash_combine(seed, std::hash{}(c.noise_persistence)); + boost::hash_combine(seed, std::hash{}(c.mode)); + boost::hash_combine(seed, std::hash{}(c.ripples_per_layer)); + boost::hash_combine(seed, std::hash{}(c.ripple_offset)); + boost::hash_combine(seed, std::hash{}(c.layers_between_ripple_offset)); return seed; } }; @@ -92,7 +103,8 @@ public: bool has_fuzzy_skin = false; bool has_fuzzy_hole = false; - std::unordered_map regions_by_fuzzify; + // Preserve construction order so overlap precedence remains deterministic. + std::vector> regions_by_fuzzify; PerimeterGenerator( // Input: diff --git a/src/libslic3r/Polygon.cpp b/src/libslic3r/Polygon.cpp index 9ecc2630d4..32b4d062f1 100644 --- a/src/libslic3r/Polygon.cpp +++ b/src/libslic3r/Polygon.cpp @@ -38,6 +38,9 @@ Polyline Polygon::split_at_vertex(const Point &point) const Polyline Polygon::split_at_index(int index) const { Polyline polyline; + if (this->points.empty()) + return polyline; + polyline.points.reserve(this->points.size() + 1); for (Points::const_iterator it = this->points.begin() + index; it != this->points.end(); ++it) polyline.points.push_back(*it); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index c0b7a06d20..a9e9e1e305 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1049,7 +1049,7 @@ static std::vector s_Preset_print_options{ "support_ironing_flow", "support_ironing_spacing", "max_travel_detour_distance", - "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", "fuzzy_skin_noise_type", "fuzzy_skin_mode", "fuzzy_skin_scale", "fuzzy_skin_octaves", "fuzzy_skin_persistence", + "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", "fuzzy_skin_noise_type", "fuzzy_skin_mode", "fuzzy_skin_scale", "fuzzy_skin_octaves", "fuzzy_skin_persistence", "fuzzy_skin_ripples_per_layer", "fuzzy_skin_ripple_offset", "fuzzy_skin_layers_between_ripple_offset", "max_volumetric_extrusion_rate_slope", "max_volumetric_extrusion_rate_slope_segment_length","extrusion_rate_smoothing_external_perimeter_only", "inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed", "top_surface_speed", "support_speed", "support_object_xy_distance", "support_object_first_layer_gap", "support_interface_speed", diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 7b75d14cf1..740db92f15 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -4557,6 +4557,7 @@ std::pair PresetBundle::load_vendor_configs_ std::string version_str = it.value(); auto config_version = Semver::parse(version_str); if (! config_version) { + ++m_errors; throw ConfigurationError((boost::format("vendor %1%'s config version: %2% invalid\nSuggest cleaning the directory %3% firstly") % vendor_name % version_str % path).str()); } else { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 65a7ed6207..35d7a25258 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1045,29 +1045,61 @@ static StringObjectException layered_print_cleareance_valid(const Print &print, return {}; } -FilamentCompatibilityType Print::check_multi_filaments_compatibility(const std::vector& filament_types) +FilamentCompatibilityType Print::check_multi_filaments_compatibility( + const std::vector& filament_types, + const std::vector& nozzle_temperatures, + const std::vector& nozzle_temperature_range_lows, + const std::vector& nozzle_temperature_range_highs) { - bool has_high_temperature_filament = false; - bool has_low_temperature_filament = false; - bool has_mid_temperature_filament = false; + const size_t filament_count = filament_types.size(); + if (filament_count < 2) + return FilamentCompatibilityType::Compatible; - for (const auto& type : filament_types) { - if (get_filament_temp_type(type) ==FilamentTempType::HighTemp) - has_high_temperature_filament = true; - else if (get_filament_temp_type(type) == FilamentTempType::LowTemp) - has_low_temperature_filament = true; - else if (get_filament_temp_type(type) == FilamentTempType::HighLowCompatible) - has_mid_temperature_filament = true; + std::vector resolved_temperatures(filament_count, 0); + std::vector resolved_range_lows(filament_count, 0); + std::vector resolved_range_highs(filament_count, 0); + for (size_t i = 0; i < filament_count; ++i) { + int range_low = (i < nozzle_temperature_range_lows.size()) ? nozzle_temperature_range_lows[i] : 0; + int range_high = (i < nozzle_temperature_range_highs.size()) ? nozzle_temperature_range_highs[i] : 0; + + if (range_low == 0 || range_high == 0) { + int default_low = range_low; + int default_high = range_high; + MaterialType::get_temperature_range(filament_types[i], default_low, default_high); + if (range_low == 0) + range_low = default_low; + if (range_high == 0) + range_high = default_high; + } + + if (range_low >= range_high) + return FilamentCompatibilityType::InvalidTemperatureRange; + + int print_temperature = (i < nozzle_temperatures.size()) ? nozzle_temperatures[i] : 0; + + resolved_temperatures[i] = print_temperature; + resolved_range_lows[i] = range_low; + resolved_range_highs[i] = range_high; } - if (has_high_temperature_filament && has_low_temperature_filament) - return FilamentCompatibilityType::HighLowMixed; - else if (has_high_temperature_filament && has_mid_temperature_filament) - return FilamentCompatibilityType::HighMidMixed; - else if (has_low_temperature_filament && has_mid_temperature_filament) - return FilamentCompatibilityType::LowMidMixed; - else - return FilamentCompatibilityType::Compatible; + for (size_t i = 0; i < filament_count; ++i) { + for (size_t j = i + 1; j < filament_count; ++j) { + const bool i_temp_is_compatible_with_j = + resolved_temperatures[i] >= resolved_range_lows[j] && + resolved_temperatures[i] <= resolved_range_highs[j]; + const bool j_temp_is_compatible_with_i = + resolved_temperatures[j] >= resolved_range_lows[i] && + resolved_temperatures[j] <= resolved_range_highs[i]; + + if (i_temp_is_compatible_with_j && j_temp_is_compatible_with_i) + continue; + + // Range-only rule: any pair outside mutual recommended ranges is incompatible. + return FilamentCompatibilityType::HighLowMixed; + } + } + + return FilamentCompatibilityType::Compatible; } bool Print::is_filaments_compatible(const std::vector& filament_types) @@ -1112,18 +1144,21 @@ int Print::get_compatible_filament_type(const std::set& filament_types) StringObjectException Print::check_multi_filament_valid(const Print& print) { auto print_config = print.config(); + const std::string incompatible_temp_msg = L("Selected nozzle temperatures are incompatible. Each filament's nozzle temperature must fall within the recommended nozzle temperature range of the other filaments. Otherwise, nozzle clogging or printer damage may occur."); + const std::string invalid_temp_range_msg = L("Invalid recommended nozzle temperature range. The lower bound must be lower than the upper bound."); + const std::string incompatible_temp_msg_preferences_enable = L("If you still want to print, you can enable the option in Preferences / Control / Slicing / Remove mixed temperature restriction."); if(print_config.print_sequence == PrintSequence::ByObject) {// use ByObject valid under ByObject print sequence - std::set Compatibility_each_obj; + bool has_incompatible_object = false; bool enable_mix_printing = !print.need_check_multi_filaments_compatibility(); + StringObjectException ret; for (const auto &objectID_t : print.print_object_ids()) { std::set obj_used_extruder_ids; auto print_object = print.get_object(objectID_t);// current object if (print_object){ auto object_extruders_t = print_object->object_extruders(); // object used extruder - for (int extruder : object_extruders_t) { - assert(extruder > 0); - obj_used_extruder_ids.insert(extruder); + for (unsigned int extruder : object_extruders_t) { + obj_used_extruder_ids.insert(static_cast(extruder)); } } @@ -1137,57 +1172,83 @@ StringObjectException Print::check_multi_filament_valid(const Print& print) obj_used_extruder_ids.insert((unsigned int) print_object->config().support_interface_filament - 1); } std::vector filament_types; + std::vector nozzle_temperatures; + std::vector nozzle_temperature_range_lows; + std::vector nozzle_temperature_range_highs; filament_types.reserve(obj_used_extruder_ids.size()); - for (const auto &extruder_idx : obj_used_extruder_ids) filament_types.push_back(print_config.filament_type.get_at(extruder_idx)); + nozzle_temperatures.reserve(obj_used_extruder_ids.size()); + nozzle_temperature_range_lows.reserve(obj_used_extruder_ids.size()); + nozzle_temperature_range_highs.reserve(obj_used_extruder_ids.size()); - auto compatibility = check_multi_filaments_compatibility(filament_types);// check for each object - Compatibility_each_obj.insert(compatibility); + for (const auto &extruder_idx : obj_used_extruder_ids) { + filament_types.push_back(print_config.filament_type.get_at(extruder_idx)); + nozzle_temperatures.push_back(print_config.nozzle_temperature.get_at(extruder_idx)); + nozzle_temperature_range_lows.push_back(print_config.nozzle_temperature_range_low.get_at(extruder_idx)); + nozzle_temperature_range_highs.push_back(print_config.nozzle_temperature_range_high.get_at(extruder_idx)); + } + + auto compatibility = check_multi_filaments_compatibility( + filament_types, + nozzle_temperatures, + nozzle_temperature_range_lows, + nozzle_temperature_range_highs); // check for each object + if (compatibility == FilamentCompatibilityType::InvalidTemperatureRange) { + ret.string = invalid_temp_range_msg; + return ret; + } + if (compatibility != FilamentCompatibilityType::Compatible) { + has_incompatible_object = true; + break; + } } - StringObjectException ret; - std::string hypertext = "filament_mix_print"; - if (Compatibility_each_obj.count(FilamentCompatibilityType::HighLowMixed)){// at least one object has HighLowMixed + if (has_incompatible_object){ if (enable_mix_printing) { - ret.string = L("Printing high-temp and low-temp filaments together may cause nozzle clogging or printer damage."); + ret.string = incompatible_temp_msg; ret.is_warning = true; - // ret.hypetext = hypertext; } else - ret.string = L("Printing high-temp and low-temp filaments together may cause nozzle clogging or printer damage. If you still want to print, you can enable the option in Preferences."); - }else if (Compatibility_each_obj.count(FilamentCompatibilityType::LowMidMixed) || Compatibility_each_obj.count(FilamentCompatibilityType::HighMidMixed)){// at least one object has other Mixed - ret.is_warning = true; - // ret.hypetext = hypertext; - ret.string = L("Printing different-temp filaments together may cause nozzle clogging or printer damage."); + ret.string = incompatible_temp_msg + " " + incompatible_temp_msg_preferences_enable; } return ret; } std::vector extruders = print.extruders(); std::vector filament_types; + std::vector nozzle_temperatures; + std::vector nozzle_temperature_range_lows; + std::vector nozzle_temperature_range_highs; filament_types.reserve(extruders.size()); - for (const auto& extruder_idx : extruders) + nozzle_temperatures.reserve(extruders.size()); + nozzle_temperature_range_lows.reserve(extruders.size()); + nozzle_temperature_range_highs.reserve(extruders.size()); + for (const auto& extruder_idx : extruders) { filament_types.push_back(print_config.filament_type.get_at(extruder_idx)); + nozzle_temperatures.push_back(print_config.nozzle_temperature.get_at(extruder_idx)); + nozzle_temperature_range_lows.push_back(print_config.nozzle_temperature_range_low.get_at(extruder_idx)); + nozzle_temperature_range_highs.push_back(print_config.nozzle_temperature_range_high.get_at(extruder_idx)); + } - auto compatibility = check_multi_filaments_compatibility(filament_types); + auto compatibility = check_multi_filaments_compatibility( + filament_types, + nozzle_temperatures, + nozzle_temperature_range_lows, + nozzle_temperature_range_highs); bool enable_mix_printing = !print.need_check_multi_filaments_compatibility(); StringObjectException ret; - if(compatibility == FilamentCompatibilityType::HighLowMixed){ + if (compatibility == FilamentCompatibilityType::InvalidTemperatureRange) { + ret.string = invalid_temp_range_msg; + return ret; + } + + if(compatibility != FilamentCompatibilityType::Compatible){ if(enable_mix_printing){ - ret.string =L("Printing high-temp and low-temp filaments together may cause nozzle clogging or printer damage."); + ret.string = incompatible_temp_msg; ret.is_warning = true; } else{ - ret.string =L("Printing high-temp and low-temp filaments together may cause nozzle clogging or printer damage. If you still want to print, you can enable the option in Preferences."); + ret.string = incompatible_temp_msg + " " + incompatible_temp_msg_preferences_enable; } } - else if (compatibility == FilamentCompatibilityType::HighMidMixed) { - ret.is_warning = true; - ret.string =L("Printing high-temp and mid-temp filaments together may cause nozzle clogging or printer damage."); - - } - else if (compatibility == FilamentCompatibilityType::LowMidMixed) { - ret.is_warning = true; - ret.string = L("Printing mid-temp and low-temp filaments together may cause nozzle clogging or printer damage."); - } return ret; } @@ -2831,43 +2892,7 @@ Vec2d Print::translate_to_print_space(const Point &point) const { FilamentTempType Print::get_filament_temp_type(const std::string& filament_type) { - const static std::string HighTempFilamentStr = "high_temp_filament"; - const static std::string LowTempFilamentStr = "low_temp_filament"; - const static std::string HighLowCompatibleFilamentStr = "high_low_compatible_filament"; - static std::unordered_map>filament_temp_type_map; - - if (filament_temp_type_map.empty()) { - fs::path file_path = fs::path(resources_dir()) / "info" / "filament_info.json"; - std::ifstream in(file_path.string()); - json j; - try{ - j = json::parse(in); - in.close(); - auto&&high_temp_filament_arr =j[HighTempFilamentStr].get < std::vector>(); - filament_temp_type_map[HighTempFilamentStr] = std::unordered_set(high_temp_filament_arr.begin(), high_temp_filament_arr.end()); - auto&& low_temp_filament_arr = j[LowTempFilamentStr].get < std::vector>(); - filament_temp_type_map[LowTempFilamentStr] = std::unordered_set(low_temp_filament_arr.begin(), low_temp_filament_arr.end()); - auto&& high_low_compatible_filament_arr = j[HighLowCompatibleFilamentStr].get < std::vector>(); - filament_temp_type_map[HighLowCompatibleFilamentStr] = std::unordered_set(high_low_compatible_filament_arr.begin(), high_low_compatible_filament_arr.end()); - } - catch (const json::parse_error& err){ - in.close(); - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << file_path.string() << " got a nlohmann::detail::parse_error, reason = " << err.what(); - filament_temp_type_map[HighTempFilamentStr] = {"ABS","ASA","PC","PA","PA-CF","PA-GF","PA6-CF","PET-CF", "PETG-GF","PPS","PPS-CF","PPA-GF","PPA-CF","ABS-Aero","ABS-GF"}; - filament_temp_type_map[LowTempFilamentStr] = {"PLA","TPU","PLA-CF","PLA-AERO","PVA","BVOH","SBS"}; - filament_temp_type_map[HighLowCompatibleFilamentStr] = { "HIPS","PETG","PCTG","PE","PP","EVA","PE-CF","PP-CF","PP-GF","PHA"}; - } - } - - if (filament_temp_type_map[HighLowCompatibleFilamentStr].find(filament_type) != filament_temp_type_map[HighLowCompatibleFilamentStr].end()) - return HighLowCompatible; - if (filament_temp_type_map[HighTempFilamentStr].find(filament_type) != filament_temp_type_map[HighTempFilamentStr].end()) - return HighTemp; - if (filament_temp_type_map[LowTempFilamentStr].find(filament_type) != filament_temp_type_map[LowTempFilamentStr].end()) - return LowTemp; - - // Orca: prefer explicit definition from JSON, if the filament type is not defined in json, fallback to temperature-based logic to determine the filament temp type. - // FilamentTempType Temperature-based logic + // Range-based classification only: do not use filament_info.json. int min_temp, max_temp; if (MaterialType::get_temperature_range(filament_type, min_temp, max_temp)) { if (max_temp <= 250) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index eeb74a87ed..9206f2a390 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -877,8 +877,9 @@ enum FilamentTempType { enum FilamentCompatibilityType { Compatible, HighLowMixed, - HighMidMixed, - LowMidMixed + //HighLowMixed, + //HighMidMixed, + InvalidTemperatureRange }; // The complete print tray with possibly multiple objects. @@ -905,7 +906,7 @@ public: // List of existing PrintObject IDs, to remove notifications for non-existent IDs. std::vector print_object_ids() const override; - ApplyStatus apply(const Model &model, DynamicPrintConfig config) override; + ApplyStatus apply(const Model &model, DynamicPrintConfig config, bool extruder_applied = false) override; void process(long long *time_cost_with_cache = nullptr, bool use_cache = false) override; // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. @@ -1087,7 +1088,11 @@ public: static FilamentTempType get_filament_temp_type(const std::string& filament_type); static int get_hrc_by_nozzle_type(const NozzleType& type); static std::vector get_incompatible_filaments_by_nozzle(const float nozzle_diameter, const std::optional nozzle_volume_type = std::nullopt); - static FilamentCompatibilityType check_multi_filaments_compatibility(const std::vector& filament_types); + static FilamentCompatibilityType check_multi_filaments_compatibility( + const std::vector& filament_types, + const std::vector& nozzle_temperatures, + const std::vector& nozzle_temperature_range_lows, + const std::vector& nozzle_temperature_range_highs); // similar to check_multi_filaments_compatibility, but the input is int, and may be negative (means unset) static bool is_filaments_compatible(const std::vector& types); // get the compatible filament type of a multi-material object diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index dfe85dfd83..789076a43e 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1105,7 +1105,7 @@ static PrintObjectRegions* generate_print_object_regions( return out.release(); } -Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_config) +Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_config, bool extruder_applied) { #ifdef _DEBUG check_model_ids_validity(model); @@ -1157,10 +1157,24 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ } //apply extruder related values - new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); - new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); - //update print config related with variants - new_full_config.update_values_to_printer_extruders(new_full_config, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + if (!extruder_applied) { + new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); + new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); + //update print config related with variants + new_full_config.update_values_to_printer_extruders(new_full_config, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + + m_ori_full_print_config = new_full_config; + new_full_config.update_values_to_printer_extruders_for_multiple_filaments(new_full_config, filament_options_with_variant, "filament_self_index", "filament_extruder_variant"); + } + // else { + // int extruder_count; + // bool different_extruder = new_full_config.support_different_extruders(extruder_count); + // print_variant_index.resize(extruder_count); + // for (int e_index = 0; e_index < extruder_count; e_index++) + // { + // print_variant_index[e_index] = e_index; + // } + // } // Derive physical_extruder_map (0-indexed) from printer_extruder_id (1-indexed) when the // map hasn't been explicitly configured in the printer profile (size <= 1 = default). diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 21092ff257..4158c23065 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -407,7 +407,7 @@ public: // Some data was changed, which in turn invalidated already calculated steps. APPLY_STATUS_INVALIDATED, }; - virtual ApplyStatus apply(const Model &model, DynamicPrintConfig config) = 0; + virtual ApplyStatus apply(const Model &model, DynamicPrintConfig config, bool extruder_applied = false) = 0; const Model& model() const { return m_model; } struct TaskParams { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index faabf3fd73..f57b5e75ea 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -172,6 +172,7 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PowerLossRecoveryMode) static t_config_enum_values s_keys_map_FuzzySkinType { { "none", int(FuzzySkinType::None) }, { "external", int(FuzzySkinType::External) }, + { "hole", int(FuzzySkinType::Hole) }, { "all", int(FuzzySkinType::All) }, { "allwalls", int(FuzzySkinType::AllWalls)}, { "disabled_fuzzy", int(FuzzySkinType::Disabled_fuzzy)} @@ -183,7 +184,8 @@ static t_config_enum_values s_keys_map_NoiseType { { "perlin", int(NoiseType::Perlin) }, { "billow", int(NoiseType::Billow) }, { "ridgedmulti", int(NoiseType::RidgedMulti) }, - { "voronoi", int(NoiseType::Voronoi) } + { "voronoi", int(NoiseType::Voronoi) }, + { "ripple", int(NoiseType::Ripple) } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NoiseType) @@ -715,11 +717,11 @@ void PrintConfigDef::init_common_params() def->set_default_value(new ConfigOptionInt(1)); def = this->add("elefant_foot_layers_density", coPercent); - def->label = L("Elefant foot layers density"); + def->label = L("Elephant foot layers density"); def->category = L("Quality"); - def->tooltip = L("Density of internal solid infill for elefant foot layers compensation. " - "The initial value for the second layer is set. " - "Subsequent layers become linearly denser by the height specified in elefant_foot_compensation_layers. "); + def->tooltip = L("Density of internal solid infill for Elephant foot layers compensation.\n" + "The initial value for the second layer is set.\n" + "Subsequent layers become linearly denser by the height specified in elefant_foot_compensation_layers."); def->sidetext = "%"; def->min = 50; def->max = 100; @@ -2210,6 +2212,7 @@ void PrintConfigDef::init_fff_params() "This setting changes all extrusion flow of this filament in G-code proportionally. " "The recommended value range is between 0.95 and 1.05. " "You may be able to tune this value to get a nice flat surface if there is slight overflow or underflow."); + def->min = 0; def->max = 2; def->mode = comAdvanced; def->nullable = true; @@ -3371,11 +3374,13 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("none"); def->enum_values.push_back("external"); + def->enum_values.push_back("hole"); def->enum_values.push_back("all"); def->enum_values.push_back("allwalls"); def->enum_values.push_back("disabled_fuzzy"); def->enum_labels.push_back(L("Painted only")); def->enum_labels.push_back(L("Contour")); + def->enum_labels.push_back(L("Hole")); def->enum_labels.push_back(L("Contour and hole")); def->enum_labels.push_back(L("All walls")); def->enum_labels.push_back(L("Disabled")); @@ -3388,7 +3393,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("The width within which to jitter. It's advised to be below outer wall line width."); def->sidetext = L("mm"); // millimeters, CIS languages need translation def->min = 0; - def->max = 1; + def->max = 2; def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(0.2)); @@ -3440,18 +3445,21 @@ void PrintConfigDef::init_fff_params() "Perlin: Perlin noise, which gives a more consistent texture.\n" "Billow: Similar to perlin noise, but clumpier.\n" "Ridged Multifractal: Ridged noise with sharp, jagged features. Creates marble-like textures.\n" - "Voronoi: Divides the surface into voronoi cells, and displaces each one by a random amount. Creates a patchwork texture."); + "Voronoi: Divides the surface into voronoi cells, and displaces each one by a random amount. Creates a patchwork texture.\n" + "Ripple: Uniform ripple pattern that ripples left and right of the original path. Repeating pattern, woven appearance."); def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("classic"); def->enum_values.push_back("perlin"); def->enum_values.push_back("billow"); def->enum_values.push_back("ridgedmulti"); def->enum_values.push_back("voronoi"); + def->enum_values.push_back("ripple"); def->enum_labels.push_back(L("Classic")); def->enum_labels.push_back(L("Perlin")); def->enum_labels.push_back(L("Billow")); def->enum_labels.push_back(L("Ridged Multifractal")); def->enum_labels.push_back(L("Voronoi")); + def->enum_labels.push_back(L("Ripple")); def->mode = comSimple; def->set_default_value(new ConfigOptionEnum(NoiseType::Classic)); @@ -3483,6 +3491,39 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.5)); + def = this->add("fuzzy_skin_ripples_per_layer", coInt); + def->label = L("Number of ripples per layer"); + def->category = L("Others"); + def->tooltip = L("Controls how many full cycles of ripples will be added per layer."); + def->min = 1; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionInt(15)); + + def = this->add("fuzzy_skin_ripple_offset", coPercent); + def->label = L("Ripple offset"); + def->category = L("Others"); + def->tooltip = L("Shifts the ripple phase forward along the print path by the specified percentage of a wavelength each layer period.\n" + "- 0% keeps every layer identical.\n" + "- 50% shifts the pattern by half a wavelength, effectively inverting the phase.\n" + "- 100% shifts the pattern by a full wavelength, returning to the original phase.\n\n" + "The shift is applied once every number of layers set by Layers between ripple offset, so layers within the same group are printed identically."); + def->min = 0; + def->max = 100; + def->sidetext = ("%"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionPercent(50)); + + def = this->add("fuzzy_skin_layers_between_ripple_offset", coInt); + def->label = L("Layers between ripple offset"); + def->category = L("Others"); + def->tooltip = L("Specifies how many consecutive layers share the same ripple phase before the offset is applied.\n" + "For example:\n" + "- 1 = Layer 1 is printed with the base ripple pattern, then layer 2 is shifted by the configured offset, then layer 3 returns to the base pattern, and so on.\n" + "- 3 = Layers 1 to 3 are printed with the base ripple pattern, then layers 4 to 6 are shifted by the configured offset, then layers 7 to 9 return to the base pattern, etc."); + def->min = 1; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionInt(1)); + def = this->add("filter_out_gap_fill", coFloat); def->label = L("Filter out tiny gaps"); def->category = L("Layers and Perimeters"); @@ -4143,15 +4184,16 @@ void PrintConfigDef::init_fff_params() def = this->add("zaa_enabled", coBool); def->label = L("Z contouring enabled"); def->category = L("Quality"); - def->tooltip = L("Enable Z-layer contouring (aka Z-layer anti-aliasing)"); + def->tooltip = L("Enable Z-layer contouring (aka Z-layer anti-aliasing)."); def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); def = this->add("zaa_minimize_perimeter_height", coFloat); def->label = L("Minimize wall height angle"); def->category = L("Quality"); - def->tooltip = L("Reduce height of top surface perimeters to match height of model edge. " - "Effects perimeters whose slope is less than this angle in degrees. Reasonable value is 35. Set 0 to disable."); + def->tooltip = L("Reduce the height of top-surface perimeters to match the model edge height.\n" + "Affects perimeters with a slope less than this angle (degrees).\n" + "A reasonable value is 35. Set to 0 to disable."); def->sidetext = L("°"); def->min = 0; def->max = 90; @@ -4161,14 +4203,15 @@ void PrintConfigDef::init_fff_params() def = this->add("zaa_dont_alternate_fill_direction", coBool); def->label = L("Don't alternate fill direction"); def->category = L("Quality"); - def->tooltip = L("Disable alternating fill direction when using Z contouring"); + def->tooltip = L("Disable alternating fill direction when using Z contouring."); def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); def = this->add("zaa_min_z", coFloat); def->label = L("Minimum z height"); def->category = L("Quality"); - def->tooltip = L("Minimum z layer height. Also controls slicing plane"); + def->tooltip = L("Minimum Z-layer height.\n" + "Also controls the slicing plane."); def->sidetext = L("mm"); def->min = 0; def->max = 100; @@ -5256,7 +5299,8 @@ void PrintConfigDef::init_fff_params() def->label = L("Scarf joint flow ratio"); def->category = L("Quality"); def->tooltip = L("This factor affects the amount of material for scarf joints."); - def->mode = comDevelop; + def->mode = comExpert; + def->min = 0; def->max = 2; def->set_default_value(new ConfigOptionFloat(1)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index a7456c6943..98413679fb 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -39,6 +39,7 @@ enum GCodeFlavor : unsigned char { enum class FuzzySkinType { None, External, + Hole, All, AllWalls, Disabled_fuzzy, @@ -56,6 +57,7 @@ enum class NoiseType { Billow, RidgedMulti, Voronoi, + Ripple, }; enum class WipeTowerType { @@ -1111,6 +1113,9 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, fuzzy_skin_scale)) ((ConfigOptionInt, fuzzy_skin_octaves)) ((ConfigOptionFloat, fuzzy_skin_persistence)) + ((ConfigOptionInt, fuzzy_skin_ripples_per_layer)) + ((ConfigOptionPercent, fuzzy_skin_ripple_offset)) + ((ConfigOptionInt, fuzzy_skin_layers_between_ripple_offset)) ((ConfigOptionFloat, gap_infill_speed)) ((ConfigOptionInt, sparse_infill_filament)) ((ConfigOptionFloatOrPercent, sparse_infill_line_width)) diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index abeb420e00..1e59b44e30 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -48,7 +48,7 @@ LayerPtrs new_layers( } if (zaa_active) { slice_z = lo + z_offset; - if (slice_z < lo || slice_z > hi) { + if ((slice_z < lo && !is_approx(slice_z, lo)) || (slice_z > hi && !is_approx(slice_z, hi))) { throw RuntimeError("Bad min Z value"); } } diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 569d22501e..ca07f8754e 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -184,7 +184,7 @@ std::vector SLAPrint::print_object_ids() const return out; } -SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig config) +SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig config, bool extruder_applied) { #ifdef _DEBUG check_model_ids_validity(model); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 887942c9cf..a8c49674fc 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -450,7 +450,7 @@ public: bool empty() const override { return m_objects.empty(); } // List of existing PrintObject IDs, to remove notifications for non-existent IDs. std::vector print_object_ids() const override; - ApplyStatus apply(const Model &model, DynamicPrintConfig config) override; + ApplyStatus apply(const Model &model, DynamicPrintConfig config, bool extruder_applied = false) override; void set_task(const TaskParams ¶ms) override; void process(long long *time_cost_with_cache = nullptr, bool use_cache = false) override; void finalize() override; diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 0ec3e5f503..1fb73d4b00 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -114,6 +114,14 @@ void set_logging_level(unsigned int level) { logSeverity = level_to_boost(level); + // Force at debug level logging for pre-release builds. + const std::string version = SoftFever_VERSION; + if (boost::algorithm::icontains(version, "dev") || + boost::algorithm::icontains(version, "alpha") || + boost::algorithm::icontains(version, "beta")) { + logSeverity = boost::log::trivial::debug; + } + boost::log::core::get()->set_filter ( boost::log::trivial::severity >= logSeverity diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp index 66fe521105..cc6db72ff5 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp @@ -1505,6 +1505,9 @@ bool CalibrationPresetPage::is_filaments_compatiable(const std::map filament_types; + std::vector nozzle_temperatures; + std::vector nozzle_temperature_range_lows; + std::vector nozzle_temperature_range_highs; for (auto &item : prests) { const auto& item_preset = item.second; if (!item_preset) @@ -1533,13 +1536,38 @@ bool CalibrationPresetPage::is_filaments_compatiable(const std::mapconfig.get_filament_type(display_filament_type, 0)); + int nozzle_temperature = 0; + int nozzle_temperature_range_low = 0; + int nozzle_temperature_range_high = 0; + if (const auto* opt_nozzle_temp = item_preset->config.option("nozzle_temperature")) + nozzle_temperature = opt_nozzle_temp->get_at(0); + if (const auto* opt_nozzle_temp_low = item_preset->config.option("nozzle_temperature_range_low")) + nozzle_temperature_range_low = opt_nozzle_temp_low->get_at(0); + if (const auto* opt_nozzle_temp_high = item_preset->config.option("nozzle_temperature_range_high")) + nozzle_temperature_range_high = opt_nozzle_temp_high->get_at(0); + + nozzle_temperatures.push_back(nozzle_temperature); + nozzle_temperature_range_lows.push_back(nozzle_temperature_range_low); + nozzle_temperature_range_highs.push_back(nozzle_temperature_range_high); + // check is it in the filament blacklist if (!is_filament_in_blacklist(item.first, item_preset, error_tips)) return false; } - if (Print::check_multi_filaments_compatibility(filament_types) == FilamentCompatibilityType::HighLowMixed) { - error_tips = _u8L("Cannot print multiple filaments which have large difference of temperature together. Otherwise, the extruder and nozzle may be blocked or damaged during printing"); + auto compatibility = Print::check_multi_filaments_compatibility( + filament_types, + nozzle_temperatures, + nozzle_temperature_range_lows, + nozzle_temperature_range_highs); + + if (compatibility == FilamentCompatibilityType::InvalidTemperatureRange) { + error_tips = _u8L("Invalid recommended nozzle temperature range. The lower bound must be lower than the upper bound."); + return false; + } + + if (compatibility == FilamentCompatibilityType::HighLowMixed) { + error_tips = _u8L("Selected nozzle temperatures are incompatible. For multi-material printing, each filament's nozzle temperature must be within the recommended nozzle temperature range of the other filaments. Otherwise, nozzle clogging or printer damage may occur."); return false; } diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 238b6ac690..f3a359f560 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -881,9 +881,13 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co // Show noise type specific options with the same logic NoiseType fuzzy_skin_noise_type = config->opt_enum("fuzzy_skin_noise_type"); - toggle_line("fuzzy_skin_scale", fuzzy_skin_noise_type != NoiseType::Classic && has_fuzzy_skin); - toggle_line("fuzzy_skin_octaves", fuzzy_skin_noise_type != NoiseType::Classic && fuzzy_skin_noise_type != NoiseType::Voronoi && has_fuzzy_skin); - toggle_line("fuzzy_skin_persistence", (fuzzy_skin_noise_type == NoiseType::Perlin || fuzzy_skin_noise_type == NoiseType::Billow) && has_fuzzy_skin); + const bool is_ripple = fuzzy_skin_noise_type == NoiseType::Ripple; + toggle_line("fuzzy_skin_scale", fuzzy_skin_noise_type != NoiseType::Classic && has_fuzzy_skin && !is_ripple); + toggle_line("fuzzy_skin_octaves", fuzzy_skin_noise_type != NoiseType::Classic && fuzzy_skin_noise_type != NoiseType::Voronoi && has_fuzzy_skin && !is_ripple); + toggle_line("fuzzy_skin_persistence", (fuzzy_skin_noise_type == NoiseType::Perlin || fuzzy_skin_noise_type == NoiseType::Billow) && has_fuzzy_skin && !is_ripple); + toggle_line("fuzzy_skin_ripples_per_layer", is_ripple && has_fuzzy_skin); + toggle_line("fuzzy_skin_ripple_offset", is_ripple && has_fuzzy_skin); + toggle_line("fuzzy_skin_layers_between_ripple_offset", is_ripple && has_fuzzy_skin); bool have_arachne = config->opt_enum("wall_generator") == PerimeterGeneratorType::Arachne; for (auto el : {"wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "min_feature_size", "min_length_factor", diff --git a/src/slic3r/GUI/DeviceCore/DevManager.cpp b/src/slic3r/GUI/DeviceCore/DevManager.cpp index 5535f8b696..0e197a236b 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.cpp +++ b/src/slic3r/GUI/DeviceCore/DevManager.cpp @@ -913,12 +913,13 @@ namespace Slic3r } // do some refresh - if (Slic3r::GUI::wxGetApp().is_user_login(Slic3r::GUI::wxGetApp().get_printer_cloud_provider())) + const auto cloud_provider = Slic3r::GUI::wxGetApp().get_printer_cloud_provider(); + if (Slic3r::GUI::wxGetApp().is_user_login(cloud_provider)) { m_manager->check_pushing(); try { - agent->refresh_connection(); + agent->refresh_connection(cloud_provider); } catch (...) { diff --git a/src/slic3r/GUI/DeviceCore/DevManager.h b/src/slic3r/GUI/DeviceCore/DevManager.h index 095d9ea779..087e3312c9 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.h +++ b/src/slic3r/GUI/DeviceCore/DevManager.h @@ -116,7 +116,7 @@ public: class DeviceManagerRefresher : public wxObject { wxTimer* m_timer{ nullptr }; - int m_timer_interval_msec = 1000; + int m_timer_interval_msec = 5000; DeviceManager* m_manager{ nullptr }; diff --git a/src/slic3r/GUI/DeviceCore/DevMapping.cpp b/src/slic3r/GUI/DeviceCore/DevMapping.cpp index e655f12db7..af3539f372 100644 --- a/src/slic3r/GUI/DeviceCore/DevMapping.cpp +++ b/src/slic3r/GUI/DeviceCore/DevMapping.cpp @@ -354,6 +354,27 @@ namespace Slic3r } } + // Orca: special cases that no AMS available, we select ext slot automatically because we don't have other choice anyway + if (tray_filaments.size() == 1 && devPrinterUtil::IsVirtualSlot(tray_filaments.begin()->first)) { + auto ext_tray = tray_filaments.begin(); + for (auto & r : result) { + if (r.tray_id < 0) { + r.tray_id = ext_tray->first; + + r.color = ext_tray->second.color; + r.type = ext_tray->second.type; + r.distance = ext_tray->second.distance; + r.filament_id = ext_tray->second.filament_id; + r.ctype = ext_tray->second.ctype; + r.colors = ext_tray->second.colors; + + /*for new ams mapping*/ + r.ams_id = ext_tray->second.ams_id; + r.slot_id = ext_tray->second.slot_id; + } + } + } + //check ams mapping result if (DevMappingUtil::is_valid_mapping_result(obj, result, true)) { diff --git a/src/slic3r/GUI/DeviceErrorDialog.cpp b/src/slic3r/GUI/DeviceErrorDialog.cpp index ff9fe63dbf..008c99474d 100644 --- a/src/slic3r/GUI/DeviceErrorDialog.cpp +++ b/src/slic3r/GUI/DeviceErrorDialog.cpp @@ -240,7 +240,14 @@ wxString DeviceErrorDialog::show_error_code(int error_code) Show(); Raise(); +#ifndef __linux__ + // On Linux (especially Wayland) RequestUserAttention(wxUSER_ATTENTION_ERROR) maps to + // gtk_window_set_urgency_hint(TRUE) which can leave the window in an urgent-but-unfocused + // state — clicks no longer reach any widget in the app and the user has to kill the + // process to recover. Same root cause as #9874, where SecondaryCheckDialog had its + // RequestUserAttention call removed for the identical reason. this->RequestUserAttention(wxUSER_ATTENTION_ERROR); +#endif return error_msg; } diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 5454c62ca9..99e903dded 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -291,7 +291,6 @@ public: bool is_target_slot_unload() const; bool can_unload_filament(); - bool is_support_amx_ext_mix_mapping() const { return true;} void get_ams_colors(std::vector& ams_colors); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9fa4a2b8c5..61f9cbd90e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -519,13 +519,15 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode } ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 3.f * m_scale); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(.5f, .5f)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(2.f, 2.f) * m_scale); ImGui::PushStyleColor(ImGuiCol_Button , ImVec4(0, 0, 0, 0)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered , ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive , ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); const float main_wnd_height = ImGui::GetWindowHeight(); - if (ImGui::Button(into_u8(properties_shown ? ImGui::UnfoldButtonIcon : ImGui::FoldButtonIcon).c_str(), ImVec2(24.f, 24.f) * m_scale)) { + // ORCA use glyph based button for fixing button sizes changing depends on used font size on platform + const wchar_t foldIcon = properties_shown ? ImGui::UnfoldButtonIcon : ImGui::FoldButtonIcon; + if (imgui.glyph_button(foldIcon, ImVec2(16.f, 16.f) * m_scale)) { properties_shown = !properties_shown; static float main_wnd_height_temp = ImGui::GetWindowHeight(); static float first_click = true; @@ -540,7 +542,8 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode ImGui::SameLine(); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetStyle().FramePadding.y); // aligns button with next group + if(!properties_shown) + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetStyle().FramePadding.y); // aligns button with next group ImGui::BeginGroup(); // group contents to make information area more compact @@ -3631,29 +3634,26 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ImGui::Dummy({ window_padding, window_padding }); ImGui::Dummy({ window_padding, window_padding }); ImGui::SameLine(window_padding * 2); // ORCA Ignores item spacing to get perfect window margins since since this part uses dummies for window padding - std::wstring btn_name; - if (m_fold) - btn_name = ImGui::UnfoldButtonIcon; - else - btn_name = ImGui::FoldButtonIcon; + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); - float calc_padding = (ImGui::GetFrameHeight() - 16 * m_scale) / 2; // ORCA calculated padding for 16x16 icon - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(calc_padding, calc_padding)); // ORCA Center icon with frame padding - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f * m_scale); // ORCA Match button style with combo box + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(2.f, 2.f) * m_scale); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f * m_scale); // ORCA Match button style with combo box - float button_width = 16 * m_scale + calc_padding * 2; // ORCA match buttons height with combo box - if (ImGui::Button(into_u8(btn_name).c_str(), ImVec2(button_width, button_width))) { + // ORCA use glyph based button for fixing button sizes changing depends on used font size on platform + const wchar_t foldIcon = m_fold ? ImGui::UnfoldButtonIcon : ImGui::FoldButtonIcon; + if (imgui.glyph_button(foldIcon, ImVec2(16.f, 16.f) * m_scale)) { m_fold = !m_fold; } ImGui::SameLine(); const wchar_t gCodeToggle = ImGui::gCodeButtonIcon; - if (ImGui::Button(into_u8(gCodeToggle).c_str(), ImVec2(button_width, button_width))) { + if (imgui.glyph_button(gCodeToggle, ImVec2(16.f, 16.f) * m_scale)) { wxGetApp().toggle_show_gcode_window(); wxGetApp().plater()->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); } + ImGui::PopStyleColor(3); ImGui::PopStyleVar(2); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fddffb7e35..469e580427 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1920,6 +1920,14 @@ void GLCanvas3D::render(bool only_init) if (!is_initialized() && !init()) return; + + // If a scene reload was postponed while the canvas was hidden, consume it on first visible render. + if (m_reload_delayed) { + reload_scene(true); + if (m_reload_delayed) + return; + } + if (m_canvas_type == ECanvasType::CanvasView3D && m_gizmos.get_current_type() == GLGizmosManager::Undefined) { enable_return_toolbar(false); } @@ -2406,10 +2414,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (m_canvas == nullptr || m_config == nullptr || m_model == nullptr) return; - if (!m_initialized) + if (!m_initialized || !_set_current()) { + m_reload_delayed = true; + set_as_dirty(); return; - - _set_current(); + } m_hover_volume_idxs.clear(); @@ -2464,6 +2473,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re auto model_volume_state_lower = [](const ModelVolumeState& m1, const ModelVolumeState& m2) { return m1.geometry_id < m2.geometry_id; }; m_reload_delayed = !m_canvas->IsShown() && !refresh_immediately && !force_full_scene_refresh; + if (m_reload_delayed) { + set_as_dirty(); + return; + } PrinterTechnology printer_technology = current_printer_technology(); @@ -2625,9 +2638,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re //BBS clean hover_volume_idxs m_hover_volume_idxs.clear(); - if (m_reload_delayed) - return; - // BBS: do not check wipe tower changes bool update_object_list = false; if (deleted_volumes.size() != deleted_wipe_towers.size()) @@ -3905,7 +3915,7 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) if (m_gizmos.on_mouse_wheel(evt)) return; - if (m_canvas_type == CanvasAssembleView && (evt.AltDown() || evt.CmdDown())) { + if (m_canvas_type == CanvasAssembleView && (evt.AltDown() || evt.CmdDown()) && m_gizmos.m_assemble_view_data != nullptr) { float rotation = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta(); if (evt.AltDown()) { auto clp_dist = m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position(); @@ -9117,6 +9127,9 @@ float GLCanvas3D::_render_assembly_tooltip_button(ImGuiWrapper* imgui_wrapper) c //BBS void GLCanvas3D::_render_assemble_control() { + if(m_gizmos.m_assemble_view_data == nullptr) + return; + if (m_canvas_type != ECanvasType::CanvasAssembleView) { GLVolume::explosion_ratio = m_explosion_ratio = 1.0; return; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a3cdb0f069..1b677df488 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -276,8 +276,8 @@ bool is_associate_files(std::wstring extend) class SplashScreen : public wxSplashScreen { public: - SplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds, wxPoint pos = wxDefaultPosition) - : wxSplashScreen(bitmap, splashStyle, milliseconds, static_cast(wxGetApp().mainframe), wxID_ANY, wxDefaultPosition, wxDefaultSize, + SplashScreen(wxPoint pos = wxDefaultPosition) + : wxSplashScreen(wxBitmap(FromDIP(wxSize(480,480),nullptr)), wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, 1500, nullptr, wxID_ANY, wxDefaultPosition, wxDefaultSize, #ifdef __APPLE__ wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP #else @@ -285,51 +285,53 @@ public: #endif // !__APPLE__ ) { - int init_dpi = get_dpi_for_window(this); this->SetPosition(pos); this->CenterOnScreen(); - int new_dpi = get_dpi_for_window(this); - m_scale = (float)(new_dpi) / (float)(init_dpi); + scale_font(m_font_version, 1.65f); // only scale this one since it hasnt a preloaded font like Label::Body_24; - m_main_bitmap = bitmap; + m_bg_color = StateColor::darkModeColorFor(wxColour("#FFFFFF")); + m_fg_color = StateColor::darkModeColorFor(wxColour("#6B6A6A")); + bool dark_mode = m_fg_color != wxColour("#6B6A6A"); + wxSize sz = m_window->GetClientSize(); + BitmapCache bmp_cache; + m_logo_bmp = *bmp_cache.load_svg(dark_mode ? "splash_logo_dark" : "splash_logo", sz.GetWidth(), sz.GetHeight()); - scale_bitmap(m_main_bitmap, m_scale); + m_window->Bind(wxEVT_PAINT, &SplashScreen::OnPaint, this); + m_window->Refresh(); + m_window->Update(); + } - // init constant texts and scale fonts - m_constant_text.init(Label::Body_16); + void OnPaint(wxPaintEvent& evt) + { + wxPaintDC dc(m_window); + wxSize c_sz = m_window->GetClientSize(); - // ORCA scale all fonts with monitor scale - scale_font(m_constant_text.version_font, m_scale * 2); - scale_font(m_constant_text.based_on_font, m_scale * 1.5f); - scale_font(m_constant_text.credits_font, m_scale * 2); + dc.SetBackground(wxBrush(m_bg_color)); + dc.Clear(); + if (m_logo_bmp.IsOk()) + dc.DrawBitmap(m_logo_bmp, 0, 0, true); - // this font will be used for the action string - m_action_font = m_constant_text.credits_font; + wxRect rc = wxRect(0, 0, c_sz.GetWidth(), 0); + dc.SetTextForeground(m_fg_color); - // draw logo and constant info text - Decorate(m_main_bitmap); - wxGetApp().UpdateFrameDarkUI(this); + dc.SetFont(m_font_version); + rc.y = c_sz.GetHeight() * 0.72; + rc.height = dc.GetTextExtent(m_text_version).GetHeight(); + dc.DrawLabel(m_text_version, rc, wxALIGN_CENTER); + + dc.SetFont(m_font_action); + rc.y = c_sz.GetHeight() * 0.88; + rc.height = dc.GetTextExtent(m_text_action).GetHeight(); + dc.DrawLabel(m_text_action, rc, wxALIGN_CENTER); } void SetText(const wxString& text) { - set_bitmap(m_main_bitmap); if (!text.empty()) { - wxBitmap bitmap(m_main_bitmap); - - wxMemoryDC memDC; - memDC.SelectObject(bitmap); - memDC.SetFont(m_action_font); - memDC.SetTextForeground(StateColor::darkModeColorFor(wxColour(144, 144, 144))); - int width = bitmap.GetWidth(); - int text_height = memDC.GetTextExtent(text).GetHeight(); - int text_width = memDC.GetTextExtent(text).GetWidth(); - wxRect text_rect(wxPoint(0, m_action_line_y_position), wxPoint(width, m_action_line_y_position + text_height)); - memDC.DrawLabel(text, text_rect, wxALIGN_CENTER); - - memDC.SelectObject(wxNullBitmap); - set_bitmap(bitmap); + m_text_action = text; + m_window->Refresh(); + m_window->Update(); #ifdef __WXOSX__ // without this code splash screen wouldn't be updated under OSX wxYield(); @@ -337,77 +339,6 @@ public: } } - void Decorate(wxBitmap& bmp) - { - if (!bmp.IsOk()) - return; - - bool is_dark = wxGetApp().app_config->get("dark_color_mode") == "1"; - - // use a memory DC to draw directly onto the bitmap - wxMemoryDC memDc(bmp); - - int width = bmp.GetWidth(); - int height = bmp.GetHeight(); - - // Logo - BitmapCache bmp_cache; - wxBitmap logo_bmp = *bmp_cache.load_svg(is_dark ? "splash_logo_dark" : "splash_logo", width, height); // use with full width & height - memDc.DrawBitmap(logo_bmp, 0, 0, true); - - // Version - memDc.SetFont(m_constant_text.version_font); - memDc.SetTextForeground(StateColor::darkModeColorFor(wxColor(134, 134, 134))); - wxSize version_ext = memDc.GetTextExtent(m_constant_text.version); - wxRect version_rect( - wxPoint(0, int(height * 0.70)), - wxPoint(width, int(height * 0.70) + version_ext.GetHeight()) - ); - memDc.DrawLabel(m_constant_text.version, version_rect, wxALIGN_CENTER); - - // Dynamic Text - m_action_line_y_position = int(height * 0.83); - } - - static wxBitmap MakeBitmap() - { - int width = FromDIP(480, nullptr); - int height = FromDIP(480, nullptr); - - wxImage image(width, height); - wxBitmap new_bmp(image); - - wxMemoryDC memDC; - memDC.SelectObject(new_bmp); - memDC.SetBrush(StateColor::darkModeColorFor(*wxWHITE)); - memDC.DrawRectangle(-1, -1, width + 2, height + 2); - memDC.DrawBitmap(new_bmp, 0, 0, true); - return new_bmp; - } - - void set_bitmap(wxBitmap& bmp) - { - m_window->SetBitmap(bmp); - m_window->Refresh(); - m_window->Update(); - } - - void scale_bitmap(wxBitmap& bmp, float scale) - { - if (scale == 1.0) - return; - - wxImage image = bmp.ConvertToImage(); - if (!image.IsOk() || image.GetWidth() == 0 || image.GetHeight() == 0) - return; - - int width = int(scale * image.GetWidth()); - int height = int(scale * image.GetHeight()); - image.Rescale(width, height, wxIMAGE_QUALITY_BILINEAR); - - bmp = wxBitmap(std::move(image)); - } - void scale_font(wxFont& font, float scale) { #ifdef __WXMSW__ @@ -425,47 +356,16 @@ public: #endif //__WXMSW__ } - private: - wxStaticText* m_staticText_slicer_name; - wxStaticText* m_staticText_slicer_version; - wxStaticBitmap* m_bitmap; - wxStaticText* m_staticText_loading; + wxBitmap m_logo_bmp; + wxColour m_fg_color; + wxColour m_bg_color; - wxBitmap m_main_bitmap; - wxFont m_action_font; - int m_action_line_y_position; - float m_scale {1.0}; + wxString m_text_version = GUI_App::format_display_version(); + wxString m_text_action = _L("Loading configuration") + dots; - struct ConstantText - { - wxString title; - wxString version; - wxString credits; - - wxFont title_font; - wxFont version_font; - wxFont credits_font; - wxFont based_on_font; - - void init(wxFont init_font) - { - // title - //title = wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME; - - // dynamically get the version to display - version = GUI_App::format_display_version(); - - // credits infornation - credits = ""; - - //title_font = Label::Head_16; - version_font = Label::Body_13; - based_on_font = Label::Body_8; - credits_font = Label::Body_8; - } - } - m_constant_text; + wxFont m_font_version = Label::Body_16; + wxFont m_font_action = Label::Body_16; }; #ifdef __linux__ @@ -2844,9 +2744,6 @@ bool GUI_App::on_init_inner() SplashScreen * scrn = nullptr; if (app_config->get("show_splash_screen") == "true") { - // make a bitmap with dark grey banner on the left side - //BBS make BBL splash screen bitmap - wxBitmap bmp = SplashScreen::MakeBitmap(); // Detect position (display) to show the splash screen // Now this position is equal to the mainframe position wxPoint splashscreen_pos = wxDefaultPosition; @@ -2858,9 +2755,9 @@ bool GUI_App::on_init_inner() BOOST_LOG_TRIVIAL(info) << "begin to show the splash screen..."; //BBS use BBL splashScreen - scrn = new SplashScreen(bmp, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, 1500, splashscreen_pos); + scrn = new SplashScreen(splashscreen_pos); wxYield(); - scrn->SetText(_L("Loading configuration")+ dots); + //scrn->SetText(_L("Loading configuration")+ dots); } BOOST_LOG_TRIVIAL(info) << "loading systen presets..."; @@ -4572,6 +4469,21 @@ std::string GUI_App::handle_web_request(std::string cmd) boost::optional command = root.get_optional("command"); if (command.has_value()) { std::string command_str = command.value(); + static const std::unordered_set stealth_blocked_commands = { + "get_login_info", + "get_orca_login_info", + "get_bambu_login_info", + "homepage_login_or_register", + "homepage_orca_login_or_register", + "homepage_bambu_login_or_register", + }; + if (app_config->get_stealth_mode() && stealth_blocked_commands.count(command_str)) { + CallAfter([this] { + if (mainframe && mainframe->m_webview) + mainframe->m_webview->SendCloudProvidersInfo(); + }); + return ""; + } if (command_str.compare("request_project_download") == 0) { if (root.get_child_optional("data") != boost::none) { pt::ptree data_node = root.get_child("data"); @@ -5895,12 +5807,16 @@ bool GUI_App::maybe_migrate_user_presets_on_login() { namespace fs = boost::filesystem; + BOOST_LOG_TRIVIAL(info) << "Migrate user presets to the OrcaCloud user folder if needed."; + if (!m_agent || !m_agent->is_user_login()) return false; std::string new_user_id = m_agent->get_user_id(); - if (new_user_id.empty()) + if (new_user_id.empty()) { + BOOST_LOG_TRIVIAL(warning) << "Failed to get user ID, skipping migration."; return false; + } fs::path user_base = fs::path(data_dir()) / PRESET_USER_DIR; fs::path target_dir = user_base / new_user_id; @@ -6834,6 +6750,16 @@ void GUI_App::stop_sync_user_preset() } } +void GUI_App::on_stealth_mode_enter() +{ + stop_sync_user_preset(); + request_user_logout(ORCA_CLOUD_PROVIDER); + request_user_logout(BBL_CLOUD_PROVIDER); + if (mainframe && mainframe->m_webview) { + mainframe->m_webview->SendCloudProvidersInfo(); + } +} + void GUI_App::start_http_server(const std::string& provider) { m_http_server.set_request_handler([provider](const std::string& url) { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 0ffd3b808b..fac853e65c 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -530,6 +530,7 @@ public: void sync_preset(Preset* preset); void start_sync_user_preset(bool with_progress_dlg = false); void stop_sync_user_preset(); + void on_stealth_mode_enter(); // Bundle subscription sync void check_bundle_updates(); diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index 3f60f4a409..a16d9916a6 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -13,6 +13,10 @@ #include #endif // _WIN32 +#ifdef __WXGTK__ +#include +#endif + #include #include #include @@ -496,6 +500,60 @@ void fit_in_display(wxTopLevelWindow& window, wxSize desired_size) window.SetSize(desired_size); } +#ifdef __WXGTK__ +void RemoveButtonBorder(wxWindow* win) +{ + GtkWidget* widget = win->GetHandle(); + if (!widget) return; + +#if GTK_CHECK_VERSION(3, 0, 0) + // GTK3+: use CSS provider + GtkCssProvider* provider = gtk_css_provider_new(); + + const char* css = + "button {" + " border: none;" + " outline: none;" + " box-shadow: none;" + " padding: 0px;" + " margin: 0px;" + " min-height: 0px;" + " min-width: 0px;" + " background: none;" + "}"; + +#if GTK_CHECK_VERSION(4, 0, 0) + // GTK4: no GError argument + gtk_css_provider_load_from_data(provider, css, -1); +#else + // GTK3: has GError argument + gtk_css_provider_load_from_data(provider, css, -1, nullptr); +#endif + + GtkStyleContext* ctx = gtk_widget_get_style_context(widget); + gtk_style_context_add_provider( + ctx, + GTK_STYLE_PROVIDER(provider), + GTK_STYLE_PROVIDER_PRIORITY_USER + ); + g_object_unref(provider); + +#else + // GTK2: use rc string, no CSS + gtk_rc_parse_string( + "style \"no-border\" {" + " GtkButton::inner-border = { 0, 0, 0, 0 }" + " GtkWidget::focus-line-width = 0" + " GtkWidget::focus-padding = 0" + " xthickness = 0" + " ythickness = 0" + "}" + "widget \"*.GtkBitmapToggleButton\" style \"no-border\"" + ); +#endif +} +#endif // __WXGTK__ + #ifdef __linux__ // Detect if the application is running inside a debugger. // https://stackoverflow.com/a/69842462/3289421 diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index 7e62d00c23..e50c9254a9 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -461,6 +461,10 @@ void dataview_remove_insets(wxDataViewCtrl* dv); void staticbox_remove_margin(wxStaticBox* sb); #endif +#ifdef __WXGTK3__ +void RemoveButtonBorder(wxWindow* win); +#endif + #if defined(__WXOSX__) || defined(__linux__) bool is_debugger_present(); #endif diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 7aa347b9c2..7af55915d5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -191,6 +191,12 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l if (! m_c->selection_info()->model_object()) return; + float scale = m_parent.get_scale(); + #ifdef WIN32 + int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); + scale *= (float) dpi / (float) DPI_DEFAULT; + #endif // WIN32 + // BBS wchar_t old_tool = m_current_tool; @@ -258,30 +264,24 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l std::array tool_tips = { _L("Circle"), _L("Sphere"), _L("Fill"), _L("Gap Fill") }; for (int i = 0; i < tool_ids.size(); i++) { - std::string str_label = std::string("##"); - std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); + //std::string str_label = std::string("##"); + //std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); // ORCA Removes button background on dark mode - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f)); // ORCA: Fixes icon rendered without colors while using Light theme - if (m_current_tool == tool_ids[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.59f, 0.53f, 0.30f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_Border, ImGuiWrapper::COL_ORCA); // ORCA use orca color for border on selected tool / brush - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); - } - bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); - if (m_current_tool == tool_ids[i]) - { - ImGui::PopStyleColor(4); - ImGui::PopStyleVar(2); - } - ImGui::PopStyleColor(2); - ImGui::PopStyleVar(1); + bool is_active = m_current_tool == tool_ids[i]; + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 3.f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(4.f * scale, 4.f * scale)); + ImGui::PushStyleColor(ImGuiCol_Text , ImVec4(1,1,1,1)); // ORCA Fixes icon rendered without colors while using Light theme + ImGui::PushStyleColor(ImGuiCol_Button , is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(.6f,.6f,.6f,.2f)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonActive , is_active ? ImVec4(0.f, .59f, .53f, .30f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_Border , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_BorderActive , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA matched color for fixing flicker on click + bool btn_clicked = m_imgui->glyph_button(icons[i], ImVec2(16.f * scale, 16.f * scale)); // ORCA glyph_button for fixing unequal paddings + ImGui::PopStyleColor(6); + ImGui::PopStyleVar(3); if (btn_clicked && m_current_tool != tool_ids[i]) { m_current_tool = tool_ids[i]; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp index 80470de7ad..d80687544e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFuzzySkin.cpp @@ -117,6 +117,12 @@ void GLGizmoFuzzySkin::on_render_input_window(float x, float y, float bottom_lim if (!mo) return; + float scale = m_parent.get_scale(); + #ifdef WIN32 + int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); + scale *= (float) dpi / (float) DPI_DEFAULT; + #endif // WIN32 + const DynamicPrintConfig &obj_cfg = mo->config.get(); const float approx_height = m_imgui->scaled(22.f); @@ -192,29 +198,24 @@ void GLGizmoFuzzySkin::on_render_input_window(float x, float y, float bottom_lim icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::FillButtonIcon }; std::array tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Fill") }; for (int i = 0; i < tool_ids.size(); i++) { - std::string str_label = std::string(""); - std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); + //std::string str_label = std::string(""); + //std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.5f)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); // ORCA Removes button background on dark mode - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f)); // ORCA Fixes icon rendered without colors while using Light theme - if (m_current_tool == tool_ids[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.59f, 0.53f, 0.30f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_Border, ImGuiWrapper::COL_ORCA); // ORCA use orca color for border on selected tool / brush - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); - } - bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); - if (m_current_tool == tool_ids[i]) - { - ImGui::PopStyleColor(4); - ImGui::PopStyleVar(2); - } - ImGui::PopStyleColor(2); - ImGui::PopStyleVar(1); + + bool is_active = m_current_tool == tool_ids[i]; + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 3.f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(4.f * scale, 4.f * scale)); + ImGui::PushStyleColor(ImGuiCol_Text , ImVec4(1,1,1,1)); // ORCA Fixes icon rendered without colors while using Light theme + ImGui::PushStyleColor(ImGuiCol_Button , is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(.6f,.6f,.6f,.2f)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonActive , is_active ? ImVec4(0.f, .59f, .53f, .30f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_Border , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_BorderActive , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA matched color for fixing flicker on click + bool btn_clicked = m_imgui->glyph_button(icons[i], ImVec2(16.f * scale, 16.f * scale)); // ORCA glyph_button for fixing unequal paddings + ImGui::PopStyleColor(6); + ImGui::PopStyleVar(3); if (btn_clicked && m_current_tool != tool_ids[i]) { m_current_tool = tool_ids[i]; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index e3fbfe0726..72e880f85d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -115,9 +115,9 @@ bool GLGizmoMmuSegmentation::on_init() m_desc["smart_fill_angle"] = _L("Smart fill angle"); m_desc["height_range"] = _L("Height range"); m_desc["toggle_wireframe"] = _L("Toggle Wireframe"); - m_desc["perform_remap"] = _L("Remap filaments"); + m_desc["perform_remap"] = _u8L("Remap filaments"); m_desc["remap"] = _L("Remap"); - m_desc["cancel_remap"] = _L("Cancel"); + m_desc["remap_reset"] = _L("Reset"); std::pair paint_shortcut = {_L("Left mouse button"), m_desc["paint"]}; std::pair erase_shortcut = {shift + _L("Left mouse button"), m_desc["erase"]}; @@ -304,10 +304,56 @@ void GLGizmoMmuSegmentation::render_tooltip_button(float x, float y) GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, get_shortcuts(), x, y); } +// ORCA +bool GLGizmoMmuSegmentation::draw_color_button(int idx, std::string id_str, const ColorRGBA& color, ColorRGBA& map_color, bool active, float scale) +{ + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + std::string label_id = std::to_string(idx) + id_str + std::to_string(idx); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 size = ImVec2(27.f * scale, 27.f * scale); + ImVec4 color_vec = ImGuiWrapper::to_ImVec4(color); + ImU32 br_color = ImGui::ColorConvertFloat4ToU32(active ? ImGuiWrapper::COL_ORCA : m_is_dark_mode ? ImVec4(.35f, .35f, .35f, 1) : ImVec4(.85f, .85f, .85f, 1)); + bool dark_tone = (0.299f * color.r() + 0.587f * color.g() + 0.114f * color.b()) < 0.51f; // matching values used by wxWidgets with clr.GetLuminance() < 0.51 + + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 7.f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_Text , dark_tone ? ImVec4(1,1,1,1) : ImVec4(0,0,0,1)); + ImGui::PushStyleColor(ImGuiCol_Button , color_vec); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, color_vec); + ImGui::PushStyleColor(ImGuiCol_ButtonActive , color_vec); + bool clicked = ImGui::Button(label_id.c_str(), size); + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(4); + + auto drawBorder = [&](float d, float r, float t, ImU32 col) { + draw_list->AddRect({pos.x + d * scale, pos.y + d * scale}, {pos.x + size.x - d * scale , pos.y + size.y - d * scale}, col, r * scale, 0, t * scale); + }; + drawBorder(1.5f, 3.f, 4.f, ImGui::ColorConvertFloat4ToU32(ImGui::GetStyleColorVec4(ImGuiCol_WindowBg))); + if(active) + drawBorder(.5f, 4.f , 2.f, br_color); + else + drawBorder(3.f, 2.5f, 1.f, br_color); + + if (color != map_color){ // show mapped color as bubble if mapped + ImVec2 center = {pos.x + size.x - 3.f * scale, pos.y + 3.f * scale}; + draw_list->AddCircleFilled(center, 6.f * scale, br_color, 16); // outer border for better visibility + draw_list->AddCircleFilled(center, 5.f * scale, ImGuiWrapper::to_ImU32(map_color), 16); + } + + return clicked; +}; + void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bottom_limit) { if (!m_c->selection_info()->model_object()) return; + float scale = m_parent.get_scale(); + #ifdef WIN32 + int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); + scale *= (float) dpi / (float) DPI_DEFAULT; + #endif // WIN32 + const float approx_height = m_imgui->scaled(22.0f); y = std::min(y, bottom_limit - approx_height); GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always); @@ -363,69 +409,67 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_width - space_size; const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; - ImDrawList * draw_list = ImGui::GetWindowDrawList(); - ImVec2 pos = ImGui::GetCursorScreenPos(); - static float color_button_high = 25.0; - draw_list->AddRectFilled({pos.x - 10.0f, pos.y - 7.0f}, {pos.x + window_width + ImGui::GetFrameHeight(), pos.y + color_button_high}, ImGui::GetColorU32(ImGuiCol_FrameBgActive, 1.0f), 5.0f); - - float color_button = ImGui::GetCursorPos().y; m_imgui->text(m_desc.at("filaments")); - float start_pos_x = ImGui::GetCursorPos().x; - const ImVec2 max_label_size = ImGui::CalcTextSize("99", NULL, true); - const float item_spacing = m_imgui->scaled(0.8f); size_t n_extruder_colors = std::min((size_t)EnforcerBlockerType::ExtruderMax, m_extruders_colors.size()); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(7.f * scale, 7.f * scale)); + ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0); // removes extra space on tree node indentation for (int extruder_idx = 0; extruder_idx < n_extruder_colors; extruder_idx++) { - const ColorRGBA &extruder_color = m_extruders_colors[extruder_idx]; - ImVec4 color_vec = ImGuiWrapper::to_ImVec4(extruder_color); - std::string color_label = std::string("##extruder color ") + std::to_string(extruder_idx); - std::string item_text = std::to_string(extruder_idx + 1); - const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true); - const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f),0.f); + if (extruder_idx % max_filament_items_per_line != 0) + ImGui::SameLine(); - float button_offset = start_pos_x; - if (extruder_idx % max_filament_items_per_line != 0) { - button_offset += filament_item_width * (extruder_idx % max_filament_items_per_line); - ImGui::SameLine(button_offset); + if (draw_color_button( + extruder_idx + 1, // idx + "###extruder_color_", // button_id + m_extruders_colors[extruder_idx], // color + m_extruders_colors[extruder_idx], // mapped_color (not used in here) + m_selected_extruder_idx == extruder_idx, // is_active + scale + )){ + m_selected_extruder_idx = extruder_idx; } - // draw filament background - ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip; - if (m_selected_extruder_idx != extruder_idx) flags |= ImGuiColorEditFlags_NoBorder; - #ifdef __APPLE__ - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); // ORCA use orca color for selected filament border - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0); - bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(1); - #else - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); // ORCA use orca color for selected filament border - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0); - bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(1); - #endif - color_button_high = ImGui::GetCursorPos().y - color_button - 2.0; - if (color_picked) { m_selected_extruder_idx = extruder_idx; } - if (extruder_idx < 16 && ImGui::IsItemHovered()) m_imgui->tooltip(_L("Shortcut Key ") + std::to_string(extruder_idx + 1), max_tooltip_width); - - // draw filament id - float gray = 0.299 * extruder_color.r() + 0.587 * extruder_color.g() + 0.114 * extruder_color.b(); - ImGui::SameLine(button_offset + (button_size.x - label_size.x) / 2.f); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {10.0,15.0}); - if (gray * 255.f < 80.f) - ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%s", item_text.c_str()); - else - ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), "%s", item_text.c_str()); - - ImGui::PopStyleVar(); } - //ImGui::NewLine(); + // ORCA: Remap filaments section (Border only, Title in border). + // Styled as a panel for visual grouping. + if (ImGui::TreeNodeEx(m_desc.at("perform_remap").c_str(), ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_FramePadding)){ + render_filament_remap_ui(window_width, max_tooltip_width, scale); + + bool has_mapping = false; + for (size_t i = 0; i < m_extruder_remap.size(); ++i){ + if(m_extruder_remap[i] != i){ + has_mapping = true; + break; + } + } + + ImGui::Dummy(ImVec2(0,0)); + + // ORCA: Add Remap and Cancel buttons (outside the panel) + m_imgui->disabled_begin(!has_mapping); // disable when no mapping + if (m_imgui->button(m_desc.at("remap"))) { + this->remap_filament_assignments(); + // Reset mapping to identity after apply + for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i; + } + m_imgui->disabled_end(/*m_is_unknown_font*/); + + if (has_mapping){ // show only when it has mapping + ImGui::SameLine(); + if (m_imgui->button(m_desc.at("remap_reset"))) { + // Reset mapping to identity + for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i; + } + } + + //ImGui::Dummy(ImVec2(0.0f, 3.f * scale)); + ImGui::TreePop(); + } + ImGui::PopStyleVar(2); // IndentSpacing ItemSpacing + ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1)); m_imgui->text(m_desc.at("tool_type")); @@ -439,29 +483,24 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon }; std::array tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Height Range"), _L("Fill"), _L("Gap Fill") }; for (int i = 0; i < tool_ids.size(); i++) { - std::string str_label = std::string(""); - std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); + //std::string str_label = std::string(""); + //std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.5f)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); // ORCA Removes button background on dark mode - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f)); // ORCA Fixes icon rendered without colors while using Light theme - if (m_current_tool == tool_ids[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.59f, 0.53f, 0.30f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_Border, ImGuiWrapper::COL_ORCA); // ORCA use orca color for border on selected tool / brush - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); - } - bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); - if (m_current_tool == tool_ids[i]) - { - ImGui::PopStyleColor(4); - ImGui::PopStyleVar(2); - } - ImGui::PopStyleColor(2); - ImGui::PopStyleVar(1); + + bool is_active = m_current_tool == tool_ids[i]; + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 3.f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(4.f * scale, 4.f * scale)); + ImGui::PushStyleColor(ImGuiCol_Text , ImVec4(1,1,1,1)); // ORCA Fixes icon rendered without colors while using Light theme + ImGui::PushStyleColor(ImGuiCol_Button , is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(.6f,.6f,.6f,.2f)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonActive , is_active ? ImVec4(0.f, .59f, .53f, .30f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_Border , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_BorderActive , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA matched color for fixing flicker on click + bool btn_clicked = m_imgui->glyph_button(icons[i], ImVec2(16.f * scale, 16.f * scale)); // ORCA glyph_button for fixing unequal paddings + ImGui::PopStyleColor(6); + ImGui::PopStyleVar(3); if (btn_clicked && m_current_tool != tool_ids[i]) { m_current_tool = tool_ids[i]; @@ -598,60 +637,6 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott m_c->object_clipper()->set_position_by_ratio(clp_dist, true); } - ImGui::Separator(); - // ORCA: Remap filaments section (Border only, Title in border). - // Styled as a panel for visual grouping. - if (m_imgui->button(m_desc.at("perform_remap"))) { - m_show_remap_panel = !m_show_remap_panel; - } - - if (m_show_remap_panel) - { - ImGui::Spacing(); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - std::string title = into_u8(m_desc.at("perform_remap")); - float available_width = ImGui::GetContentRegionAvail().x; - - // ORCA: Draw Background filled (consistent with Filaments section) - // Use static to remember height from previous frame so we can draw it behind. - static float remap_panel_high = 40.0f; - ImVec2 p_bg_min = ImGui::GetCursorScreenPos(); - // Adjust background position: slight negative offset to align with padding, width fills available - // height from static variable. - draw_list->AddRectFilled({p_bg_min.x - 10.0f, p_bg_min.y - 7.0f}, {p_bg_min.x + available_width + ImGui::GetFrameHeight(), p_bg_min.y + remap_panel_high}, ImGui::GetColorU32(ImGuiCol_FrameBgActive, 1.0f), 5.0f); - - float start_y = ImGui::GetCursorPos().y; - - // ORCA: Title as simple text - Removed as per request (redundant with button) - // m_imgui->text(title); - - ImGui::BeginGroup(); - // ORCA: Reduce vertical spacing within this group - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(m_imgui->scaled(0.4f), m_imgui->scaled(0.2f))); - - render_filament_remap_ui(window_width, max_tooltip_width); - - ImGui::PopStyleVar(); - ImGui::EndGroup(); - - // ORCA: Update height for next frame fill - remap_panel_high = ImGui::GetCursorPos().y - start_y; - - // ORCA: Add Remap and Cancel buttons (outside the panel) - ImGui::Spacing(); - if (m_imgui->button(m_desc.at("remap"))) { - this->remap_filament_assignments(); - // Reset mapping to identity after apply - for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i; - } - ImGui::SameLine(); - if (m_imgui->button(m_desc.at("cancel_remap"))) { - // Reset mapping to identity - for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i; - } - } - ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); @@ -1000,180 +985,85 @@ void GLGizmoMmuSegmentation::update_used_filaments() } } -void GLGizmoMmuSegmentation::render_filament_remap_ui(float window_width, float max_tooltip_width) +void GLGizmoMmuSegmentation::render_filament_remap_ui(float window_width, float max_tooltip_width, float scale) { size_t n_extr = std::min((size_t)EnforcerBlockerType::ExtruderMax, m_extruders_colors.size()); - const ImVec2 max_label_size = ImGui::CalcTextSize("99", NULL, true); - const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f), 0.f); - int displayed_count = 0; const int max_per_line = 8; // ORCA: Use m_used_filaments to show only relevant source filaments + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(7.f * scale, 7.f * scale)); for (size_t src : m_used_filaments) { if (src >= n_extr) continue; - const ColorRGBA &src_col = m_extruders_colors[src]; // keep for text contrast - const ColorRGBA &dst_col = m_extruders_colors[m_extruder_remap[src]]; - - // ORCA: Button now shows the SOURCE color (per maintainer request) - // This keeps the UI stable until "Remap" is clicked. - ImVec4 col_vec = ImGuiWrapper::to_ImVec4(src_col); - if (displayed_count > 0 && (displayed_count % max_per_line != 0)) ImGui::SameLine(); - std::string btn_id = "##remap_src_" + std::to_string(src); std::string pop_id = "popup_" + std::to_string(src); - - ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | - ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | - ImGuiColorEditFlags_NoTooltip; - - // ORCA: Show border ONLY if the popup is open (visual feedback for active selection) - // Decoupled from m_selected_extruder_idx to prevent unwanted selection highlights. - if (!ImGui::IsPopupOpen(pop_id.c_str())) - flags |= ImGuiColorEditFlags_NoBorder; - - #ifdef __APPLE__ - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0); - bool clicked = ImGui::ColorButton(btn_id.c_str(), col_vec, flags, button_size); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(1); - #else - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0); - bool clicked = ImGui::ColorButton(btn_id.c_str(), col_vec, flags, button_size); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(1); - #endif - // overlay destination number with proper contrast calculation - // ORCA: Text still shows DESTINATION index, but contrast is against SOURCE color now. - std::string dst_txt = std::to_string(m_extruder_remap[src] + 1); - float gray = 0.299f * src_col.r() + 0.587f * src_col.g() + 0.114f * src_col.b(); - ImVec2 txt_sz = ImGui::CalcTextSize(dst_txt.c_str()); - ImVec2 pos = ImGui::GetItemRectMin(); - ImVec2 size = ImGui::GetItemRectSize(); - - if (gray * 255.f < 80.f) - ImGui::GetWindowDrawList()->AddText( - ImVec2(pos.x + (size.x - txt_sz.x) * 0.5f, pos.y + (size.y - txt_sz.y) * 0.5f), - IM_COL32(255,255,255,255), dst_txt.c_str()); - else - ImGui::GetWindowDrawList()->AddText( - ImVec2(pos.x + (size.x - txt_sz.x) * 0.5f, pos.y + (size.y - txt_sz.y) * 0.5f), - IM_COL32(0,0,0,255), dst_txt.c_str()); + bool src_clicked = draw_color_button( + (int)src + 1, // idx + "###remap_src_", // button_id + m_extruders_colors[src], // color + m_extruders_colors[m_extruder_remap[src]], // mapped_color (shows bubble if not matches with Color) + ImGui::IsPopupOpen(pop_id.c_str()), // is_active + scale + ); - // ORCA: Show NEW color as a small triangle in the corner if remapped - if (src != m_extruder_remap[src]) { - float s = m_imgui->scaled(0.55f); - float offset = m_imgui->scaled(0.15f); // Inset to avoid rounded corner clipping - ImVec2 p = ImVec2(pos.x + offset, pos.y + offset); - - // Contrast outline: White for dark backgrounds, Black for light backgrounds - // Use dst_col (new color) for outline contrast check? Or src_col? - // Usually outline is around the triangle (dst_col). - float dst_gray = 0.299f * dst_col.r() + 0.587f * dst_col.g() + 0.114f * dst_col.b(); - ImU32 outline_col = (dst_gray * 255.f < 80.f) ? IM_COL32(255, 255, 255, 180) : IM_COL32(0, 0, 0, 180); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->AddTriangleFilled( - p, - ImVec2(p.x + s, p.y), - ImVec2(p.x, p.y + s), - ImGuiWrapper::to_ImU32(dst_col)); - - // ORCA: Add a thin outline for better contrast when colors are similar - draw_list->AddTriangle( - p, - ImVec2(p.x + s, p.y), - ImVec2(p.x, p.y + s), - outline_col, - 0.5f); - } - - // popup with possible destinations - if (clicked) { + if (src_clicked) { // Calculate popup position centered below the current button ImVec2 button_pos = ImGui::GetItemRectMin(); ImVec2 button_size = ImGui::GetItemRectSize(); - ImVec2 popup_pos(button_pos.x + button_size.x * 0.5f, button_pos.y + button_size.y); - - // Set popup styling BEFORE opening popup + + // Ensure popup is within the main viewport bounds + int dst_count = (int)std::min(n_extr, (size_t)max_per_line); + float est_popup_w = button_size.x * dst_count + + ImGui::GetStyle().ItemSpacing.x * (dst_count - 1) + + ImGui::GetStyle().WindowPadding.x * 2.f; + + ImGuiViewport* vp = ImGui::GetMainViewport(); + float right_limit = vp->WorkPos.x + vp->WorkSize.x - est_popup_w * 0.5f; // pivot is 0.5 so subtract half + float centered_x = button_pos.x + button_size.x * 0.5f; // pivot 0.5 just needs center x + + ImVec2 popup_pos(std::min(centered_x, right_limit), button_pos.y + button_size.y); + ImGui::SetNextWindowPos(popup_pos, ImGuiCond_Appearing, ImVec2(0.5f, -0.1f)); ImGui::SetNextWindowBgAlpha(1.0f); // Ensure full opacity ImGui::OpenPopup(pop_id.c_str()); } + + if (ImGui::IsItemHovered() && src != m_extruder_remap[src]) // show tooltip if it has mapping info + m_imgui->tooltip(std::to_string(src + 1) + " >> " + std::to_string(m_extruder_remap[src] + 1), max_tooltip_width); // Apply popup styling before BeginPopup using standard Orca colors - ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f); - ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 1.0f); - // ORCA: Use FrameBgActive for consistency and to ensure visibility of white filaments - ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGui::GetStyleColorVec4(ImGuiCol_FrameBgActive)); - ImGui::PushStyleColor(ImGuiCol_Border, m_is_dark_mode ? ImVec4(0.5f, 0.5f, 0.5f, 1.0f) : ImVec4(0.6f, 0.6f, 0.6f, 1.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding , 8.0f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 2.0f * scale); // thicker & colored border to prevent mixing with main window. Current ImGui version not supports shadows + ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg)); + ImGui::PushStyleColor(ImGuiCol_Border , ImGui::ColorConvertFloat4ToU32(ImGuiWrapper::COL_ORCA)); if (ImGui::BeginPopup(pop_id.c_str())) { m_imgui->text(_L("To:")); for (int dst = 0; dst < (int)n_extr; ++dst) { - const ColorRGBA &dst_col_popup = m_extruders_colors[dst]; - ImVec4 dst_vec = ImGuiWrapper::to_ImVec4(dst_col_popup); if (dst > 0 && (dst % max_per_line != 0)) ImGui::SameLine(); - std::string dst_btn = "##dst_" + std::to_string(src) + "_" + std::to_string(dst); - - // Apply same styling to destination buttons - ImGuiColorEditFlags dst_flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | - ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | - ImGuiColorEditFlags_NoTooltip; - // Show border for currently selected destination filament - if (m_extruder_remap[src] != dst) dst_flags |= ImGuiColorEditFlags_NoBorder; - - #ifdef __APPLE__ - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0); - bool dst_clicked = ImGui::ColorButton(dst_btn.c_str(), dst_vec, dst_flags, button_size); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(1); - #else - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0); - bool dst_clicked = ImGui::ColorButton(dst_btn.c_str(), dst_vec, dst_flags, button_size); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(1); - #endif - - // overlay destination number on popup buttons - std::string dst_num_txt = std::to_string(dst + 1); - float dst_gray = 0.299f * dst_col_popup.r() + 0.587f * dst_col_popup.g() + 0.114f * dst_col_popup.b(); - ImVec2 dst_txt_sz = ImGui::CalcTextSize(dst_num_txt.c_str()); - ImVec2 dst_pos = ImGui::GetItemRectMin(); - ImVec2 dst_size = ImGui::GetItemRectSize(); - - if (dst_gray * 255.f < 80.f) - ImGui::GetWindowDrawList()->AddText( - ImVec2(dst_pos.x + (dst_size.x - dst_txt_sz.x) * 0.5f, dst_pos.y + (dst_size.y - dst_txt_sz.y) * 0.5f), - IM_COL32(255,255,255,255), dst_num_txt.c_str()); - else - ImGui::GetWindowDrawList()->AddText( - ImVec2(dst_pos.x + (dst_size.x - dst_txt_sz.x) * 0.5f, dst_pos.y + (dst_size.y - dst_txt_sz.y) * 0.5f), - IM_COL32(0,0,0,255), dst_num_txt.c_str()); - - if (dst_clicked) - { + bool dst_clicked = draw_color_button( + dst + 1, // idx + "###remap_dst_", // button_id + m_extruders_colors[dst], // color + m_extruders_colors[dst], // mapped_color (non fuctional in here) + m_extruder_remap[src] == dst, // is_active + scale + ); + if (dst_clicked) { m_extruder_remap[src] = dst; // update the source button color immediately ImGui::CloseCurrentPopup(); } } + ImGui::Dummy(ImVec2(0.0f, 2.f * scale)); ImGui::EndPopup(); } @@ -1183,6 +1073,7 @@ void GLGizmoMmuSegmentation::render_filament_remap_ui(float window_width, float displayed_count++; } + ImGui::PopStyleVar(1); // ItemSpacing } void GLGizmoMmuSegmentation::remap_filament_assignments() diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index 756ada7670..eb8473aea6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -114,7 +114,6 @@ protected: bool m_detect_geometry_edge = true; // Filament remap feature - bool m_show_remap_panel = false; std::vector m_extruder_remap; // index → target extruder index // ORCA: Cache used filaments to filter UI std::set m_used_filaments; // Set of used filament indices (cached) @@ -136,13 +135,16 @@ private: void init_model_triangle_selectors(); + // ORCA + bool draw_color_button(int idx, std::string id_str, const ColorRGBA& color, ColorRGBA& map_color, bool active, float scale); + // BBS void update_triangle_selectors_colors(); void init_extruders_data(); // Filament remapping methods void remap_filament_assignments(); - void render_filament_remap_ui(float window_width, float max_tooltip_width); + void render_filament_remap_ui(float window_width, float max_tooltip_width, float scale); // ORCA: Helper to update the cache of used filaments void update_used_filaments(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 8790fd430d..1051c5ab3c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -121,6 +121,12 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) if (! m_c->selection_info()->model_object()) return; + float scale = m_parent.get_scale(); + #ifdef WIN32 + int dpi = get_dpi_for_window(wxGetApp().GetTopWindow()); + scale *= (float) dpi / (float) DPI_DEFAULT; + #endif // WIN32 + const float approx_height = m_imgui->scaled(12.5f); y = std::min(y, bottom_limit - approx_height); //BBS: GUI refactor: move gizmo to the right @@ -170,29 +176,25 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon }; std::array tool_tips = { _L("Circle"), _L("Sphere")}; for (int i = 0; i < tool_ids.size(); i++) { - std::string str_label = std::string("##"); - std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); + //std::string str_label = std::string("##"); + //std::wstring btn_name = icons[i] + boost::nowide::widen(str_label); if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); // ORCA Removes button background on dark mode - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f)); // ORCA: Fixes icon rendered without colors while using Light theme - if (m_current_tool == tool_ids[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.f, 0.59f, 0.53f, 0.25f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.59f, 0.53f, 0.30f)); // ORCA use orca color for selected tool / brush - ImGui::PushStyleColor(ImGuiCol_Border, ImGuiWrapper::COL_ORCA); // ORCA use orca color for border on selected tool / brush - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); - } - bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); - if (m_current_tool == tool_ids[i]) - { - ImGui::PopStyleColor(4); - ImGui::PopStyleVar(2); - } - ImGui::PopStyleColor(2); - ImGui::PopStyleVar(1); + + bool is_active = m_current_tool == tool_ids[i]; + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 3.f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(4.f * scale, 4.f * scale)); + ImGui::PushStyleColor(ImGuiCol_Text , ImVec4(1,1,1,1)); // ORCA Fixes icon rendered without colors while using Light theme + ImGui::PushStyleColor(ImGuiCol_Button , is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, is_active ? ImVec4(0.f, .59f, .53f, .25f) : ImVec4(.6f,.6f,.6f,.2f)); // ORCA + ImGui::PushStyleColor(ImGuiCol_ButtonActive , is_active ? ImVec4(0.f, .59f, .53f, .30f) : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_Border , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA + ImGui::PushStyleColor(ImGuiCol_BorderActive , is_active ? ImGuiWrapper::COL_ORCA : ImVec4(0,0,0,0)); // ORCA matched color for fixing flicker on click + bool btn_clicked = m_imgui->glyph_button(icons[i], ImVec2(16.f * scale, 16.f * scale)); // ORCA glyph_button for fixing unequal paddings + ImGui::PopStyleColor(6); + ImGui::PopStyleVar(3); + if (btn_clicked && m_current_tool != tool_ids[i]) { m_current_tool = tool_ids[i]; for (auto& triangle_selector : m_triangle_selectors) { diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 67f33ce851..85f59d31e5 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -908,6 +908,54 @@ bool ImGuiWrapper::button(const wxString& label, const ImVec2 &size, bool enable return (enable) ? res : false; } +// ORCA Glyph based button for correctly rendering icon size based Glyph +// excludes spacings after Glyph and centers icon properly +// compared to image_button this supports styling +bool ImGuiWrapper::glyph_button(wchar_t icon_char, ImVec2 icon_size) +{ + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImFont* font = ImGui::GetFont(); + ImGuiStyle& style = ImGui::GetStyle(); + ImVec2 padding = style.FramePadding; + float border_w = style.FrameBorderSize; + float rounding = style.FrameRounding; + std::string icon_str = into_u8(icon_char); + const char* icon = icon_str.c_str(); + + float width = icon_size.x + (padding.x + border_w) * 2.f; + float height = icon_size.y + (padding.y + border_w) * 2.f; + ImVec2 rc_min = ImGui::GetCursorScreenPos(); + ImVec2 rc_max = ImVec2(rc_min.x + width, rc_min.y + height); + + ImGui::Dummy(ImVec2(width, height)); + + ImGuiCol bg_color = ImGuiCol_Button; + ImGuiCol border_color = ImGuiCol_Border; + bool clicked = false; + + if (ImGui::IsMouseHoveringRect(rc_min, rc_max)) { + bg_color = ImGuiCol_ButtonHovered; + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { + bg_color = ImGuiCol_ButtonActive; + border_color = ImGuiCol_BorderShadow; + clicked = true; + } + } + + draw_list->AddRectFilled(rc_min, rc_max, ImGui::GetColorU32(bg_color), rounding); + + if (border_w > 0.f) + draw_list->AddRect(rc_min, rc_max, ImGui::GetColorU32(border_color), rounding, 0, border_w); + + ImVec2 text_pos = ImVec2( + rc_min.x + (width - font->FontSize) * .5f, + rc_min.y + (height - font->FontSize) * .5f + ); + draw_list->AddText(font, font->FontSize, text_pos, ImGui::GetColorU32(ImGuiCol_Text), icon); + + return clicked; +} + bool ImGuiWrapper::radio_button(const wxString &label, bool active) { auto label_utf8 = into_u8(label); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 21ca91013b..a2b8476c71 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -133,6 +133,7 @@ public: bool bbl_button(const wxString &label, const wxString& tooltip = {}); bool button(const wxString& label, float width, float height); bool button(const wxString& label, const ImVec2 &size, bool enable); // default size = ImVec2(0.f, 0.f) + bool glyph_button(wchar_t icon_char, ImVec2 icon_size); // ORCA bool radio_button(const wxString &label, bool active); static ImVec4 to_ImVec4(const ColorRGB &color); bool input_double(const std::string &label, const double &value, const std::string &format = "%.3f"); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 7a699ea2c1..aeaf0cb020 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -4560,12 +4560,13 @@ int PartPlate::load_gcode_from_file(const std::string& filename) int ret = 0; // process gcode - DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(); + std::vector filament_maps = this->get_filament_maps(); + DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(false, filament_maps); full_config.apply(m_config, true); - m_print->apply(*m_model, full_config); + m_print->apply(*m_model, full_config, false); //BBS: need to apply two times, for after the first apply, the m_print got its object, //which will affect the config when new_full_config.normalize_fdm(used_filaments); - m_print->apply(*m_model, full_config); + m_print->apply(*m_model, full_config, false); // BBS: use backup path to save temp gcode // auto path = get_tmp_gcode_path(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 110cbbf356..d24e20a23d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6927,6 +6927,12 @@ std::vector Plater::priv::load_files(const std::vector& input_ } if (load_model) { + if (!q->m_exported_file && view3D != nullptr) { + // Force a 3D scene refresh after view/plate selection to avoid losing the first load + // on platforms where the GL canvas mapping lags behind model loading. + view3D->reload_scene(true); + view3D->set_as_dirty(); + } if (!silence) wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().make_preferred().string()); // XXX: Plater.pm had @loaded_files, but didn't seem to fill them with the filenames... } @@ -9143,6 +9149,20 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) if (current_panel == panel) { + if (panel == view3D) { + if (view3D->is_reload_delayed()) { + // Delayed loading of the 3D scene when caller requests the already active tab. + if (printer_technology == ptSLA) + update_restart_background_process(true, false); + else + view3D->reload_scene(true); + } + + view3D->set_as_dirty(); + view3D->get_canvas3d()->reset_old_size(); + if (notification_manager != nullptr) + notification_manager->set_in_preview(false); + } //BBS: add slice logic when switch to preview page //BBS: add only gcode mode if (!q->only_gcode_mode() && (current_panel == preview) && (wxGetApp().is_editor())) { diff --git a/src/slic3r/GUI/PrePrintChecker.cpp b/src/slic3r/GUI/PrePrintChecker.cpp index ef9c1447bb..7f21bc90a9 100644 --- a/src/slic3r/GUI/PrePrintChecker.cpp +++ b/src/slic3r/GUI/PrePrintChecker.cpp @@ -53,6 +53,7 @@ std::string PrePrintChecker::get_print_status_info(PrintDialogStatus status) case PrintStatusFilamentWarningHighChamberTempCloseDoor: return "PrintStatusFilamentWarningHighChamberTempCloseDoor"; case PrintStatusFilamentWarningHighChamberTempSoft: return "PrintStatusFilamentWarningHighChamberTempSoft"; case PrintStatusFilamentWarningUnknownHighChamberTempSoft: return "PrintStatusFilamentWarningUnknownHighChamberTempSoft"; + case PrintStatusWarningExtFilamentNotMatch: return "PrintStatusWarningExtFilamentNotMatch"; case PrintStatusReadingFinished: return "PrintStatusReadingFinished"; case PrintStatusSendingCanceled: return "PrintStatusSendingCanceled"; case PrintStatusAmsMappingSuccess: return "PrintStatusAmsMappingSuccess"; @@ -92,6 +93,7 @@ wxString PrePrintChecker::get_pre_state_msg(PrintDialogStatus status) case PrintStatusWarningKvalueNotUsed: return _L("Set dynamic flow calibration to 'OFF' to enable custom dynamic flow value."); case PrintStatusNotSupportedPrintAll: return _L("This printer does not support printing all plates."); case PrintStatusColorQuantityExceed: return _L("The current firmware supports a maximum of 16 materials. You can either reduce the number of materials to 16 or fewer on the Preparation Page, or try updating the firmware. If you are still restricted after the update, please wait for subsequent firmware support."); + case PrintStatusWarningExtFilamentNotMatch: return _L("The type of external filament is unknown or does not match with the filament type in the slicing file. Please make sure you have installed the correct filament in the external spool."); } return wxEmptyString; } diff --git a/src/slic3r/GUI/PrePrintChecker.hpp b/src/slic3r/GUI/PrePrintChecker.hpp index feac610628..8e4d4ed3f4 100644 --- a/src/slic3r/GUI/PrePrintChecker.hpp +++ b/src/slic3r/GUI/PrePrintChecker.hpp @@ -99,6 +99,7 @@ enum PrintDialogStatus : unsigned int { PrintStatusFilamentWarningHighChamberTempCloseDoor, PrintStatusFilamentWarningHighChamberTempSoft, PrintStatusFilamentWarningUnknownHighChamberTempSoft, + PrintStatusWarningExtFilamentNotMatch, PrintStatusFilamentWarningEnd, PrintStatusWarningEnd,//->end error<- diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index c5d377b67b..ccb85ec813 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -924,6 +924,8 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too checkbox->SetValue(app_config->get_bool(param)); checkbox->SetToolTip(tip); + if (param == "sync_user_preset") { m_sync_user_preset_checkbox = checkbox; } + m_sizer_checkbox->Add(checkbox_title, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, FromDIP(3)); m_sizer_checkbox->Add(checkbox , 0, wxALIGN_CENTER | wxRIGHT | wxLEFT, FromDIP(5)); @@ -955,6 +957,12 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too } BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " sync_user_preset: " << (sync ? "true" : "false"); } + else if (param == "stealth_mode") { + bool enabled = app_config->get_stealth_mode(); + if (enabled) wxGetApp().on_stealth_mode_enter(); + if (m_sync_user_preset_checkbox) m_sync_user_preset_checkbox->Enable(!enabled); + if (m_bambu_cloud_checkbox) m_bambu_cloud_checkbox->Enable(!enabled); + } #ifdef __WXMSW__ if (param == "associate_3mf") { @@ -1528,7 +1536,7 @@ void PreferencesDialog::create_items() auto item_region = create_item_region_combobox(_L("Login region"), ""); g_sizer->Add(item_region); - auto item_stealth_mode = create_item_checkbox(_L("Stealth mode"), _L("This stops the transmission of data to Bambu's cloud services. Users who don't use BBL machines or use LAN mode only can safely turn on this function."), "stealth_mode"); + auto item_stealth_mode = create_item_checkbox(_L("Stealth mode"), _L("This disables all cloud services e.g. Orca Cloud and Bambu Cloud. This stops the transmission of data to Bambu's cloud services too. Users who don't use BBL machines or use LAN mode only can safely turn on this function."), "stealth_mode"); g_sizer->Add(item_stealth_mode); auto item_network_test = create_item_button(_L("Network test"), _L("Test") + " " + dots, "", _L("Open Network Test"), []() { @@ -1552,6 +1560,7 @@ void PreferencesDialog::create_items() text->Wrap(DESIGN_TITLE_SIZE.x); auto cb = new ::CheckBox(m_parent); + m_bambu_cloud_checkbox = cb; cb->SetValue(app_config->has_cloud_provider(BBL_CLOUD_PROVIDER)); cb->SetToolTip(text->GetToolTipText()); @@ -1585,6 +1594,11 @@ void PreferencesDialog::create_items() auto item_user_sync = create_item_checkbox(_L("Auto sync user presets (Printer/Filament/Process)"), "", "sync_user_preset"); g_sizer->Add(item_user_sync); + if (app_config->get_stealth_mode()) { + if (m_bambu_cloud_checkbox) m_bambu_cloud_checkbox->Enable(false); + if (m_sync_user_preset_checkbox) m_sync_user_preset_checkbox->Enable(false); + } + auto item_system_sync = create_item_checkbox(_L("Update built-in Presets automatically."), "", "sync_system_preset"); g_sizer->Add(item_system_sync); diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index 73e61938d6..d7daca5ff8 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -71,6 +71,8 @@ public: ::CheckBox * m_developer_mode_ckeckbox = {nullptr}; ::CheckBox * m_internal_developer_mode_ckeckbox = {nullptr}; ::CheckBox * m_dark_mode_ckeckbox = {nullptr}; + ::CheckBox * m_sync_user_preset_checkbox = {nullptr}; + ::CheckBox * m_bambu_cloud_checkbox = {nullptr}; ::TextInput *m_backup_interval_textinput = {nullptr}; ::ComboBox * m_network_version_combo = {nullptr}; wxBoxSizer * m_network_version_sizer = {nullptr}; diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 0fd7374f3c..b95f74b248 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -1175,8 +1175,8 @@ void PlaterPresetComboBox::update() } bool single_bar = false; - wxString name = preset.name; - preset_aliases[name] = get_preset_name(preset).ToStdString(); // ORCA + wxString name = from_u8(preset.name); + preset_aliases[name] = get_preset_name(preset).utf8_string(); // ORCA // Track bundle names for bundled presets if (preset.is_from_bundle()) { @@ -1232,7 +1232,7 @@ void PlaterPresetComboBox::update() name = from_u8(is_selected && preset.is_dirty ? Preset::suffix_modified() + printer_model : printer_model); if (system_printer_models.count(printer_model) == 0) { - preset_aliases[name] = name.ToStdString(); // ORCA + preset_aliases[name] = name.utf8_string(); // ORCA system_presets.emplace(name, bmp); system_printer_models.insert(printer_model); } @@ -1355,16 +1355,16 @@ void PlaterPresetComboBox::update() bool unsupported = group == "Unsupported presets"; for (auto it : list) { // ORCA add sorting support for vendor / type for user presets - auto groupName2 = groupName == "by_bundle" ? (preset_bundle_names[it->first].empty() ? _L("Unspecified") : preset_bundle_names[it->first]) - : groupName == "by_type" ? (preset_filament_types[it->first].empty() ? _L("Unspecified") : preset_filament_types[it->first]) - : groupName == "by_vendor" ? (preset_filament_vendors[it->first].empty() ? _L("Unspecified") : preset_filament_vendors[it->first]) + auto groupName2 = groupName == "by_bundle" ? (preset_bundle_names[it->first].empty() ? _L("Unspecified") : from_u8(preset_bundle_names[it->first])) + : groupName == "by_type" ? (preset_filament_types[it->first].empty() ? _L("Unspecified") : from_u8(preset_filament_types[it->first])) + : groupName == "by_vendor" ? (preset_filament_vendors[it->first].empty() ? _L("Unspecified") : from_u8(preset_filament_vendors[it->first])) : groupByGroup ? groupName - : preset_filament_vendors[it->first]; + : from_u8(preset_filament_vendors[it->first]); int index = groupName == "by_bundle" - ? Append(preset_aliases[it->first], *it->second, + ? Append(from_u8(preset_aliases[it->first]), *it->second, from_u8(preset_bundle_ids[it->first]), groupName2, nullptr, unsupported ? DD_ITEM_STYLE_DISABLED : 0) - : Append(preset_aliases[it->first], *it->second, groupName2, nullptr, + : Append(from_u8(preset_aliases[it->first]), *it->second, groupName2, nullptr, unsupported ? DD_ITEM_STYLE_DISABLED : 0); SetItemAlias(index, it->first); if (unsupported) @@ -1380,7 +1380,7 @@ void PlaterPresetComboBox::update() } } else { for (std::map::const_iterator it = presets.begin(); it != presets.end(); ++it) { - int index = Append(preset_aliases[it->first], *it->second); + int index = Append(from_u8(preset_aliases[it->first]), *it->second); SetItemAlias(index, it->first); SetItemTooltip(index, preset_descriptions[it->first]); if (group == "System presets") @@ -1676,8 +1676,8 @@ void TabPresetComboBox::update() wxBitmap* bmp = get_bmp(preset); assert(bmp); - const wxString name = preset.name; - preset_aliases[name] = get_preset_name(preset).ToStdString(); + const wxString name = from_u8(preset.name); + preset_aliases[name] = get_preset_name(preset).utf8_string(); if (preset.is_system) preset_descriptions.emplace(name, from_u8(preset.description)); @@ -1767,10 +1767,10 @@ void TabPresetComboBox::update() // Get bundle name for grouping wxString bundle_name = _L("Unspecified"); if (preset_bundle_names.count(it->first) > 0 && !preset_bundle_names[it->first].empty()) { - bundle_name = preset_bundle_names[it->first]; + bundle_name = from_u8(preset_bundle_names[it->first]); } // Use Append with group parameter for sub-dropdown grouping - int item_id = Append(preset_aliases[it->first], *it->second.first, from_u8(preset_bundle_ids[it->first]), bundle_name); + int item_id = Append(from_u8(preset_aliases[it->first]), *it->second.first, from_u8(preset_bundle_ids[it->first]), bundle_name); SetItemAlias(item_id, it->first); SetItemTooltip(item_id, preset_descriptions[it->first]); bool is_enabled = it->second.second; diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index f341cff154..3dd87e8626 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -243,24 +243,23 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent) auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1)); m_line_top->SetBackgroundColour(wxColour(166, 169, 170)); + wxBoxSizer *m_sizer_top = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *m_sizer_desc = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *m_sizer_body = new wxBoxSizer(wxHORIZONTAL); - - - - auto sm = create_scaled_bitmap("OrcaSlicer", nullptr, 70); - m_brand = new wxStaticBitmap(this, wxID_ANY, sm, wxDefaultPosition, wxSize(FromDIP(70), FromDIP(70))); - - - - wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL); + auto sm = create_scaled_bitmap("OrcaSlicer", nullptr, 64); + m_brand = new wxStaticBitmap(this, wxID_ANY, sm, wxDefaultPosition, FromDIP(wxSize(64, 64))); m_text_up_info = new Label(this, Label::Head_14, wxEmptyString, LB_AUTO_WRAP); m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30)); - m_simplebook_release_note = new wxSimplebook(this); - m_simplebook_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430))); - m_simplebook_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430))); + auto github_link = new HyperLink(this, _L("Check on Github"), "", LB_AUTO_WRAP); + github_link->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { + EndModal(wxID_YES); + }); + + m_simplebook_release_note = new wxSimplebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + //m_simplebook_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430))); + m_simplebook_release_note->SetMinSize(FromDIP(wxSize(640,420))); m_simplebook_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8)); m_scrollwindows_release_note = new wxScrolledWindow(m_simplebook_release_note, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL); @@ -269,8 +268,9 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent) //webview m_vebview_release_note = CreateTipView(m_simplebook_release_note); - m_vebview_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430))); - m_vebview_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430))); + m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8)); + //m_vebview_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430))); + //m_vebview_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430))); //m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430))); if (wxGetApp().app_config->get_bool("developer_mode")) m_vebview_release_note->EnableAccessToDevTools(); @@ -300,8 +300,6 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent) m_simplebook_release_note->AddPage(m_scrollwindows_release_note, wxEmptyString, false); m_simplebook_release_note->AddPage(m_vebview_release_note, wxEmptyString, false); - - auto sizer_button = new wxBoxSizer(wxHORIZONTAL); m_button_download = new Button(this, _L("Download")); @@ -327,8 +325,6 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent) }); auto stable_only_label = new Label(this, _L("Check for stable updates only")); - stable_only_label->SetFont(Label::Body_13); - stable_only_label->SetForegroundColour(wxColour(38, 46, 48)); stable_only_label->SetFont(Label::Body_12); m_button_cancel = new Button(this, _L("Cancel")); @@ -338,25 +334,27 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent) EndModal(wxID_NO); }); - m_sizer_main->Add(m_line_top, 0, wxEXPAND | wxBOTTOM, 0); - //sizer_button->Add(m_remind_choice, 0, wxALL | wxEXPAND, FromDIP(5)); + + sizer_button->Add(m_cb_stable_only , 0, wxALIGN_CENTER); + sizer_button->Add(stable_only_label , 0, wxALIGN_CENTER | wxLEFT, FromDIP(5)); sizer_button->AddStretchSpacer(); - sizer_button->Add(stable_only_label, 0, wxALIGN_CENTER | wxLEFT, FromDIP(7)); - sizer_button->Add(m_cb_stable_only, 0, wxALIGN_CENTER | wxLEFT, FromDIP(5)); - sizer_button->Add(m_button_download, 0, wxALL, FromDIP(5)); - sizer_button->Add(m_button_skip_version, 0, wxALL, FromDIP(5)); - sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5)); + sizer_button->Add(m_button_download , 0, wxLEFT, FromDIP(10)); + sizer_button->Add(m_button_skip_version, 0, wxLEFT, FromDIP(10)); + sizer_button->Add(m_button_cancel , 0, wxLEFT, FromDIP(10)); - m_sizer_right->Add(m_text_up_info, 0, wxEXPAND | wxBOTTOM | wxTOP, FromDIP(15)); - m_sizer_right->Add(m_simplebook_release_note, 1, wxEXPAND | wxRIGHT, 0); - m_sizer_right->Add(sizer_button, 0, wxEXPAND | wxRIGHT, FromDIP(20)); + m_sizer_desc->AddStretchSpacer(); + m_sizer_desc->Add(m_text_up_info, 0, wxEXPAND | wxBOTTOM, FromDIP(5)); + m_sizer_desc->Add(github_link); + m_sizer_desc->AddStretchSpacer(); - m_sizer_body->Add(m_brand, 0, wxTOP|wxRIGHT|wxLEFT, FromDIP(15)); - m_sizer_body->Add(0, 0, 0, wxRIGHT, 0); - m_sizer_body->Add(m_sizer_right, 1, wxBOTTOM | wxEXPAND, FromDIP(8)); - m_sizer_main->Add(m_sizer_body, 1, wxEXPAND, 0); - m_sizer_main->Add(0, 0, 0, wxBOTTOM, 10); + m_sizer_top->Add(m_brand , 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(15)); + m_sizer_top->Add(m_sizer_desc, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL); + + m_sizer_main->Add(m_line_top , 0, wxEXPAND); + m_sizer_main->Add(m_sizer_top , 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(15)); + m_sizer_main->Add(m_simplebook_release_note, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(15)); + m_sizer_main->Add(sizer_button , 0, wxEXPAND | wxALL , FromDIP(15)); SetSizer(m_sizer_main); Layout(); @@ -479,14 +477,17 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve // m_vebview_release_note->LoadURL(from_u8(url_line)); // } // else { - m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430))); + //m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430))); m_simplebook_release_note->SetSelection(1); m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version)); auto data_buf_in = release_note.utf8_str(); - auto bg_color = StateColor::darkModeColorFor(*wxWHITE).GetAsString(); - auto fg_color = StateColor::darkModeColorFor(*wxBLACK).GetAsString(); - html_source = (boost::format("") - % fg_color % bg_color).str(); + auto bg_color = StateColor::darkModeColorFor(wxColour("#FFFFFF")).GetAsString(); + auto fg_color = StateColor::darkModeColorFor(wxColour("#262E30")).GetAsString(); + auto style = "body {color:" + fg_color + "; background-color:" + bg_color + "; font-family:sans-serif}" + + "a {color: #009688}" // matches hyperlink colors + + "img {max-width:100%; height:auto}" // fixes overflowing images + + "ul {padding-inline-start: 20px}"; // reduce left padding on list items + html_source = (boost::format("") % style).str(); md_html(data_buf_in.data(), data_buf_in.length(), [](const MD_CHAR* text, MD_SIZE size, void* userdata) { std::string* out_buf = (std::string*)userdata; out_buf->append(text, size); diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 59c9956bd9..1d88bbc235 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -1092,23 +1092,13 @@ bool SelectMachineDialog::do_ams_mapping(MachineObject *obj_,bool use_ams) //single nozzle else { - if (obj_->is_support_amx_ext_mix_mapping()){ - map_opt = { false, true, false, false }; //four values: use_left_ams, use_right_ams, use_left_ext, use_right_ext - if (!use_ams) { - map_opt[1] = false; - map_opt[3] = true; - } - filament_result = DevMappingUtil::ams_filament_mapping(obj_, m_filaments, m_ams_mapping_result, map_opt); - //auto_supply_with_ext(obj_->vt_slot); - } - else { - map_opt = { false, true, false, false }; - if (!use_ams) { - map_opt[1] = false; - map_opt[3] = true; - } - filament_result = DevMappingUtil::ams_filament_mapping(obj_, m_filaments, m_ams_mapping_result, map_opt); + map_opt = { false, true, false, false }; //four values: use_left_ams, use_right_ams, use_left_ext, use_right_ext + if (!use_ams) { + map_opt[1] = false; + map_opt[3] = true; } + filament_result = DevMappingUtil::ams_filament_mapping(obj_, m_filaments, m_ams_mapping_result, map_opt); + //auto_supply_with_ext(obj_->vt_slot); } if (filament_result == 0) { @@ -1147,7 +1137,7 @@ bool SelectMachineDialog::do_ams_mapping(MachineObject *obj_,bool use_ams) return true; } -bool SelectMachineDialog::get_ams_mapping_result(std::string &mapping_array_str, std::string& mapping_array_str2, std::string &ams_mapping_info) +bool SelectMachineDialog::get_ams_mapping_result(std::string &mapping_array_str, std::string& mapping_array_str2, std::string &ams_mapping_info) const { if (m_ams_mapping_result.empty()) return false; @@ -1438,7 +1428,7 @@ bool SelectMachineDialog::is_nozzle_type_match(DevExtderSystem data, wxString& e return true; } -int SelectMachineDialog::convert_filament_map_nozzle_id_to_task_nozzle_id(int nozzle_id) +int SelectMachineDialog::convert_filament_map_nozzle_id_to_task_nozzle_id(int nozzle_id) const { if (nozzle_id == (int)FilamentMapNozzleId::NOZZLE_LEFT) { return (int)CloudTaskNozzleId::NOZZLE_LEFT; @@ -1691,6 +1681,9 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vectorIsShown() && m_checkbox_list["flow_cali"]->getValue() == "auto") { const auto ¬_default_ams_names = _check_kval_not_default(obj_, m_ams_mapping_result); diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index 302b37b553..f0e135f33e 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -500,12 +500,12 @@ public: bool Show(bool show); void show_init(); bool do_ams_mapping(MachineObject *obj_,bool use_ams); - bool get_ams_mapping_result(std::string& mapping_array_str, std::string& mapping_array_str2, std::string& ams_mapping_info); + bool get_ams_mapping_result(std::string& mapping_array_str, std::string& mapping_array_str2, std::string& ams_mapping_info) const; bool build_nozzles_info(std::string& nozzles_info); bool can_hybrid_mapping(DevExtderSystem data); void auto_supply_with_ext(std::vector slots); bool is_nozzle_type_match(DevExtderSystem data, wxString& error_message) const; - int convert_filament_map_nozzle_id_to_task_nozzle_id(int nozzle_id); + int convert_filament_map_nozzle_id_to_task_nozzle_id(int nozzle_id) const; PrintFromType get_print_type() {return m_print_type;}; wxString format_steel_name(NozzleType type); diff --git a/src/slic3r/GUI/SyncAmsInfoDialog.cpp b/src/slic3r/GUI/SyncAmsInfoDialog.cpp index 4056d48fe5..bfb1e931be 100644 --- a/src/slic3r/GUI/SyncAmsInfoDialog.cpp +++ b/src/slic3r/GUI/SyncAmsInfoDialog.cpp @@ -1261,15 +1261,10 @@ bool SyncAmsInfoDialog::do_ams_mapping(MachineObject *obj_) } // single nozzle else { - if (obj_->is_support_amx_ext_mix_mapping()) { - map_opt = {false, true, false, true}; // four values: use_left_ams, use_right_ams, use_left_ext, use_right_ext - filament_result = DevMappingUtil::ams_filament_mapping(obj_, m_filaments, m_ams_mapping_result, map_opt, std::vector(), - wxGetApp().app_config->get_bool("ams_sync_match_full_use_color_dist") ? false : true); - // auto_supply_with_ext(obj_->vt_slot); - } else { - map_opt = {false, true, false, false}; - filament_result = DevMappingUtil::ams_filament_mapping(obj_, m_filaments, m_ams_mapping_result, map_opt); - } + map_opt = {false, true, false, true}; // four values: use_left_ams, use_right_ams, use_left_ext, use_right_ext + filament_result = DevMappingUtil::ams_filament_mapping(obj_, m_filaments, m_ams_mapping_result, map_opt, std::vector(), + wxGetApp().app_config->get_bool("ams_sync_match_full_use_color_dist") ? false : true); + // auto_supply_with_ext(obj_->vt_slot); } if (filament_result == 0) { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 238b6709fa..856bf8dc81 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1244,6 +1244,8 @@ void Tab::reload_config() { if (m_active_page) m_active_page->reload_config(); + if (m_type == Preset::TYPE_PRINT && m_config != nullptr) + m_last_sparse_infill_rotate_template_value = m_config->opt_string("sparse_infill_rotate_template"); } void Tab::update_mode() @@ -1747,8 +1749,9 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) auto new_value = boost::any_cast(value); is_safe_to_rotate = is_safe_to_rotate || new_value.empty(); + const bool had_previous_value = !m_last_sparse_infill_rotate_template_value.empty(); - if (!is_safe_to_rotate) { + if (!is_safe_to_rotate && !had_previous_value) { wxString msg_text = _( L("Infill patterns are typically designed to handle rotation automatically to ensure proper printing and achieve their " "intended effects (e.g., Gyroid, Cubic). Rotating the current sparse infill pattern may lead to insufficient support. " @@ -1765,6 +1768,8 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) wxGetApp().plater()->update(); } } + + m_last_sparse_infill_rotate_template_value = m_config->opt_string("sparse_infill_rotate_template"); } if(opt_key=="layer_height"){ @@ -2306,7 +2311,7 @@ void TabPrint::build() optgroup->append_single_option_line("xy_hole_compensation", "quality_settings_precision#x-y-compensation"); optgroup->append_single_option_line("xy_contour_compensation", "quality_settings_precision#x-y-compensation"); optgroup->append_single_option_line("elefant_foot_compensation", "quality_settings_precision#elephant-foot-compensation"); - optgroup->append_single_option_line("elefant_foot_layers_density", "quality_settings_precision#elephant-foot-compensation"); + optgroup->append_single_option_line("elefant_foot_layers_density", "quality_settings_precision#elephant-foot-compensation-density"); optgroup->append_single_option_line("elefant_foot_compensation_layers", "quality_settings_precision#elephant-foot-compensation"); optgroup->append_single_option_line("precise_outer_wall", "quality_settings_precision#precise-wall"); optgroup->append_single_option_line("precise_z_height", "quality_settings_precision#precise-z-height"); @@ -2324,25 +2329,25 @@ void TabPrint::build() optgroup->append_single_option_line("ironing_angle_fixed", "quality_settings_ironing#fixed-angle"); optgroup = page->new_optgroup("Z Contouring", L"param_advanced"); - optgroup->append_single_option_line("zaa_enabled"); - optgroup->append_single_option_line("zaa_minimize_perimeter_height"); - optgroup->append_single_option_line("zaa_min_z"); - optgroup->append_single_option_line("zaa_dont_alternate_fill_direction"); + optgroup->append_single_option_line("zaa_enabled", "quality_settings_z_contouring"); + optgroup->append_single_option_line("zaa_minimize_perimeter_height", "quality_settings_z_contouring#minimize-wall-height-angle"); + optgroup->append_single_option_line("zaa_min_z", "quality_settings_z_contouring#minimum-z-height"); + optgroup->append_single_option_line("zaa_dont_alternate_fill_direction", "quality_settings_z_contouring#dont-alternate-fill-direction"); // Orca: it's not used yet, so hide it in UI for now // optgroup->append_single_option_line("ironing_expansion"); optgroup = page->new_optgroup(L("Wall generator"), L"param_wall_generator"); optgroup->append_single_option_line("wall_generator", "quality_settings_wall_generator"); - optgroup->append_single_option_line("wall_transition_angle", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("wall_transition_filter_deviation", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("wall_transition_length", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("wall_distribution_count", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("initial_layer_min_bead_width", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("min_bead_width", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("min_feature_size", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("min_length_factor", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("wall_maximum_resolution", "quality_settings_wall_generator#arachne"); - optgroup->append_single_option_line("wall_maximum_deviation", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("wall_transition_angle", "quality_settings_wall_generator#wall-transitioning-threshhold-angle"); + optgroup->append_single_option_line("wall_transition_filter_deviation", "quality_settings_wall_generator#wall-transitioning-filter-margin"); + optgroup->append_single_option_line("wall_transition_length", "quality_settings_wall_generator#wall-transitioning-length"); + optgroup->append_single_option_line("wall_distribution_count", "quality_settings_wall_generator#wall-distribution-count"); + optgroup->append_single_option_line("initial_layer_min_bead_width", "quality_settings_wall_generator#first-layer-minimum-wall-width"); + optgroup->append_single_option_line("min_bead_width", "quality_settings_wall_generator#minimum-wall-width"); + optgroup->append_single_option_line("min_feature_size", "quality_settings_wall_generator#minimum-feature-size"); + optgroup->append_single_option_line("min_length_factor", "quality_settings_wall_generator#minimum-wall-length"); + optgroup->append_single_option_line("wall_maximum_resolution", "quality_settings_wall_generator#maximum-wall-resolution"); + optgroup->append_single_option_line("wall_maximum_deviation", "quality_settings_wall_generator#maximum-wall-deviation"); optgroup = page->new_optgroup(L("Walls and surfaces"), L"param_wall_surface"); optgroup->append_single_option_line("wall_sequence", "quality_settings_wall_and_surfaces#walls-printing-order"); @@ -2680,6 +2685,9 @@ void TabPrint::build() optgroup->append_single_option_line("fuzzy_skin_scale", "others_settings_fuzzy_skin#skin-feature-size"); optgroup->append_single_option_line("fuzzy_skin_octaves", "others_settings_fuzzy_skin#skin-noise-octaves"); optgroup->append_single_option_line("fuzzy_skin_persistence", "others_settings_fuzzy_skin#skin-noise-persistence"); + optgroup->append_single_option_line("fuzzy_skin_ripples_per_layer", "others_settings_fuzzy_skin#ripples-per-layer"); + optgroup->append_single_option_line("fuzzy_skin_ripple_offset", "others_settings_fuzzy_skin#ripple-offset"); + optgroup->append_single_option_line("fuzzy_skin_layers_between_ripple_offset", "others_settings_fuzzy_skin#layers-between-ripple-offset"); optgroup->append_single_option_line("fuzzy_skin_first_layer", "others_settings_fuzzy_skin#apply-fuzzy-skin-to-first-layer"); optgroup = page->new_optgroup(L("G-code output"), L"param_gcode"); @@ -4270,14 +4278,7 @@ void TabFilament::toggle_options() toggle_line("pellet_flow_coefficient", is_pellet_printer); toggle_line("filament_diameter", !is_pellet_printer); - bool support_chamber_temp_control = printer_cfg.opt_bool("support_chamber_temp_control"); - toggle_line("activate_chamber_temp_control", support_chamber_temp_control); - toggle_line("chamber_temperature", support_chamber_temp_control); - - if (support_chamber_temp_control) { - bool activate_chamber_temp_control = m_config->opt_bool("activate_chamber_temp_control", 0); - toggle_option("chamber_temperature", activate_chamber_temp_control); - } + toggle_line("activate_chamber_temp_control", printer_cfg.opt_bool("support_chamber_temp_control")); std::string volumetric_speed_cos = m_config->opt_string("volumetric_speed_coefficients", 0u); bool enable_fit = volumetric_speed_cos != "0 0 0 0 0 0"; @@ -7526,10 +7527,10 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep // Collect and set indices of depending_presets marked as compatible. wxArrayInt selections; auto *compatible_printers = dynamic_cast(m_config->option(deps.key_list)); - if (compatible_printers != nullptr || !compatible_printers->values.empty()) + if (compatible_printers != nullptr && !compatible_printers->values.empty()) for (auto preset_name : compatible_printers->values) for (size_t idx = 0; idx < presets.GetCount(); ++idx) - if (presets[idx] == preset_name) { + if (presets[idx] == from_u8(preset_name)) { selections.Add(idx); break; } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 1592212c8c..931061e0d3 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -446,6 +446,7 @@ protected: void filter_diff_option(std::vector &options); ConfigManipulation m_config_manipulation; + std::string m_last_sparse_infill_rotate_template_value; ConfigManipulation get_config_manipulation(); friend class EditGCodeDialog; }; diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 53ce5e1318..85e3261afa 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -25,6 +25,7 @@ #include "Widgets/RoundedRectangle.hpp" #include "Widgets/CheckBox.hpp" #include "Widgets/DialogButtons.hpp" +#include "Widgets/HyperLink.hpp" using boost::optional; @@ -959,6 +960,11 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection *dependent_ m_sizer_button->Add(checkbox_sizer, 0, wxLEFT, FromDIP(22)); checkbox_sizer->Show(bool(m_buttons & REMEMBER_CHOISE)); + if (dependent_presets != nullptr) { + auto wiki = new HyperLink(this, _L("Help"), "https://www.orcaslicer.com/wiki/transfer_discard_changes"); + m_sizer_button->Add(wiki, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(22)); + } + m_sizer_button->Add(0, 0, 1, 0, 0); // Add Buttons diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 7988f91147..2a88277680 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -418,8 +418,9 @@ void WebViewPanel::OnFreshLoginStatus(wxTimerEvent &event) { auto mainframe = Slic3r::GUI::wxGetApp().mainframe; if (mainframe && mainframe->m_webview == this) { - Slic3r::GUI::wxGetApp().get_login_info(ORCA_CLOUD_PROVIDER); auto* app_config = Slic3r::GUI::wxGetApp().app_config; + if (app_config && app_config->get_stealth_mode()) return; + Slic3r::GUI::wxGetApp().get_login_info(ORCA_CLOUD_PROVIDER); if (app_config && app_config->has_cloud_provider(BBL_CLOUD_PROVIDER)) { Slic3r::GUI::wxGetApp().get_login_info(BBL_CLOUD_PROVIDER); } @@ -520,14 +521,18 @@ void WebViewPanel::SendCloudProvidersInfo() if (!app_config) return; - auto providers = app_config->get_cloud_providers(); json j; j["command"] = "cloud_providers_info"; json data; json provider_array = json::array(); - for (const auto& p : providers) { - provider_array.push_back(p); + + if (!app_config->get_stealth_mode()) { + auto providers = app_config->get_cloud_providers(); + for (const auto& p : providers) { + provider_array.push_back(p); + } } + data["providers"] = provider_array; j["data"] = data; diff --git a/src/slic3r/GUI/Widgets/CheckBox.cpp b/src/slic3r/GUI/Widgets/CheckBox.cpp index 4e03f42187..54e98887e7 100644 --- a/src/slic3r/GUI/Widgets/CheckBox.cpp +++ b/src/slic3r/GUI/Widgets/CheckBox.cpp @@ -2,6 +2,10 @@ #include "../wxExtensions.hpp" +#ifdef __WXGTK3__ +#include "../GUI_Utils.hpp" +#endif + CheckBox::CheckBox(wxWindow *parent, int id) : wxBitmapToggleButton(parent, id, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) , m_on(this, "check_on", 18) @@ -24,16 +28,12 @@ CheckBox::CheckBox(wxWindow *parent, int id) Bind(wxEVT_ENTER_WINDOW, &CheckBox::updateBitmap, this); Bind(wxEVT_LEAVE_WINDOW, &CheckBox::updateBitmap, this); #endif - update(); -#ifdef __WXGTK__ - wxSize bestSize = GetBestSize(); - bestSize.IncTo(m_on.GetBmpSize()); - SetSize(bestSize); - SetMinSize(bestSize); -#else - SetSize(m_on.GetBmpSize()); - SetMinSize(m_on.GetBmpSize()); + +#ifdef __WXGTK3__ + Slic3r::GUI::RemoveButtonBorder(this); #endif + + Rescale(); } void CheckBox::SetValue(bool value) @@ -61,16 +61,9 @@ void CheckBox::Rescale() m_on_focused.msw_rescale(); m_half_focused.msw_rescale(); m_off_focused.msw_rescale(); - update(); -#ifdef __WXGTK__ - wxSize bestSize = GetBestSize(); - bestSize.IncTo(m_on.GetBmpSize()); - SetSize(bestSize); - SetMinSize(bestSize); -#else SetSize(m_on.GetBmpSize()); SetMinSize(m_on.GetBmpSize()); -#endif + update(); } void CheckBox::update() diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp index aedd868f8f..3b7664683c 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.cpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp @@ -11,6 +11,10 @@ #include "libslic3r/MacUtils.hpp" #endif +#ifdef __WXGTK3__ +#include "../GUI_Utils.hpp" +#endif + #include #include #include @@ -28,6 +32,11 @@ SwitchButton::SwitchButton(wxWindow* parent, wxWindowID id) SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent)); Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { update(); e.Skip(); }); SetFont(Label::Body_12); + +#ifdef __WXGTK3__ + Slic3r::GUI::RemoveButtonBorder(this); +#endif + Rescale(); } diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index 32da6f0b3c..03e677b636 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -340,9 +340,17 @@ bool NetworkAgent::is_server_connected(const std::string& provider) return false; } -int NetworkAgent::refresh_connection() +int NetworkAgent::refresh_connection(const std::string& provider) { - return invoke_on_all_cloud_agents(m_cloud_agents, [](ICloudServiceAgent& cloud_agent) { return cloud_agent.refresh_connection(); }); + if(provider.empty()) + return invoke_on_all_cloud_agents(m_cloud_agents, [](ICloudServiceAgent& cloud_agent) { return cloud_agent.refresh_connection(); }); + else { + const auto cloud_agent = get_cloud_agent(provider); + if (cloud_agent) + return cloud_agent->refresh_connection(); + return -1; + } + } void NetworkAgent::enable_multi_machine(bool enable, const std::string& provider) diff --git a/src/slic3r/Utils/NetworkAgent.hpp b/src/slic3r/Utils/NetworkAgent.hpp index 74fb839aa4..e069066b58 100644 --- a/src/slic3r/Utils/NetworkAgent.hpp +++ b/src/slic3r/Utils/NetworkAgent.hpp @@ -71,7 +71,7 @@ public: int set_on_http_error_fn(AppOnHttpErrorFn fn); int set_get_country_code_fn(GetCountryCodeFn fn); int connect_server(); - int refresh_connection(); + int refresh_connection(const std::string& provider = ""); int change_user(std::string user_info, const std::string& provider = ORCA_CLOUD_PROVIDER); bool is_user_login(const std::string& provider = ORCA_CLOUD_PROVIDER); diff --git a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp index f8a242f7ae..abbebef42c 100644 --- a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp +++ b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp @@ -74,19 +74,21 @@ constexpr const char* SECRET_STORE_SERVICE = "OrcaSlicer/Auth"; constexpr const char* SECRET_STORE_USER = "orca_refresh_token"; constexpr std::chrono::seconds TOKEN_REFRESH_SKEW{900}; // 15 minutes -std::string generate_uuid_for_setting_id(const std::string& name = "") +std::string generate_uuid_for_setting_id(const std::string& name, const std::string& user_id = "") { if (name.empty()) { return ""; } - // Use a fixed namespace UUID for OrcaSlicer profiles - // This ensures the same name always generates the same UUID + // Mix user_id into the hashed input so two different users generating a setting_id + // for an identically-named preset get distinct UUIDs. Without this, the cloud's ID + // space collides across accounts and the second user's create gets HTTP 409 with + // server_profile=null on every sync (the foreign owner's record is not exposed). static const boost::uuids::uuid orca_namespace = boost::uuids::string_generator()("f47ac10b-58cc-4372-a567-0e02b2c3d479"); boost::uuids::name_generator_sha1 gen(orca_namespace); - boost::uuids::uuid id = gen(name); + boost::uuids::uuid id = user_id.empty() ? gen(name) : gen(user_id + "/" + name); return boost::uuids::to_string(id); } @@ -904,7 +906,7 @@ int OrcaCloudServiceAgent::get_user_presets(std::map* values_map, unsigned int* http_code) { - std::string new_id = generate_uuid_for_setting_id(name); + std::string new_id = generate_uuid_for_setting_id(name, get_user_id()); if (new_id.empty()) { BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: request_setting_id failed - name is empty"; return "";